cs-icon.svg

Set up Live Preview for Gatsby-powered Sites

Gatsby is an open-source framework that combines functionality from React, GraphQL and Webpack into a single tool for building static websites and apps.

This guide explains in detail how to set up Live Preview for your Gatsby-powered websites.

Prerequisites

Steps for Execution

Here is an overview of the steps involved in setting up live preview for your Gatsby-powered sites:

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

Set up the Website

These steps will guide you through configuring your website's code to enable the live preview functionality.

  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. Initialize the Contentstack Gatsby class
    Within the src folder, generate a new file called live-preview.js (you can choose any path and name for the file). Within this file, you can configure the necessary settings for enabling live preview. Import ContentstackGatsby from the gatsby-source-plugin and initialize it with the data, then proceed to export it.

    The ContentstackGatsby will be responsible for fetching the data during the live preview updates.

    import { ContentstackGatsby } from "gatsby-source-contentstack/live-preview";
    export const getCSData = new ContentstackGatsby({
        api_key: GATSBY_CONTENTSTACK_API_KEY,
        environment: GATSBY_CONTENTSTACK_ENVIRONMENT,
        delivery_token: GATSBY_CONTENTSTACK_DELIVERY_TOKEN,
        live_preview: {
            preview_token: GATSBY_CONTENTSTACK_PREVIEW_TOKEN,
            enable: true,
            host: "rest-preview.contentstack.com"
        }
    });
    
    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
  3. Install and initialize the live preview utils SDK
    The Live Preview Utils SDK operates by monitoring content updates and instructing Contentstack's delivery SDK to retrieve draft or preview content or manage real-time content changes. To achieve this functionality, you must run this SDK on the client side.

    You can install the Live Preview Utils SDK package via npm by running the following command:

    npm install @contentstack/live-preview-utils
    

    Initialize the SDK by executing the init() method within the live-preview.js file you created previously. This method establishes event listeners to monitor any modifications made to the content of the entry being previewed. Ensure to pass the getCSData.stackSdk parameter obtained from the earlier setup of Contentstack Gatsby.

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

    Note: To avoid configuration reset errors in your Live Preview setup due to rerendering, it's crucial to encapsulate your SDK initialization code within a separate JavaScript file.

  4. Configure live preview for every webpage

    Whenever you update an entry, the onEntryChange() method will be triggered. You can use this method to define any coding logic that assists in fetching data.

    Now, let's enable live preview for the following Gatsby page.

    import React from "react"
    import ContentstackLivePreview from "@contentstack/live-preview-utils"
    export const pageQuery = graphql`
    // your Gatsby query
    `
    const Home = (props) => {
    return (
    <div>{props.data.allContentstackPage.nodes[0].title}</div>
    )
    }
    export default Home;
    

    In this scenario, you are currently accessing the title directly from the props. However, for live preview purposes, we'll store this data in the component's state and use it from there.

    To do this, first import ContentstackLivePreview and getCSData that you created in step two. Then, create a new function that utilizes getCSData.get() to retrieve a fresh value and update the component's state with this value. Finally, pass this function to ContentstackLivePreview.onLiveEdit().

    Ensure that you include __typename and uid in your query, as this is essential for the correct functioning of live preview.

    import React, { useEffect, useState } from "react"
    import ContentstackLivePreview from "@contentstack/live-preview-utils"
    import { getCSData } from "../live-preview"
    export const pageQuery = graphql`
     // your Gatsby query
    `
    const Home = (props) => {
      const [data, setData] = useState(props.data.allContentstackPage.nodes[0])
      const fetchLivePreviewData = async () => {
        const updatedData = await getCSData.get(props.data.allContentstackPage.nodes[0]);
        setData(updatedData)
      }
      useEffect(() => {
        ContentstackLivePreview.onLiveEdit(fetchLivePreviewData)
      }, [])
      return (
            <div>{data.title}</div>
      )
    }
    export default Home;
    

    Note: In the above example, the onLiveEdit() method is opted for instead of onEntryChange() because onLiveEdit() specifically triggers the fetch function when a user edits the entry. If onEntryChange() is used in conjunction with ContentstackGatsby.get(), it may lead to an error.

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.
  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.

    live_preview_settings

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.

