cs-icon.svg

Live Preview Implementation for CSR without Contentstack SDK

Note: This guide is focused on configuring the live preview feature for REST APIs. If you are working with GraphQL APIs, please refer to the Set-up Live Preview with GraphQL for CSR document.

Client-side rendering (CSR) is where developers render their content directly to a browser using JavaScript. This guide explains in detail how to set up Live Preview for your CSR websites using REST APIs.

Note: You can use CSR (Client-side rendering) mode for SSG (Static Site Generator) type applications.

Prerequisites

Steps for Execution

Here is an overview of the steps involved in setting up live preview with REST for your Client-side Rendering (CSR) sites without Contentstack SDK:

  1. Set up the Website
  2. Host the Website
  3. Update Stack Settings
  4. Live Edit Tags for Entries (optional)

Set up the Website

  1. Generate a preview token for configuration:

    You can create a preview token within the Contentstack app by navigating to Settings > Tokens > Delivery Tokens (press “alt + O” for Windows or “option key + O” for Mac). It is recommended to use a preview token for Live Preview instead of a previously utilized, read-only management token.

    Each preview token is associated with a delivery token and shares access to the specific environment. Therefore, if a delivery token doesn't exist, you must create a new one, where you can enable the Create Preview Token toggle. For an existing delivery token, you will find an option to generate a preview token. Click + Create Preview Token and copy the resulting token.

    Create-a-Preview-Token_GIF.gif
  2. Install and initialize the Live Preview utils SDK:

    The Live Preview Utils SDK listens to content changes and requests Contentstack's delivery SDK to fetch draft or preview content or process real-time content changes. Consequently, this SDK needs to be executed on the client side.

    To install it, you can use npm or import it using the script tag in your HTML page code.

    Using script tag: To import and initialize the Live Preview Utils SDK using the script tag of the HTML file, add the following code:

    <script type='module'>
         import ContentstackLivePreview from 'https://esm.sh/@contentstack/live-preview-utils@2.0.3';
         ContentstackLivePreview.init({
            stackDetails: {
                apiKey: "your-stack-api-key",
            },
            ssr: false
        });
    </script>
    

    Using npm: Alternatively, you can install the Live Preview Utils SDK package via npm using the following command:

    npm install @contentstack/live-preview-utils
    

    You can then initialize the SDK using the init() method. This method helps set up event listeners that keep a tab of any changes made to the previewed entry's content.

    import ContentstackLivePreview from "@contentstack/live-preview-utils";
        ContentstackLivePreview.init({
         ssr: false,
         });
    

    Note: You need to define your SDK initialization code within a separate JavaScript file to prevent configuration resetting errors in your Live Preview setup caused by rerendering.

  3. Update the REST URL and headers

    To ensure the proper functioning of the website within the Live Preview panel, it’s necessary to change the REST API’s hostname. When the website operates within a Live Preview panel, the Live Preview SDK receives a hash via the URL search params in SSR mode. Consequently, you can examine this hash to switch to the appropriate hostname.

    function getHeaders() {
        const headers = new Headers();
        headers.append("Content-Type", "application/json");
        headers.append("access_token", REACT_APP_CONTENTSTACK_DELIVERY_TOKEN);
        headers.append("api_key", REACT_APP_CONTENTSTACK_API_KEY);
        return headers;
    }
    export const fetchData = async (ctUID, entryUID) => {
        const contentstackURL = new URL(
            `https://${CONTENTSTACK_CDN_URL}/v3/content_types/${ctUID}/entries/${entryUID}?environment=${REACT_APP_CONTENTSTACK_ENVIRONMENT}`
        );
        const headers = getHeaders();
        const res = await fetch(contentstackURL.toString(), {
            method: "GET",
            headers: headers,
        });
        return res.json();
    };
    

    In this setup, a simple configuration directs the contentstackURL to the Contentstack CDN endpoint, while the getHeaders() function generates the necessary headers for requests. The fetchData() function manages data retrieval, ensuring the correct information is fetched from the server.

    import ContentstackLivePreview from "@contentstack/live-preview-utils";
    const CONTENTSTACK_CDN_URL = "cdn.contentstack.io";
    const LIVE_PREVIEW_HOST_NAME = "rest-preview.contentstack.com";
    function getHeaders() {
        const headers = new Headers();
        headers.append("Content-Type", "application/json");
        headers.append("access_token", REACT_APP_CONTENTSTACK_DELIVERY_TOKEN);
        headers.append("api_key", REACT_APP_CONTENTSTACK_API_KEY);
        return headers;
    }
    export const fetchData = async (ctUID, entryUID) => {
        const contentstackURL = new URL(
            `https://${CONTENTSTACK_CDN_URL}/v3/content_types/${ctUID}/entries/${entryUID}?environment=${REACT_APP_CONTENTSTACK_ENVIRONMENT}`
        );
        const hash = ContentstackLivePreview.hash;
        const headers = getHeaders();
        if (hash) {
            headers.append("live_preview", hash);
            // Optionally, to enable variant support add the include_applied_variants header.
            headers.append("include_applied_variants", "true");
            headers.append("preview_token", REACT_APP_CONTENTSTACK_PREVIEW_TOKEN);
            contentstackURL.hostname = LIVE_PREVIEW_HOST_NAME;
        } else {
            contentstackURL.hostname = CONTENTSTACK_CDN_URL;
        }
        const res = await fetch(contentstackURL.toString(), {
            method: "GET",
            headers: headers,
        });
        return res.json();
    };
    

    In this example, you can use ContentstackLivePreview.hash to selectively modify the hostname and headers. When it comes to enabling Live Preview, it's essential to transmit both the hash and preview_token. Optionally, to enable variant support in edit tags add the include_applied_variants header. Once you have configured this data, you can continue using REST API just as you normally would.

    Note:For the North America endpoint, set the host parameter to rest-preview.contentstack.com. If your website is hosted on other data centers, pass the following:
    • AWS EU: eu-rest-preview.contentstack.com
    • Azure NA: : azure-na-rest-preview.contentstack.com
    • Azure EU: : azure-eu-rest-preview.contentstack.com
    • GCP NA: : gcp-na-rest-preview.contentstack.com

    To fetch content in the live preview panel, it is recommended to utilize the preview token instead of the read-only management token. For additional details, please refer to the documentation on Preview tokens.

  4. Configure Live Preview across each webpage:

    Whenever you update an entry, the onLivedEdit() method will be executed. Hence, you can define any coding logic that helps fetch data inside this method.

    Each page has a function responsible for retrieving data and setting it to the state. Here, we have used React.js for demonstration. We have created an fetchData() function responsible for fetching the data.

    Now, inside the useEffect() function, we call the fetchData() function inside the onLiveEdit() method. This onLiveEdit method runs the fetchData() function every time you update entry content.

    // utils.js
    ...
    export const onLiveEdit = ContentstackLivePreview.onLiveEdit;
    ...
    // Footer.js
    import React from "react";
    import { onLiveEdit, fetchData } from "./utils.js";
    const Footer = () => {
        const [data, setData] = React.useState({});
        React.useEffect(() => {
          // For Initial render 
          fetchData("your_content_type_uid", "your_entry_uid").then((data) => {
            const entry = data.entry;
            setEntry(entry);
          });
          // To fetch the live preview data
          onLiveEdit(() => {
            fetchData("your_content_type_uid", "your_entry_uid").then((data) => {
              const entry = data.entry;
              setEntry(entry);
            });
          })
        }, []);
        return <div>{data.company_name}</div>;
    };
    

Host the Website

To host a website, you can simply use ngrok or any other website hosting service.

Update Stack Settings

To enable Live Preview through the stack settings in Contentstack, follow the steps given below:

  1. Go to Settings > Environments.
  2. Create a new environment if there are no existing environments in your stack.
  3. Add your hosted website URL as the base URL for the environment created.Set_Base_URL_for_Environment.png
  4. Navigate to the Live Preview section under stack's "Settings".
  5. Select the Enable Live Preview checkbox.
  6. Select the Default Preview Environment from the dropdown. This helps avoid having to add the preview settings manually across multiple entries.
  7. Save the settings.Set_default_preview_environment.png

You will now be able to see the Live Preview icon within all the entries of your stack and the feature will preview data from the hosted website.

Live Edit Tags for Entries (optional)

Live edit tags provide a seamless way to jump directly to the specific content you want to modify within the live preview. Clicking the "Edit" button next to a content block in the preview pane automatically takes you to the corresponding field in the entry editor. If the field refers to another entry, you'll be directed to that entry's editor page for further editing.

Additional Resource: For detailed information on how to set up Live Edit tags, please refer to our documentation on Set Up Live Edit Tags for Entries with REST

Was this article helpful?
^