cs-icon.svg

Set up Live Edit Tags for Entries with REST

Live edit tags allow you to navigate to the field that contains the website content being previewed within the Live Preview pane. When you click on the "Edit" button beside a content block in the preview pane, 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-Content-in-Preview-Pane.gif

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} 

for example,

home.blt80654132ff521260.en-us.json_rte

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, we 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. Import the addEditableTags() method


    Now, import the addEditableTags() method from the Contentstack SDK:
    const Contentstack = require("contentstack");
    const addEditableTags = Contentstack.Utils.addEditableTags
    

    Note: The addEditableTags() method is also available in the Contentstack JavaScript Utils SDK package.

  2. Locate the Stack.ContentType() method


    Firstly, navigate to the website code where the JavaScript Delivery SDK delivers entry content, and move to the section where you use the Stack.ContentType() method.
    Here is a sample code for the Stack.ContentType() method:
    let entry = await Stack.ContentType("content_type_uid").Query()
                .where("url", URL)
                .find();
    
    To enable variant support in edit tags include the .addParams({"include_applied_variants": "true"}) param:
    let entry = await Stack.ContentType("content_type_uid").Query()
                .addParams({"include_applied_variants": "true"})
                .where("url", URL)
                .find();
    
  3. Generate edit tags for previewed entry content


    After retrieving data using the Contentstack JavaScript Delivery SDK, 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 we cannot directly add any attributes in the form of string. Instead, we 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:

    let entry = await Stack.ContentType("content_type_uid").Query()
                .where("url", URL)
                .find();
    addEditableTags(entry[0][0], "content_type_uid", false, 'en-us')
    

    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 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",
           environment: "your environment",
           branch: "your branch"
    },
       clientUrlParams: {
           protocol: "https",
           host: "app.contentstack.com",
           port: 443,
       },
    })
    

    Here, the ClientUrlParams key is optional and is set for the North America region. For other regions, you can use the following region-specific config values:

    • AWS Europe host: "eu-app.contentstack.com"
    • Azure NA host: "azure-na-app.contentstack.com"
    • AZURE EU host: "azure-eu-app.contentstack.com"
    • GCP NA host: "gcp-na-api.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 blocks 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, we 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. Enable Support for Multiple Field Actions in Visual Builder

    To enable actions like adding, deleting, and ordering an instance of a multiple field (block of Modular Blocks field), add live edit tags for each instance of the field. Add the live edit tag of the field to the parent element of these instances.

    In this code snippet, page_components represents a Modular Blocks field. This field has an array type value with each array element representing a block. Each block is mapped to a component or HTML element and the live edit tag for the block is added using the page_components__${index} key on the $ object.

    <div {...(entry.$?.page_components ?? {})}>
      {entry.page_components?.map((component, index) => (
        <div key={`component-${index}`} {...entry.$?.[`page_components__${index}`]}>
          <Section component={component}/>
        </div>
      ))}
    </div>
    
  7. Add CSS to display edit buttons in the project

    Note: This step is not required for Live Preview SDK version 2.0.0 and above.

    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 main index.js file using npm 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@1.4.3/dist/main.css">
    

Configure Edit button Using the editButton Object

The editButton object, included in the Live Preview Utils SDK, allows you to manage the "Edit" button, enabling customization for both the Live Preview portal and external applications.

It offers the following features:

  • Enable/disable the "Edit" button
  • Include/exclude the "Edit" button from inside/outside the Live Preview panel
  • Adjust the position of the "Edit" button using eight over predefined positions

The editButton object contains four keys:

  • enable

    This key lets you specify whether you want to display the “Edit” button or not. It is of type “Boolean” with the value true/false.

    typedefaultoptional
    booleantrueno
  • exclude

    This key provides you with the option to exclude the edit button from either inside or outside the Live Preview portal for certain conditions.

    typedefaultoptional
    array[ ]yes

    It is of type “Array” and takes one of the following string values:

    • insideLivePreviewPortal

      Used when you want to remove the “Edit” button from within the Live Preview portal.

    • outsideLivePreviewPortal

      Used when you want to remove the “Edit” button from outside the Live Preview portal.

    Note: Although you have excluded the "Edit" button for Live Preview, you can add the cslp-buttons query parameter in your website URL to display the "Edit" button outside of your Live Preview-enabled website.

  • includeByQueryParameter

    This key is used to override the cslp-buttons query parameter. You can set this to true/false to enable/disable the "Edit" button option, respectively.

    typedefaultoptional
    booleantrueyes
  • position

    The user can place the "Edit" button in eight predefined positions within or over the Live Preview portal using these values: left, right, top-left (or top), top-right, top-center, bottom-left (or bottom), bottom-right, and bottom-center.

    typedefaultoptional
    stringtopyes

    Note: The default position of the "Edit" button is set to "top". In a collaborative work environment, you can also manually position the “Edit” button on your website by applying the data-cslp-button-position attribute to the HTML tag with one of the position values.

    For example:

    ContentstackLivePreview.init({
        ...
        editButton: {
            enable: true,
            exclude: ["outsideLivePreviewPortal"],
            includeByQueryParameter: false,
            position:'top-right',
        }
    });
    
Was this article helpful?
^