Note: Since the preview service operates with draft data that hasn't been published, it cannot provide publish_details in its response.

Live Edit Tags for Entries (optional)

Live edit tags allow you to navigate to the field that contains the website content being previewed within the Live Preview panel. When you click on the "Edit" button beside a content block in the preview panel, you will be redirected to the corresponding field within the entry. If the field holds reference to another entry, you will be redirected to the referenced entry's editor page.

track_and_edit_in_live_preview_panel

Edit tags contain the location where the corresponding field lies within the entry. The Live Preview Utils SDK searches for the elements which contain the edit tags referred to as data-cslp.

The structure of the edit tag (field location in the entry) you can pass against the data-cslp attribute is as follows:

{content_type_uid}.{entry_uid}.{locale}.{field_uid}

Here's a sample field path:

home.blt80654132ff521260.en-us.modular_blocks.block_1.media_group_uid.image_uid

Note: If the field is nested within another complex field, such as Modular Blocks, provide the field path as follows: {modular_block_field_UID}.{block_UID}.{field_UID}.

For a website built using Contentstack's JavaScript Delivery SDK, you can use the addEditableTags() method to automatically generate the edit tag for you. The following section explains how you can set up live edit tags using addEditableTags().

Set Up Live Editing Using the addEditableTags Method

  1. Process entry for live editing

    Update the query to incorporate __typename and uid for all the references within the data. This is crucial to ensure accurate redirection of references. Then, navigate to the website's code where the entry is retrieved, which, in this case, occurs just before it is assigned to the state.

      const fetchLivePreviewData = async () => {
        const updatedData = await getCSData.get(props.data.allContentstackPage.nodes[0]);
        setData(updatedData)
      }
    

    After obtaining the data, utilize the ContentstackGatsby.addContentTypeUidFromTypename() method to include _content_type_uid in the references, as it is a necessary step.

      const fetchLivePreviewData = async () => {
        const updatedData = await getCSData.get(props.data.allContentstackPage.nodes[0]);
    ContentstackGatsby.addContentTypeUidFromTypename(updatedData)
    // call addEditableTags here
        setData(updatedData)
      }
    

    Note: You can skip using the ContentstackGatsby.addContentTypeUidFromTypename() method if there are no references in the page.

  2. Import the addEditableTags() method

    Install the Contentstack Utils from npm:

    npm i @contentstack/utils
    

    Import the addEditableTags from Contentstack utils:

    import {addEditableTags} from "@contentstack/utils"
    
  3. Generate edit tags for previewed entry content

    After retrieving data using the ContentstackGatsby class, pass the resultant entry within the addEditableTags() function to add edit tags to the previewed entry content:

      addEditableTags(entry, content_type_uid, tagsAsObject, locale)
    

    Here, entry is the actual entry you get from the SDK, content_type_uid is the unique ID of the current entry’s content type, and tagsAsObject determines the format in which the edit tag would be added.

    Note: The addEditableTags() method does not return any value. It only modifies the entry passed as the first argument to the method.

    By default, tagsAsObject is set to false, and it appends data-cslp in the form of a string as follows:

    'data-cslp=path.to.field'
    

    Note: This option is provided for React-based apps as you cannot directly add any attributes in string format. Instead, you need to destructure an object.

    If tagsAsObject is set to true, the data-cslp attribute is returned in object format as follows:

    { 'data-cslp': 'path.to.field'}
    

    Here's a sample that shows how the code would look once you add the addEditableTags() method:

    addEditableTags(props.data.allContentstackPage.nodes[0], "content_type_uid", false)
    

    When you use the addEditableTags() method, a new key-value pair is returned at every level in the existing entry schema. This pair is known as the edit tag and is denoted by a dollar sign ($).

    For example, consider that you passed the following entry schema against the first parameter in the addEditableTags() method:

    {
        "name": "John Doe",
        "description": {
            "occupation": [{
                "name": "Plumber",
                "since": 1920
            }],
            "height": "5ft"
        }
    }
    

    Once the addEditableTags() method is executed, the entry passed against the first parameter is updated as follows:

    {
        "name": "John Doe",
        "$": {
            "name": "profile.blt8tvsk328dbw258.en-us.name"
        },
        "description": {
            "$": {
                "occupation": "profile.blt8tvsk328dbw258.en-us.description.occupation",
                "height": "profile.blt8tvsk328dbw258.en-us.description.height"
            },
            "occupation": [{
                "$": {
                    "name": "profile.blt8tvsk328dbw258.en-us.description.occupation.name",
                    "since": "profile.blt8tvsk328dbw258.en-us.description.occupation.since"
                },
                "name": "Plumber",
                "since": 1920
            }],
            "height": "5ft"
        }
    }
    
  4. Set up the Live Preview Utils SDK

    Live Preview requires the stack API key and host URL to perform appropriate redirection to the relevant stack.

    ContentstackLivePreview.init({
        ...
        stackDetails: {
           apiKey: "your api key",
       },
       clientUrlParams: {
           host: "app.contentstack.com",
       },
    })
    

    Here, the clientUrlParams key is optional and is set for the North America region. For other regions, you can use the following configurations for clientUrlParams.
    For Europe region, use the following config:

    {
       host: "eu-app.contentstack.com"
    }
    

    For Azure NA region, use the following config:

    {
       host: "azure-na-app.contentstack.com"
    }
    

    For Azure EU region, use the following config:

    {
       host: "azure-eu-app.contentstack.com"
    }
    
  5. Configure live edit tags for each webpage

    Now, navigate to the section in your website's front-end HTML code where you need to pass the edit tags as attributes. To access an edit tag, fetch the path to a field in the entry and add a dollar sign ($) before the last field in the field depth hierarchy.

    For example, if the path to your entry data is data.description.height, then the corresponding edit tag will be data.description.$.height.

    Once you add the edit tag, content managers will be able to see the "Edit" icon whenever they hover over the corresponding content block on the website.

    <header class="text-center">
        <div class="author">
            <img {{ data.author.profile_image.$.url }} src="{{ data.author.profile_image.url }}" alt="{{ data.author.title }}"/>
        </div>
        <h1 {{ data.author.$.title }}>{{ data.author.title }}</h1>
        <h2 class="author-job" {{ data.author.$.job_title }}>{{ data.author.job_title }}</h2>
        <p class="author-bio" {{ data.author.$.biography }}>{{ data.author.biography }}</p>
        <div class="author-social">
            <a href="mailto:{{ data.author.social.email }}"><ion-icon name="mail-outline"></ion-icon></a>
            <a href="https://www.twitter.com/{{ data.author.social.twitter }}"><ion-icon name="logo-twitter"></ion-icon></a>
            <a href="https://www.instagram.com/{{ data.author.social.instagram }}"><ion-icon name="logo-instagram"></ion-icon></a>
        </div>
    </header>
    

    For React-based applications, you can generate edit tags by setting the tagsAsObject parameter to true. When set to true, this parameter returns the edit tag in object format. You need to destructure the object while passing it within the JSX element.

    Here is an example of an edit tag that is returned in object format:

    <h1 {...data.$.name}>{data.name}</h1><p> {...data.description.$.height}>{data.description.height}</p>
    

    Note: This setup only works for generic websites that use basic JavaScript frontend code. For websites working on other programming languages, you need to provide the entire path to the specific field.

  6. Add CSS to display edit buttons in the project

    The styles for the live edit tags are available in the @contentstack/live-preview-utils/dist/main.css file. You can import these styles in your Gatsby pages or your layout components as follows:

        import "@contentstack/live-preview-utils/dist/main.css";
    

    Alternatively, you can directly import the CSS within the HTML using the following code:

    <link rel="stylesheet" href="https://unpkg.com/@contentstack/live-preview-utils/dist/main.css">
    

Once you have configured the settings, you will be able to see the Edit icon whenever you hover over a content block in your preview panel.

edit_icon_in_the_live_preview_panel
Was this article helpful?
^