Skip navigation

Set up preview for content items

9 min read
Download PDF

Set up content preview for your Kontent.ai projects so that your content creators can preview unpublished content and review it with confidence. 

In this article, you'll learn to:

Table of contents

    Learn to get your latest content

    Start by teaching your app how to fetch the latest versions of your content. This means making requests to Delivery Preview API. Every request to the API must be authenticated with a Preview API key. Keep in mind that server-side technology is required to keep your API keys secret.

    To get the Preview API key:

    1. In Kontent.ai, go to  Project settings > API keys.
    2. In the Preview API card, click  for one of the keys.

    Quick facts about the Primary and Secondary keys

    • The scope of the API keys is per environment.
    • Their default expiration date is 1 year.
    • Use the Primary key for continuous use in your apps.
    • Use the Secondary key when revoking the Primary key to prevent downtime.

    Here's an example of how you can get the latest version of a My article content item:

    • Java
    // Tip: Find more about Java SDK at https://kontent.ai/learn/java import kontent.ai.delivery.*; // Initializes a DeliveryClient for preview DeliveryClient client = new DeliveryClient( DeliveryOptions.builder() .projectId("<YOUR_PROJECT_ID>") .previewApiKey("<YOUR_PREVIEW_API_KEY>") .usePreviewApi(true) .build(); ); // Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models // Registers the model class for articles client.registerType(Article.class); // Gets the latest version of an item CompletionStage<Article> article = client.getItem( "my_article", Article.class );
    // Tip: Find more about Java SDK at https://kontent.ai/learn/java import kontent.ai.delivery.*; // Initializes a DeliveryClient for preview DeliveryClient client = new DeliveryClient( DeliveryOptions.builder() .projectId("<YOUR_PROJECT_ID>") .previewApiKey("<YOUR_PREVIEW_API_KEY>") .usePreviewApi(true) .build(); ); // Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models // Registers the model class for articles client.registerType(Article.class); // Gets the latest version of an item CompletionStage<Article> article = client.getItem( "my_article", Article.class );
    • JavaScript
    // Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript const KontentDelivery = require('@kontent-ai/delivery-sdk'); const deliveryClient = KontentDelivery.createDeliveryClient({ projectId: '<YOUR_PROJECT_ID>', previewApiKey: '<YOUR_PREVIEW_API_KEY>', defaultQueryConfig: { usePreviewMode: true, // Queries the Delivery Preview API. } }); const response = await deliveryClient.item('my_article') .toPromise();
    // Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript const KontentDelivery = require('@kontent-ai/delivery-sdk'); const deliveryClient = KontentDelivery.createDeliveryClient({ projectId: '<YOUR_PROJECT_ID>', previewApiKey: '<YOUR_PREVIEW_API_KEY>', defaultQueryConfig: { usePreviewMode: true, // Queries the Delivery Preview API. } }); const response = await deliveryClient.item('my_article') .toPromise();
    • C#
    // Tip: Find more about .NET SDKs at https://kontent.ai/learn/net using Kontent.Ai.Delivery; // Creates an instance of the delivery client // ProTip: Use DI for this in your apps https://kontent.ai/learn/net-register-client for previewing content IDeliveryClient client = DeliveryClientBuilder .WithOptions(builder => builder .WithProjectId("975bf280-fd91-488c-994c-2f04416e5ee3") .UsePreviewApi("<YOUR_PREVIEW_API_KEY>") .Build()) .Build(); // Gets the latest version of a content item // Create strongly typed models according to https://kontent.ai/learn/net-strong-types IDeliveryItemResponse<Article> response = await client.GetItemAsync<Article>("my_article"); Article item = response.Item;
    // Tip: Find more about .NET SDKs at https://kontent.ai/learn/net using Kontent.Ai.Delivery; // Creates an instance of the delivery client // ProTip: Use DI for this in your apps https://kontent.ai/learn/net-register-client for previewing content IDeliveryClient client = DeliveryClientBuilder .WithOptions(builder => builder .WithProjectId("975bf280-fd91-488c-994c-2f04416e5ee3") .UsePreviewApi("<YOUR_PREVIEW_API_KEY>") .Build()) .Build(); // Gets the latest version of a content item // Create strongly typed models according to https://kontent.ai/learn/net-strong-types IDeliveryItemResponse<Article> response = await client.GetItemAsync<Article>("my_article"); Article item = response.Item;
    • PHP
    // Tip: Find more about PHP SDKs at https://kontent.ai/learn/php // Defined by Composer to include required libraries require __DIR__ . '/vendor/autoload.php'; use Kontent\Ai\Delivery\DeliveryClient; $client = new DeliveryClient('<YOUR_PROJECT_ID>', '<YOUR_PREVIEW_API_KEY>'); $item = $client->getItem('my_article');
    // Tip: Find more about PHP SDKs at https://kontent.ai/learn/php // Defined by Composer to include required libraries require __DIR__ . '/vendor/autoload.php'; use Kontent\Ai\Delivery\DeliveryClient; $client = new DeliveryClient('<YOUR_PROJECT_ID>', '<YOUR_PREVIEW_API_KEY>'); $item = $client->getItem('my_article');
    • cURL
    curl --request GET \ --url https://preview-deliver.kontent.ai/<YOUR_PROJECT_ID>/items/my_article \ --header 'authorization: Bearer <YOUR_PREVIEW_API_KEY>'
    curl --request GET \ --url https://preview-deliver.kontent.ai/<YOUR_PROJECT_ID>/items/my_article \ --header 'authorization: Bearer <YOUR_PREVIEW_API_KEY>'
    • Ruby
    # Tip: Find more about Ruby SDKs at https://kontent.ai/learn/ruby require 'delivery-sdk-ruby' delivery_client = Kontent::Ai::Delivery::DeliveryClient.new project_id: '975bf280-fd91-488c-994c-2f04416e5ee3', preview_key: '<YOUR_PREVIEW_API_KEY>' delivery_client.item('my_article').execute do |response| item = response.item end
    # Tip: Find more about Ruby SDKs at https://kontent.ai/learn/ruby require 'delivery-sdk-ruby' delivery_client = Kontent::Ai::Delivery::DeliveryClient.new project_id: '975bf280-fd91-488c-994c-2f04416e5ee3', preview_key: '<YOUR_PREVIEW_API_KEY>' delivery_client.item('my_article').execute do |response| item = response.item end
    • TypeScript
    // Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript import { createDeliveryClient } from '@kontent-ai/delivery-sdk'; import { Article } from './models/Article'; const deliveryClient = createDeliveryClient({ projectId: '<YOUR_PROJECT_ID>', previewApiKey: '<YOUR_PREVIEW_API_KEY>', defaultQueryConfig: { usePreviewMode: true, // Queries the Delivery Preview API. }, }); const response = await deliveryClient.item<Article>('my_article') .toPromise();
    // Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript import { createDeliveryClient } from '@kontent-ai/delivery-sdk'; import { Article } from './models/Article'; const deliveryClient = createDeliveryClient({ projectId: '<YOUR_PROJECT_ID>', previewApiKey: '<YOUR_PREVIEW_API_KEY>', defaultQueryConfig: { usePreviewMode: true, // Queries the Delivery Preview API. }, }); const response = await deliveryClient.item<Article>('my_article') .toPromise();

    Prepare your app for preview

    When your app can display the content it gets from a Kontent.ai project, the next step is to prepare your app for previewing unpublished content.

    We recommend using Delivery SDKs to make all this easier.

    To follow the best practices and avoid using your production app for fetching non-production data (preview), you need two separate instances of your app:

    • Production instance: Fetches published content via Delivery API. This instance serves content via example.org URL, for example.
    • Preview instance: Fetches the latest version of your content, even if it's not published yet, via Delivery Preview API. This instance serves content via preview.example.org URL, for example.

    You can distinguish the instances by providing or omitting the Preview API key. If the key's present, your app will run the preview instance, if it's not, that's a sign to run the production instance. 

    Set up multiple previews with spaces

    If you're working on a multi-regional or multi-brand project, you can use spaces to set up multiple previews for your websites.

    Every environment can have several spaces. You can use different domains and preview URLs for each space.

    1. From the app menu, select Project settings.
    2. Under Environment settings, select Spaces.
    3. Click Create new space.
    4. Type the new space name.
    5. Click Save.

    Create as many spaces as you need. Once you're done:

    1. Under Environment settings, select Preview URLs.
    2. In the Space domains tab, type in the domain for each space. For example, preview.example.org.

    Define preview URLs for content types

    To preview your content, you need to set up preview URLs. You can set them up only for selected content types. The URLs may be different for each combination of space and content type.

    1. Under Environment settings, select Preview URLs.
    2. In the Preview URLs for content types tab, click Set up preview for a content type.
    3. Select a content type.
    4. In Used in spaces, select a space for which you're setting up the URL.
      • If you don't use spaces, select All spaces selector. Similarly, use this selector for a preview URL that's universal across all your spaces.
    5. Type in the preview URL.

    The preview URLs must be:

    • Absolute paths in the format https://domain/path
    • Shorter than 1024 characters

    Use a secure connection

    Preview URLs require the https:// protocol and URLs accessible to Kontent.ai. Without a valid SSL certificate, Kontent.ai responds with secure connection errors.

    When developing apps locally, you can serve pages over HTTPS in combination with ngrok's forwarded address.

    Dynamic preview URLs with macros

    If you're setting up URLs that need to be dynamic, there are a few macros you can use:

    • {Space}: space domain
    • {URLslug}: content item's URL slug element value
    • {Lang}: codename of the selected language
    • {Codename}: content item's codename
    • {ItemId}: content item's internal ID
    • {Collection}: content item’s collection codename
      • This macro is available if you have collections enabled in your project.
    Preview URL patterns defined for the Article content type in two spaces

    You can create SEO-friendly URLs using the URL slug element with the {URLslug} macro: https://preview.example.org/articles/{URLslug}. Alternatively, you can use the {Codename} or {ItemId} macros to identify the content items in your preview URLs.

    In multi-regional projects, use the {Lang} macro to get the currently selected language codename, such as en-us or ja-jp.

    You can combine the macros. A preview URL https://preview.example.org/{Lang}/articles/{URLslug} would resolve to https://preview.example.org/en-ca/articles/previewing-content-items, for example.

    Multiple content items can have the same URL slug

    Kontent.ai doesn't check if a URL slug value is unique across your project. This means you can have multiple items with the same URL slug. 

    However, if you need unique URL slugs, you have several options to ensure that you don't end up with multiple same URL slugs. Check out your options to achieve unique URL slugs.

    Static preview URLs

    Your home page, for instance, doesn't need a dynamic preview URL, because it's static (it's unique and in one location).

    For example, a home page's preview URL for an app running at https://preview.example.org would be https://preview.example.org or https://{Space}.

    Set up preview for Web Spotlight

    When setting up Web Spotlight for your project, you need to set up preview links just like without Web Spotlight.

    Because the preview URLs (that is your app) will be loaded and sandboxed in an <iframe> within Kontent.ai, you need to ensure a few things for your preview environment:

    • Always use a secured connection (HTTPS) for your URL like https://preview.example.org.
    • Allow your app to load within Kontent.ai using the Content-Security-Policy header and the frame-ancestors directive: frame-ancestors https://app.kontent.ai.
      • To enable opening external links from your app, such as PDFs stored as assets in Kontent.ai, you need to set sandbox directives using the Content-Security-Policy header.
        For example, the directive allow-popups-to-escape-sandbox allows opening external links, allow-forms allows submitting forms, allow-downloads allows downloads after users click a link, and so on.
    • Make sure your web browser allows third-party cookies.
    • If you first want to test your implementation locally, you need to generate a self-signed HTTPS certificate.

    Web Spotlight and spaces

    If you'd like to use spaces in a project where you also have Web Spotlight, we recommend you the following setup:

    After you set up preview URLs for all your spaces, add one more rule for All remaining spaces (0). This rule applies to zero spaces, but that's all right. Set the preview URL as usual, without using the {Space} macro. Web Spotlight will use this URL pattern to display a preview of your website.

    Preview URL patterns defined for the Article content type in two spaces with an additional rule for zero remaining spaces that serves as a workaround for Web Spotlight.

    This is just the beginning! 

    We're working hard to bring you even more value with spaces in the upcoming months. The first thing on our radar is full support for Web Spotlight, making the website management even more powerful. Stay tuned!

    Set up edit buttons in your preview

    Once you have a preview working in both your app and Kontent.ai project, it's a good idea to add edit buttons to your application. They can look like what you see below.

    For content editors, this small addition means they can go straight to editing in Kontent.ai just by clicking the button. This will help them in case they need to fix minor errors or typos right after they spot them when previewing their content.

    If your editors have problems opening items through the edit links, verify their user roles.

    What's next?