# Implementing Live Preview

### About this export

| Field | Value |
| --- | --- |
| **content_type** | course |
| **platform** | contentstack-academy |
| **source_url** | https://www.contentstack.com/academy/courses/implementing-live-preview |
| **language** | en |
| **product_area** | Contentstack Academy |
| **learning_path** | contentstack-developer-certification |
| **course_id** | implementing-live-preview |
| **slug** | implementing-live-preview |
| **version** | 2026-03-01 |
| **last_updated** | 2026-04-28 |
| **status** | published |
| **keywords** | ["Contentstack Academy"] |
| **summary_one_line** | Hey there! Welcome to our course on the Live Preview feature in Contentstack! Get ready to explore a powerful tool that brings real-time content editing to your fingertips. In this course, we'll dive into the Live Previe… |
| **total_duration_minutes** | 45 |
| **lessons_count** | 11 |
| **video_lessons_count** | 0 |
| **text_lessons_count** | 11 |
| **linked_learning_path** | contentstack-developer-certification |
| **linked_assessment_ref** | LMS_UNCONFIGURED_COURSE_ASSESSMENT |
| **markdown_file_url** | /academy/md/courses/implementing-live-preview.md |
| **generated_at** | 2026-04-28T06:55:44.600Z |
| **intended_audience** | [] |
| **prerequisites** | [] |
| **related_courses** | [] |

> **Academy MD v3** — companion `.md` for Ask AI. Quizzes and graded assessments are **LMS-only**; this file never contains answer keys.

## Course Overview

| Metadata | Value |
| --- | --- |
| Catalog duration | 45m 28s |
| Released (if known) | 2026-03-01 |
| Product area | Contentstack Academy |

### Overview

Hey there!

Welcome to our course on the Live Preview feature in Contentstack! Get ready to explore a powerful tool that brings real-time content editing to your fingertips.

In this course, we'll dive into the Live Preview feature within Contentstack. Live Preview allows you to see your content updates instantly as you make them, providing a seamless and dynamic editing experience. Whether you're tweaking text, adjusting images, or making layout changes, Live Preview lets you view your content exactly as it will appear to your audience, eliminating the guesswork and streamlining your content creation process.

We'll cover everything from setting up Live Preview to configuring it for different environments, including both Client-Side Rendering (CSR) and Server-Side Rendering (SSR). 

By the end of this training, you'll have a solid understanding of how to leverage Live Preview in Contentstack, empowering you to create, edit, and publish content with confidence and precision.

Ready to enhance your content editing experience with Live Preview in Contentstack? Let's embark on this exciting journey together!

### Learning objectives

1. Follow each lesson in order.
2. Practice in a training stack using placeholders **YOUR_STACK_API_KEY** and **YOUR_DELIVERY_TOKEN** in local `.env` files only.
3. Validate API responses against the official documentation.

### Topics covered

Contentstack Academy

## Course structure

```text
implementing-live-preview/
├── 01-how-to-complete-the-live-preview-course · text · 3 min
├── 02-introduction-to-live-preview · text · 1 min
├── 03-untitled · text · 3 min
├── 04-how-live-preview-works · text · 1 min
├── 05-live-preview-rest-delivery-sdk · text · 1 min
├── 06-live-preview-graphql-api · text · 1 min
├── 07-live-edit-tags · text · 1 min
├── 08-chrome-extension · text · 1 min
├── 09-comprehensive-guide-to-setting-up-csr-and-ssr-for-live-preview · text · 1 min
├── 10-limitations-of-live-preview · text · 3 min
├── 11-additional-resources-references · text · 3 min
```

## Lessons

### Lesson 01 — How to Complete the Live Preview Course

<!-- ai_metadata: {"lesson_id":"01","type":"text","duration_minutes":3,"topics":["How","Complete","the","Live","Preview","Course"]} -->

#### Lesson text

# Welcome to Live Preview with Contentstack

This course is intended to outline the Contentstack features and techniques for using the Live Preview features with your content, understand the APIs, and how to leverage Live Preview within your implementation. 

Required for this course:

1.  Account in Contentstack with access to a Stack as an Administrator or Developer. Create a training Stack [here](https://www.contentstack.com/academy-old/). Training stacks are available for 90 days. Alternatively, you can bootstrap a [Starter App via the CLI](https://www.contentstack.com/docs/developers/cli/bootstrap-starter-apps) or from the [Marketplace](https://app.contentstack.com/#!/marketplace/starters). 
2.  Permissions to create a new Live Preview.

#### Key takeaways

- Connect **How to Complete the Live Preview Course** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 02 — Introduction to Live Preview

<!-- ai_metadata: {"lesson_id":"02","type":"text","duration_minutes":1,"topics":["Introduction","Live","Preview"]} -->

#### Lesson text

### **What is Live Preview?**

The Live Preview feature in Contentstack allows users to see real-time updates to their content as they make changes. 

This means that any edits or modifications to the content are immediately reflected in the preview, providing a dynamic and interactive way to view and validate content before publishing. 

Here are some key aspects of the Live Preview feature:

*   **Multiple Device Previews:** Users can preview content across different devices and screen sizes to ensure responsive design and consistency.
*   **Contextual Editing:** Users can click directly on the content in the preview pane to edit it, making the editing process more intuitive and efficient. 
*   **Immediate Effect:** Live preview eliminates the need to manually refresh or rebuild pages in real time.
*   **Reduced Errors:** Content creators can see how their content will look in the final environment in real-time, allowing them to catch any formatting or content errors, ensuring that content aligns with brand guidelines and design expectations, leading to higher-quality output.
*   **Faster Iterations:** With immediate effect, content creators can make quick adjustments, speeding up the content creation and review process.

Overall, the **Live Preview** feature enhances content management by providing a seamless and immediate way to visualize and refine content before it goes live.

### **Use Cases of Live Preview**

1.  **Omnichannel Preview Experience:**  
    Content managers can preview how their content will appear across various devices (mobiles, tablets, desktops) in real-time. They can switch between different aspect ratios to ensure responsiveness and consistency across platforms. This capability allows them to optimize content presentation without needing to switch between different devices physically.
2.  **Real-Time Edits:**  
    By clicking on the "Edit" icon next to any content block within the Live Preview window, content managers can instantly navigate to the corresponding field in the editor. This seamless integration between preview and editing facilitates quick updates and adjustments. Content managers can see changes as they make them, ensuring accuracy and alignment with their vision.
3.  **Instant Testing of Content Changes:**  
    Content managers can preview and test content changes immediately without the need to publish or save them. This feature is particularly useful for iterating on design elements, trying out different content placements, or experimenting with new features. It allows for rapid prototyping and refinement directly within the preview environment.
4.  **Scope for Innovation and Enhancement:**  
    Live Preview is integrated as a core feature within the Contentstack platform rather than a separate add-on. This integration ensures that developers can leverage and innovate upon the feature seamlessly. They can incorporate new functionalities or enhance existing ones directly within the native environment, promoting continuous improvement and adaptation.
5.  **Content Schema Integrity:**  
    Developers can maintain the integrity of the content schema while using Live Preview. Content entries remain structured in JSON format, allowing developers to define and modify content models as needed. This structured approach ensures consistency across content types and simplifies the process of scaling or modifying content structures over time.

#### Key takeaways

- Connect **Introduction to Live Preview** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 03 — Basic implementation

<!-- ai_metadata: {"lesson_id":"03","type":"text","duration_minutes":3,"topics":["Basic","implementation"]} -->

#### Lesson text

### **How to enable Live preview on your Stack?**

1.  Under stack settings, go to Live Preview, tick enable live preview and select a Default Preview [Environment](https://www.contentstack.com/docs/developers/set-up-environments/about-environments).  
    ![ImplementingLivePreview\_L3\_img-1.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt83eed7e9d24e0d53/67e1ad0029f30c277bf8de60/ImplementingLivePreview_L3_img-1.png)  
    
2.  Go to Environment settings and add the base URL (hosted website URL) in that environment’s settings.This hosted website should be fetching data from the same environment.  
    ![ImplementingLivePreview\_L3\_img-2.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltd7f06a9a55b96fc3/67e1ad4db9f9a66e76dc40cf/ImplementingLivePreview_L3_img-2.png)

### **Generate Preview Token for you stack**

1.  Under stack settings, go to [tokens](https://www.contentstack.com/docs/developers/create-tokens/types-of-tokens).
2.  Under [Delivery Token](https://www.contentstack.com/docs/developers/create-tokens/about-delivery-tokens), create a new token.  
    ![ImplementingLivePreview\_L3\_img-3.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt17620102d7b0b49e/67e1adc3c0d1f26cc60a3d03/ImplementingLivePreview_L3_img-3.png)  
    
3.  Fill in the **name and description (optional), then select the branch and environment**, enable the Create [Preview Token](https://www.contentstack.com/docs/developers/create-tokens/about-delivery-tokens#about-preview-tokens) toggle, and Generate Token.  
    ![ImplementingLivePreview\_L3\_img-4.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltb0567501a748508b/67e1add8b9f9a60a39dc4132/ImplementingLivePreview_L3_img-4.png)

#### Key takeaways

- Connect **Basic implementation** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 04 — How Live Preview works

<!-- ai_metadata: {"lesson_id":"04","type":"text","duration_minutes":1,"topics":["How","Live","Preview","works"]} -->

#### Lesson text

### **What is your website Architecture?**

When deciding between Client-Side Rendering (CSR) and Server-Side Rendering (SSR) for implementing Contentstack live preview, it's essential to consider the specific needs and constraints of your project.

Contentstack supports both SSR and CSR, and the choice might also depend on the specific framework you are using (e.g., Next.js for SSR, React for CSR). Contentstack provides [SDKs and APIs](https://www.contentstack.com/docs/developers/set-up-live-preview/how-live-preview-works-with-sdk) that are compatible with both approaches.

Here are some key factors to help you decide:

#### Client-Side Rendering (CSR)

*   **Interactivity:** CSR allows for highly interactive applications as JavaScript is executed on the client side.
*   **Initial Load Time:** The initial load time can be longer because the browser has to download and execute JavaScript before rendering the content.
*   **Complexity:** Implementing live previews might be more complex as you need to ensure that the client-side app can handle real-time updates and rendering.

#### Server-Side Rendering (SSR)

*   **Initial Load Time:** The initial load time can be faster because the server sends a fully rendered page to the client.
*   **Complexity:** Implementing live previews can be easier and more seamless since the server renders the updated content.
*   **Performance on the Server:** SSR can be more demanding on the server, especially with a high number of concurrent users.
*   **Interactivity:** SSR might not be as interactive out of the box as CSR, although hybrid approaches can mitigate this.

  

#### Hybrid Approach

In many cases, a hybrid approach, using both CSR and SSR, might be the best solution. For example, you can use SSR for the initial load to benefit from SEO and faster initial load times, and then switch to CSR for subsequent interactions to enhance interactivity.

  
  

* * *

  
  

### **Live Preview in CSR**

Client-side rendering (CSR) involves a process where all rendered HTML client pages are generated on the browser side. Consequently all the data fetching is also done on the client side. This guide explains in detail how to set up Live Preview for an CSR Application.

  

#### How CSR Works:

1.  **Initial HTML and JavaScript Load**:
    *   When a user visits a CSR-based web application, the server sends an initial HTML document that often includes references to JavaScript frameworks like React, Angular, or Vue.js.
    *   This initial HTML might include placeholders or loading indicators where content will be rendered dynamically.
2.  **Data Fetching and Rendering**:
    *   Once the browser loads the initial HTML and JavaScript, the client-side code makes requests to APIs or other data sources to fetch necessary data.
    *   This data is then used by the JavaScript frameworks to dynamically render the actual content on the page.
    *   This process allows for highly interactive and responsive user interfaces, as changes can be made to the UI without requiring full page reloads.
3.  **Benefits**:
    *   **Speed and Responsiveness**: CSR can provide a faster initial load time because only minimal HTML is initially transferred.
    *   **Interactivity**: Applications can feel more responsive since data fetching and rendering happen on the client side without waiting for server responses for every interaction.
    *   **Flexibility**: Developers have more control over how content is displayed and can create highly dynamic user interfaces.

![ImplementingLivePreview\_L4\_img-1.avif](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt42d7003887817022/67e1b16e914c2442924972c1/ImplementingLivePreview_L4_img-1.avif)

**Working of Live Preview in CSR:**

When a website is opened in the Live Preview pane, data is fetched live from the current entry using a GET call over preview service url. If changes are made to the entry, with those changes Contentstack sends a PATCH call. The onEntryChange() function then triggers another GET call to fetch the updated data, which is re-rendered on the webpage in Live Preview pane.

![ImplementingLivePreview\_L4\_img-2.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt79f0d34846849b01/67e1b6f367538e1ec22bd731/ImplementingLivePreview_L4_img-2.png)  
  

* * *

  
  

### **Live Preview in SSR**

Server-side rendering (SSR) involves a process where an application generates rendered HTML client pages on the server rather than in the browser. Consequently, data fetching is also done on the server side, with HTML pages created and sent to the browser. This guide explains in detail how to set up Live Preview for an SSR Application.

#### Server-Side Rendering (SSR)

1.  **Request Handling**:
    *   When a user requests a page from a SSR-based application, the server processes the request and generates the complete HTML for that page.
    *   This includes the content of the page, data fetched from databases or APIs, and the initial state of any client-side frameworks (if used).
2.  **HTML Generation**:
    *   Server-side frameworks like Next.js (for React), Nuxt.js (for Vue.js), or server-side template engines (e.g., EJS, Pug) are commonly used to facilitate SSR.
    *   These frameworks or engines render components or templates with the data provided by the server into a complete HTML document.
3.  **Sending HTML to Client**:
    *   Once the HTML is generated on the server, it is sent to the client's browser as a fully formed document.
    *   This HTML can include all the content necessary for the initial view of the page, reducing the need for subsequent data fetching before the page can be fully rendered.
4.  **Client Interaction**:
    *   Once the initial HTML is rendered on the client's browser, any further interactivity can be enhanced with client-side JavaScript.
    *   This includes handling user events, making API calls for dynamic updates, and managing client-side state using frameworks like React, Vue.js, or Angular.  
        

![ImplementingLivePreview\_L4\_img-3.avif](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc9d5f1526d39df0/67e1b791a352df6071697026/ImplementingLivePreview_L4_img-3.avif)  

#### Working of Live Preview in SSR

When a website is opened in the Live Preview pane, the server builds HTML pages with data fetched live from the current entry using a GET call over the preview-service URL. These pages are then sent to the client and rendered in the Live Preview pane. If changes are made to the entry, Contentstack sends a PATCH call with those changes. The webpage in the Live Preview pane is then refreshed, and the server builds HTML pages with the updated data fetched from another GET call. These updated pages are sent to the client and rendered in the Live Preview pane.

![ImplementingLivePreview\_L4\_img-4.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltdc4fe0eae7f658a1/67e1b7c72fdf5e5ad0069dde/ImplementingLivePreview_L4_img-4.png)

#### Key takeaways

- Connect **How Live Preview works** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 05 — Live preview: REST Delivery SDK

<!-- ai_metadata: {"lesson_id":"05","type":"text","duration_minutes":1,"topics":["Live","preview","REST","Delivery","SDK"]} -->

#### Lesson text

### **1\. Generate Preview Token**

In the **Basic Implementation** module, we have already generated a preview token.  

### **2. Update Contentstack's delivery SDK**

To update the package via npm, use the following command:

npm install contentstack

  

To allow [delivery SDK](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/about-javascript-delivery-sdk) to fetch preview content, we need to add live preview configs to the stack initialization method i.e. to Contenstack.Stack() method.

Contenstack.Stack() method takes the live\_preview object which includes following parameters:

*   **preview\_token**: The preview\_token is used to authenticate API requests to fetch preview content.
*   **enable:** This boolean property lets you enable the live preview on your client-side. Setting this to true turns on the live preview feature, allowing real-time updates to be shown in the application. If set to false, the live preview functionality will be disabled.
*   **host:** The host property is optional and is used to define the endpoint that the application will connect to for fetching the live preview data. REST API hosts according to regions:  
    
    *   **AWS NA**: rest-preview.contentstack.com
    *   **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
    
      
    

import Contentstack from 'contentstack'  
  
const Stack = Contentstack.Stack({  
    ... // update your configs here  
    live\_preview: {   
        preview\_token: preview\_token,   
        enable: true,   
        host: 'rest-preview.contentstack.com' //optional for AWS-NA region  
    },   
    ...  
})

### **3\. Install / Update and Initialize the Live Preview Utils SDK**

  
[Live preview utils SDK](https://www.contentstack.com/docs/developers/sdks/utils-sdk/javascript/about-javascript-live-preview-utils-sdk) listens to content changes and requests the delivery SDK to preview changes in real-time. Therefore **Live Preview Utils SDK is always initialized at the client side** irrespective of CSR/SSR is being followed.

To use Live preview utils SDK you can either install it using npm or import it using the script tag in your HTML page.

To install the package via npm, use the following command:

npm install @contentstack/live-preview-utils

initialization :

import ContentstackLivePreview from "@contentstack/live-preview-utils";  
  
ContentstackLivePreview.init({  
    enable: true  
});

or you can use Script tag to import and initialize live preview utils sdk:

![ImplementingLivePreview\_L5\_img-1.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt48250a2b71332476/67e1b9f2362ee30f7f55cbbd/ImplementingLivePreview_L5_img-1.png)  

### **ContentstackLivePreview.init() method:**

init() method initializes the Live Preview Utils SDK. The init() method accepts a configuration object as a parameter.

The following explains all the configuration options available.

*   **enable**: The enable property determines whether Live Preview communications have been enabled. It takes a boolean value. It is an optional property which takes the default value as true. 
*   **ssr**: The ssr property controls how data is updated for previewed content when you modify entry content. It is an optional property which takes the default value as true.  Its behavior changes based on whether your application uses Server-Side Rendering (SSR) or Client-Side Rendering (CSR).
    *   **When** ssr **is set to** true: Your application or website is rendered on the server (SSR). This means that each time you edit content, a request is made for a new HTML page.
    *   **When** ssr **is set to** false: Your application is rendered on the client side (CSR). In this case, your framework (e.g., React) will fetch the updated data and reload the existing page.  
        
*   **stackSdk**: The stackSdk represents the stack object. For CSR mode stackSdk object is required. When stackSdk object is provided utils SDK initialization switches to CSR mode. It is **required** to override default SSR configs.
*   stackDetails: The stackDetails object contains stack-related information which helps you redirect to the corresponding entry when you use edit tags on your website. The stackDetails object contains the following properties:
    *   apiKey
    *   branch
    *   environment 
        

*   **clientUrlParams**: The clientUrlParams object represents the URL information where your stack is present which includes host, port, and protocol. AWS NA region app host is default  
    {  
    host: "app.contentstack.com", // AWS NA region app host  
    }  
      
    The default params take AWS NA region values.  
      
    Client host for other regions:  
    • AWS EU region: eu-app.contentstack.com  
    • Azure NA region: azure-na-app.contentstack.com  
    • Azure EU region: azure-eu-app.contentstack.com  
    • GCP NA region: gcp-na-app.contentstack.com  
    • GCP EU region: gcp-eu-app.contentstack.com

*   **cleanCslpOnProduction**: When enable is set to false and cleanCslpOnProduction is set to true, the data-cslp attributes are removed from the website.  
      
    When operating in a production environment, you generally want to avoid including data-cslp attributes in your site's HTML tags or enabling the live preview feature. To manage this, you can implement conditional statements to control the live preview functionality based on the current environment.

ContentstackLivePreview.init({    
    enable: process.env.CONTENTSTACK\_ENVIRONMENT !== "production" // returns false and disables the live-preview in production environment  
    cleanCslpOnProduction: process.env.CONTENTSTACK\_ENVIRONMENT === "production" // returns true and cleans data-cslp attributes in production environment  
    ...  
}

  

*   **editButton**: The editButton object provides functionality to manage the "Edit" button in your application, whether you're inside or outside the Live Preview portal. It offers several key features, including edit button visibility and control over the inclusion or exclusion of the "Edit" button within or outside the Live Preview panel, You can also adjust the button’s positioning based on your needs. Following keys enables you to customize editButton object:
    *   enable: This key accepts boolean values, which let's you specify whether you want to display the “Edit” button or not. the default values is true.
    *   exclude: This key provides you with the option to exclude the editButton from either inside or outside the Live Preview portal for certain conditions. It is of type “Array” with any one of the following string values:  
        *   insideLivePreviewPortal is used when you want to remove the “Edit” button from within the Live Preview portal.
        *   outsideLivePreviewPortal is used when you want to remove the “Edit” button from outside the Live Preview portal.  
            
    *   includeByQueryParameter: This boolean property is used to override the cslp-buttons query parameter. You can set this to true/false to enable/disable the "Edit" button option, respectively. By default it is set to true
    *   position: This property lets you customize the "Edit" button’s placement using one of eight predefined positions. It accepts the following values: left, right, top-left (or top), top-right, top-center, bottom-left (or bottom), bottom-right, and bottom-center.

example:

ContentstackLivePreview.init({  
    ...  
    editButton: {  
        enable: true,  
        exclude: \["outsideLivePreviewPortal"\],  
        includeByQueryParameter: false,  
        position:'top-right',  
    }  
});

  

*   **debug**: Setting debug: true in ContentstackLivePreview.init() enables debugging mode for the Live Preview functionality. This mode is useful for developers as it provides additional logging and detailed information about the Live Preview's internal processes and interactions.  
    When you're done with debugging, it's generally a good idea to set debug to false or remove the debug option to avoid unnecessary logging in a production environment.

### **Configure Live preview Across Pages - CSR Powered website**

_ContentstackLivePreview.onEntryChange()_ method executes when an entry content is being changed, inside this method, you can add logic to fetch preview content.  

![ImplementingLivePreview\_L5\_img-2.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltc506e7b1bff7d46b/67e1bcb4d148edb993a3ff67/ImplementingLivePreview_L5_img-2.png)

In the above example

updateData() function is responsible for fetching new data and updating the state.

ContentstackLivePreview.onEntryChange(updateData) registers the updateData function to be called whenever an entry is updated, it fetches the draft/preview content and updates the component's state with setData i.e. data is being updated and rerendered on every change happening in the entry.  

### **Configure Live Preview Across Pages - SSR Powered website**

Set up a middleware to track all new changes being made to the entry content. This middleware injects the live preview hash and content type UID into the Stack class using the livePreviewQuery() method.

app.use((req, response, next) => {  
    // this will get live\_preview hash and ContentType to the request  
    Stack.livePreviewQuery(req.query);  
    next();  
});

In other Javascript frameworks like next.js, you can directly update the live preview query from the page component itself. 

**Next.js (SSR) example:**

*   Set up a middleware: After initialization of live preview SDK in the client component, Let's set up a middleware to track all new changes being made to the entry content. This middleware injects the live preview hash and content type UID into the Stack instance using the livePreviewQuery() method.

// utils.js ...  
export const setLivePreviewQueryParams = (queryParams) => {  
    if(queryParams?.live\_preview) {  
        Stack.livePreviewQuery(queryParams)  
    }  
}  
...  

  

*   Configure Pages: setLivePreviewQueryParams() updates the live preview query parameters based on the searchParams passed to the page which enables live content updates. This ensures that every time the page loads or search parameters change, we’re checking for and updating live preview functionality parameters.

![ImplementingLivePreview\_L5\_img-3.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltaac121a05a27022e/67e1be35a352dfb810697091/ImplementingLivePreview_L5_img-3.png)  
  

After implementing these steps you are all set to live preview your first page.  

### Configure Live preview - SSG-powered Website

Static site generation (SSG) is a web development strategy that generates HTML pages at build time using available data and templates. This results in pre-rendered static files that are served directly from a web server. In contrast, server-side rendering (SSR) and client-side rendering (CSR) generate pages dynamically for each request. SSG is used where the website needs minimal dynamic content  
When working with Live Preview the server side generates and serves static HTML files with initial/published data and the client-side handles the Live Preview in CSR mode.  

![ImplementingLivePreview\_L5\_img-4.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt13ddff7eabd3ae7d/67e1bee194fe2fa63fdc79e8/ImplementingLivePreview_L5_img-4.png)

SSG Live preview example:  

![ImplementingLivePreview\_L5\_img-5.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blte9860aefeb60f424/67e1bf09a388fcb626812206/ImplementingLivePreview_L5_img-5.png)

#### Key takeaways

- Connect **Live preview: REST Delivery SDK** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 06 — Live Preview - GraphQL API

<!-- ai_metadata: {"lesson_id":"06","type":"text","duration_minutes":1,"topics":["Live","Preview","GraphQL","API"]} -->

#### Lesson text

### **How to setup Live preview with GraphQL API?**

The [GraphQL Content Delivery API](https://www.contentstack.com/docs/developers/apis/graphql-content-delivery-api) offers a more efficient alternative to traditional Content Delivery APIs. It enables you to fetch customized responses or retrieve data from nested or multiple resources with a single API request.

GraphQL is a versatile and customizable API query language. Contentstack's GraphQL API allows you to query precisely what you need, without any excess. For example, you can fetch data from multiple content types with just one API request. You can also define the structure of your requests to customize the responses. Currently, Contentstack's GraphQL supports only queries, and the GraphQL types for each requested resource are generated in real-time, ensuring your content is always up-to-date.  

A GraphQL query like below is sent to https://{{domain}}/stacks/{{api\_key}} over POST method with environment parameter and access token in headers to fetch the content.  
![ImplementingLivePreview\_L6\_img-1.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltf9619548fdec8940/67e1bfd1b9f9a67f51dc4277/ImplementingLivePreview_L6_img-1.png)

### **1\. Generate Preview Token**

     In the **Basic Implementation** module, we have already generated a preview token.  

### **2\. Install / Update and Initialize the Live Preview Utils SDK**

[Live preview utils SDK](https://www.contentstack.com/docs/developers/sdks/utils-sdk/javascript/about-javascript-live-preview-utils-sdk) listens to content changes and requests the GraphQl Api to preview changes in real-time. Therefore Live Preview Utils SDK is always initialized at the client side irrespective of CSR/SSR is being followed.

To use Live preview utils SDK you can either install it using npm or import it using the script tag in your HTML page.

To install the package via npm, use the following command:

npm install @contentstack/live-preview-utils

Create a new JS file and initialize Live Preview SDK:

import ContentstackLivePreview from "@contentstack/live-preview-utils";  
  
ContentstackLivePreview.init({  
    enable: true  
});

or you can use Script tag to import and initialize live preview utils sdk:

![ImplementingLivePreview\_L6\_img-2.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltbc3ec508d7dc3b96/67e1c07b67538edd892bd7f1/ImplementingLivePreview_L6_img-2.png)

  

**ContentstackLivePreview.init() method:**

init() method initializes the ive Preview Utils SDK. The init() method accepts a configuration object as a parameter.

The following explains all the options available for the configuration.

*   **enable**: The enable property determines whether Live Preview communications have been enabled. It takes a boolean value. it is an optional property which takes the default value as true . 
*   **ssr**: The ssr property controls how data is updated for previewed content when you modify entry content. it is an optional property which takes the default value as true.  Its behavior changes based on whether your application uses Server-Side Rendering (SSR) or Client-Side Rendering (CSR).
    *   **When** **ssr** **is set to** **true**: Your application or website is rendered on the server (SSR). This means that each time you edit content, a request is made for a new HTML page.
    *   **When** **ssr** **is set to** **false**: Your application is rendered on the client side (CSR). In this case, your framework (e.g., React) will fetch the updated data and reload the existing page.
*   **stackDetails**: The stackDetails object contains stack-related information which helps you redirect to the corresponding entry when you use edit tags on your website. stackDetails object contains the following properties:
    *   apiKey
    *   branch
    *   environment   
        
*   **clientUrlParams**: The clientURLParams object represents the URL information where your stack is present which includes host, port, and protocol. AWS NA region app host is default.

{  
    host: "app.contentstack.com", // AWS NA region app host  
}

  
  
The default params take AWS NA region values.  
Client host for other regions:  
• AWS EU region: eu-app.contentstack.com  
• Azure NA region: azure-na-app.contentstack.com  
• Azure EU region: azure-eu-app.contentstack.com  
• GCP NA region: gcp-na-app.contentstack.com  
• GCP EU region: gcp-eu-app.contentstack.com  

*   cleanCslpOnProduction: When enable is set to false and cleanCslpOnProduction is set to true, the data-cslp attributes are removed from the website.  
      
    When operating in a production environment, you generally want to avoid including data-cslp attributes in your site's HTML tags or enabling the live preview feature. To manage this, you can implement conditional statements to control the live preview functionality based on the current environment.

ContentstackLivePreview.init({    
  enable: process.env.CONTENTSTACK\_ENVIRONMENT !== "production" // returns false and disables the live-preview in production environment    
  cleanCslpOnProduction: process.env.CONTENTSTACK\_ENVIRONMENT === "production" // returns true and cleans data-cslp attributes in production environment  
  ...  
}

*   **editButton**: The editButton object provides functionality to manage the "Edit" button in your application, whether you're inside or outside the Live Preview portal. It offers several key features, including edit button visibility and control over the inclusion or exclusion of the "Edit" button within or outside the Live Preview panel, You can also adjust the button’s positioning based on your needs. Following keys enables you to customize editButton object:
    *   enable: This key accepts boolean values, which let's you specify whether you want to display the “Edit” button or not. the default values is true.
    *   exclude: This key provides you with the option to exclude the editButton from either inside or outside the Live Preview portal for certain conditions. It is of type “Array” with any one of the following string values:
        *   insideLivePreviewPortal is used when you want to remove the "Edit" button from within the Live Preview portal.
        *   outsideLivePreviewPortal is used when you want to remove the "Edit" button from outside the Live Preview portal.
    *   includeByQueryParameter: This boolean property is used to override the cslp-buttons query parameter. You can set this to true/false to enable/disable the "Edit" button option, respectively. By default it is set to true
    *   position: This property lets you customize the "Edit" button’s placement using one of eight predefined positions. It accepts the following values: left, right, top-left (or top), top-right, top-center, bottom-left (or bottom), bottom-right, and bottom-center.

example:

ContentstackLivePreview.init({  
    ...  
    editButton: {  
        enable: true,  
        exclude: \["outsideLivePreviewPortal"\],  
        includeByQueryParameter: false,  
        position:'top-right',  
    }  
});

  

*   debug: Setting debug: true in ContentstackLivePreview.init() enables debugging mode for the Live Preview functionality. This mode is useful for developers as it provides additional logging and detailed information about the Live Preview's internal processes and interactions.  
    When you're done with debugging, it's generally a good idea to set debug to false or remove the debug option to avoid unnecessary logging in a production environment.

EXAMPLE:

import ContentstackLivePreview from "@contentstack/live-preview-utils";  
ContentstackLivePreview.init({  
    stackDetails: {  
        apiKey: "your-stack-api-key",  
        enironment: "your-environment-name",  
        branch: "your-branch-name"  
    },  
    enable: true,  
    ssr: false/true,  
});

### **3. Update GraphQL API Request**

To allow graphql API to fetch preview content, we need to append live preview hash and preview token in headers of API request and update url hostname to graphql preview hostname.

*   **preview\_token**: The preview\_token is used to authenticate API requests to fetch preview content.
*   **live\_preview****:** When you open any entry in a stack where the live preview feature is enabled, a Live Preview Hash(Session ID) is generated in the background. This hash is a unique identifier that can be used to save and fetch data to be displayed in the live preview panel.
*   **hostname****:** The hostname property is optional and is used to define the endpoint that the application will connect to for fetching the live preview data. GraphQL API hosts according to regions:
    *   **US (North America, or NA)**: graphql-preview.contentstack.com
    *   **AWS EU**: eu-graphql-preview.contentstack.com
    *   **Azure NA**: azure-na-graphql-preview.contentstack.com
    *   **Azure EU**: azure-eu-graphql-preview.contentstack.com
    *   **GCP NA**: gcp-na-graphql-preview.contentstack.com

  

> Note: If you are using framework which does strong caching like NextJS, then add no caching in fetch request like cache: "no-store" otherwise live preview might not work properly.

import ContentstackLivePreview from "@contentstack/live-preview-utils";  
  
const graphqlUrl = new URL(  
    \`https://graphql.contentstack.com/stacks/${CONTENTSTACK\_API\_KEY}?environment=${CONTENTSTACK\_ENVIRONMENT}\`,  
);  
  
const GRAPHQL\_HOST\_NAME = "graphql.contentstack.com";  
  
const LIVE\_PREVIEW\_HOST\_NAME = "graphql-preview.contentstack.com";  
  
function getHeaders() {  
    const headers = new Headers();  
    headers.append("Content-Type", "application/json");  
    headers.append("access\_token", CONTENTSTACK\_DELIVERY\_TOKEN);  
    return headers;  
}  
  
const gqlRequest = async (gql) => {  
    const hash = ContentstackLivePreview.hash;  
    const headers = getHeaders();  
  
    if (hash) {  
    headers.append("live\_preview", hash);  
    headers.append("preview\_token", CONTENTSTACK\_PREVIEW\_TOKEN);  
    graphqlUrl.hostname = LIVE\_PREVIEW\_HOST\_NAME;  
  
    } else {  
        graphqlUrl.hostname = GRAPHQL\_HOST\_NAME;  
    }  
  
    const res = await fetch(graphqlUrl.toString(), {  
        method: "POST",  
        headers: headers,  
        body: JSON.stringify({  
            query: gql,  
        }),  
        cache: 'no-store',  
    });  
  
    return res;  
}

### **Configure Live preview Across Pages - CSR Powered website**

_ContentstackLivePreview.onEntryChange()_ method executes when an entry content is being changed, inside this method, you can add logic to fetch preview content.  

import React, { useEffect, useState } from "react";  
import ContentstackLivePreview from "@contentstack/live-preview-utils";  
  
const updateData = () => {  
    const fetchedData = gqlRequest(query);  
    setData(fetchedData);  
};  
React.useEffect(() => {  
   ContentstackLivePreview.onEntryChange(updateData);  
}, \[\]);

In the above example

*   updateData() function is responsible for fetching new data and updating the state.
*   ContentstackLivePreview.onEntryChange(updateData) registers the updateData function to be called whenever an entry is updated, it fetches the draft/preview content and updates the component's state with setData i.e. data is being updated and re-rendered on every change happening in the entry.

### **Configure Live Preview Across Pages - SSR Powered website**

Pass query parameters from the URL into the setConfigFromParams() method of Live Preview which extract and store the hash, making it accessible via ContentstackLivePreview.hash. To achieve this, create a middleware and execute the following command:

import ContentstackLivePreview from "@contentstack/live-preview-utils";  
ContentstackLivePreview.setConfigFromParams(searchParams) // You could use objects provided by the frameworks as well.

#### Key takeaways

- Connect **Live Preview - GraphQL API** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 07 — Live Edit Tags

<!-- ai_metadata: {"lesson_id":"07","type":"text","duration_minutes":1,"topics":["Live","Edit","Tags"]} -->

#### Lesson text

### **Live Edit Tags**

Live edit tags enable you to quickly navigate to the field that holds the website content shown in the Live Preview pane. By clicking the "Edit" button next to a content block in the preview pane, you'll be taken to the corresponding field within the entry. If the field contains a reference to another entry, you will be directed to the editor page of that referenced entry.  
The [Live Preview Utils SDK](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/about-javascript-live-preview-utils-sdk) searches for the elements which contain the edit tags referred to as data-cslp.  
Edit tags contain the information about where your field exists in the entry. 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.blt80654132ff521599.en-us.modular\_blocks\[0\].teaser.heading

  
**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](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/about-javascript-delivery-sdk/), you can use the addEditableTags() method to automatically generate the edit tag for you. 

### **Import the addEditableTags() method**

  
Install Contentstack Utils from npm using the following command:

npm i @contentstack/utils

import addEditableTags using the following commands: 

// utils.js  
import {addEditableTags} from "@contentstack/utils”

### **Generate edit tags for entry content**

To generate entry content, navigate to the code responsible for delivering the entry content. After retrieving data from Contentstack, the resulting entry object is passed to the **addEditableTags()** method to add edit tags to the previewed entry content.

addEditableTags(entry, content\_type\_uid, tagsAsObject, locale)

here , 

*   **entry:** entry object you fetched from Contentstack SDK/API call
*   **content\_type\_uid**: is the unique ID of the current entry’s content type
*   **tagsAsObject:** By default, tagsAsObject is set to false, and it appends data-cslp in the form of a string cause as follows:

'data-cslp=path.to.field'

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

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

*   **locale**: The locale code used to fetch entry.  
    

The addEditableTags() method adds a new key-value pair at every level of your entry result object. where,

*   Key is denoted by **$** sign
*   Value is an object which contains the field name and data-cslp details.

For example, if you pass the following object to the addEditableTags method

{  
    "heading": "Exploring the Vineyards: A Journey through Wine Country",  
    "description": "As a seasoned traveler, you understand the allure of exploring new destinations. One such destination that has been gaining popularity is the wine country.",  
  
    "cta": {  
        "text": "Learn More",  
        "url": "/explore-the-vineyards"  
    },  
}

  
The result returned will look like:

{  
    "heading": "Exploring the Vineyards: A Journey through Wine Country",  
  
    "description": "As a seasoned traveler, you understand the allure of exploring new destinations. One such destination that has been gaining popularity is the wine country.",  
  
    "cta": {  
        "text": "Learn More",  
        "url": "/explore-the-vineyards",  
            "$": {  
                "text": {  
                    "data-cslp": "text\_banner.blt6fb37c46b9d17365.cta.text"  
                },  
                "url": {  
                    "data-cslp": "text\_banner.blt6fb37c46b9d17365.cta.url"  
                }  
            }  
    },  
  
    "$": {  
        "heading": {  
            "data-cslp": "text\_banner.blt6fb37c46b9d17365.heading"  
        },  
        "description": {  
            "data-cslp": "text\_banner.blt6fb37c46b9d17365.description"  
        },  
        "cta": {  
            "data-cslp": "text\_banner.blt6fb37c46b9d17365.cta"  
        },  
    }  
  
}

### **Generate Edit tags example - REST**

Once you have retrieved data using the Contentstack, utilize the addEditableTags() function. Pass the retrieved entry into this function to incorporate edit tags into the draft entry content effectively. The following example is using JavaScript Delivery SDK to fetch content.

// utils.js  
export const getEntryByUrl = async (contentTypeUid, locale, entryUrl) => {  
    try {  
        const result = Stack.ContentType(contentTypeUid)  
            .Query()  
            .language(locale)  
            .where('url', \`${entryUrl}\`)  
            .toJSON()  
            .find()  
  
    addEditableTags(result\[0\]\[0\], contentTypeUid, true, locale)  
    const data = result\[0\]\[0\]  
    return data  
  
    } catch (error) {  
        throw error  
    }  
}

### **Generate Edit tags example - Graph QL**

Locate the section of your website's code responsible for fetching content from Contentstack. To ensure proper functionality of live editing, it's crucial to retrieve system system {uid} from GraphQL at the root of the query and system {uid, content\_type\_uid} for all references.

Here is an example of the gqlRequest() method for your reference:  

export const getHeaderRes = async (): Promise => {  
    const gql = \`  
query HeaderQuery {  
    all\_header {  
        total  
        items {  
            title  
            logoConnection {  
                edges {  
                    node {  
                        url  
                        filename  
                    }  
                }  
            }  
            navigation\_menu {  
                label  
                page\_referenceConnection {  
                    totalCount  
                    edges {  
                        node {  
                            ... on Page {  
                                title  
                                url  
                                system {  
                                    uid  
                                    content\_type\_uid  
                                }  
                            }  
                        }  
                    }  
                }  
            }  
            notification\_bar {  
                show\_announcement  
                announcement\_text {  
                    json  
                }  
            }  
            system {  
                uid  
            }  
        }  
    }  
}  
\`;

  

Next, include \_content\_type\_uid and uid alongside system, and assign the values from system.content\_type\_uid to \_content\_type\_uid  and system.uid to uid:

const transformed = {  
    ...header,  
    logo: header.logoConnection.edges\[0\].node,  
    navigation\_menu: header.navigation\_menu.map((item: any) => ({  
        ...item,  
        page\_reference: item.page\_referenceConnection.edges.map((edge: any) => ({  
            ...edge.node,  
            uid: edge.node.system.uid,  
            \_content\_type\_uid: edge.node.system.content\_type\_uid,  
        })),  
    })),  
    uid: header.system.uid,  
    notification\_bar: {  
        ...header.notification\_bar,  
    },  
};

  

Include data-cslp parameters in transformed response by using addEditableTags() method from @contentstack/utils

addEditableTags(transformed, "header", true);

### **Set up the Live Preview Utils SDK**

To navigate to the correct stack it is required to provide the stackDetails object parameter to the live preview initialization method.

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

  
_Note: The host value is based on the region where your stack is located_

*   **US (NA) region host:** app.contentstack.com
*   **EU region host:** eu-app.contentstack.com
*   **Azure NA region host:** azure-na-app.contentstack.com
*   **Azure EU region host:** azure-eu-app.contentstack.com
*   **GCP NA region host:** gcp-na-app.contentstack.com

### **Configure live edit tags across webpages**

##### For pure HTML tags (tagsAsObject:false) example: 

To add edit tags to your website's HTML:

1.  **Find the HTML Section:** Locate the part of your HTML code where you want to include edit tags.
2.  **Add Edit Tags:** To access an edit tag, fetch the path to the field in your entry data and add a dollar sign ($) before the last field in the path.
    *   For instance, if the path to your data is data.description.height, the edit tag should be data.description.$.height.

Example snippet:

![ImplementingLivePreview\_L7\_img-1.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt9561e0d5f6257c5e/67e1c8296678fd4011aeaa06/ImplementingLivePreview_L7_img-1.png)

#####   

##### React-based Components (tagsAsObject:true) example: 

For React-based Applications you can set tagsAsObject to true, by enabling this you will receive edit tag details in object format. You need to destructure the object while passing it within the JSX element.Let's add edit tags to following JSX snippet: 

![ImplementingLivePreview\_L7\_img-2.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltb3ff4792d476ebc4/67e1c88d0b0fc52dadb4b1d4/ImplementingLivePreview_L7_img-2.png)

After adding edit tags the above JSX will be:

![ImplementingLivePreview\_L7\_img-3.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc04529a9ee43a32/67e1c8ade6ff22567b0d1756/ImplementingLivePreview_L7_img-3.png)

#### Key takeaways

- Connect **Live Edit Tags** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 08 — Chrome Extension

<!-- ai_metadata: {"lesson_id":"08","type":"text","duration_minutes":1,"topics":["Chrome","Extension"]} -->

#### Lesson text

### **What is Contentstack Google Chrome Extension?**

The Contentstack Google Chrome Extension enables users to seamlessly transition from a live webpage to its corresponding entry in Contentstack.

When viewing a webpage powered by Contentstack, users with editing permissions will notice an edit button at the bottom right or left of the page. Clicking this button directs them to the corresponding entry in Contentstack.

This feature significantly reduces the time and effort needed to locate specific entries within Contentstack’s web application. It also optimizes the editing experience by allowing users to update content instantly.

  

**Steps to setup Chrome Extension:**

1.  Install extension from [Contentstack Google Chrome Extension](https://chrome.google.com/webstore/detail/contentstack/kliacmaffhaakhphcelpjcmienmikgoa).
2.  In the pop-up enter stack and domain settings and button settings. Add the Stack API Key, Hosted Domain Name or Host of your website and select the Region of your organization.  
    
    ![ImplementingLivePreview\_L8\_img-1.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt7e91b21db8560d2a/67e1cb4c29f30c8409f8e1c0/ImplementingLivePreview_L8_img-1.png)
3.  Add the following attributes to the body tag of you websites page:

data-pageref: Used to identify the entry UID of the current page  
data-contenttype: Used to identify the content type UID of the entry  
data-locale: Used to identify the local of the entry for the current page

Since you might need to configure these three parameters for each page (if there are more than one page in your website), consider creating a helper function and call it on every page.

export const setDataForChromeExtension = (data: { entryUid: string, contenttype: string, locale: string }) => {  
    document.body.setAttribute('data-pageref', data.entryUid)  
    document.body.setAttribute('data-contenttype', data.contenttype)  
    document.body.setAttribute('data-locale', data.locale)  
}

Alternatively you can add these attributes to div tag tag of your component in the website

![ImplementingLivePreview\_L8\_img-2.png](https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt6eeb151ea083de4c/67e1cbf8848c63859acfd7b1/ImplementingLivePreview_L8_img-2.png)

After setting this up you will be able to see a button on your webpage which on clicking redirects you to the corresponding entry in Contentstack.

#### Key takeaways

- Connect **Chrome Extension** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 09 — Comprehensive guide to setting up CSR and SSR for Live Preview

<!-- ai_metadata: {"lesson_id":"09","type":"text","duration_minutes":1,"topics":["Comprehensive","guide","setting","CSR","and","SSR"]} -->

#### Lesson text

### **Installing a training instance**

The video below offers a step-by-step visual walkthrough of the process for setting up a training instance in Contentstack. It covers everything from signing up for a training instance to accepting your stack invitation and configuring your account. By the end of this guide, you’ll have your own training instance linked to your organization and stack. This environment will be available to you for 30 days, allowing you to explore and practice using Contentstack’s features. Whether you’re new to Contentstack or looking to enhance your skills, this training instance will give you hands-on experience in a real-world setup.

### **Setting up and Understanding Live Preview in CSR Mode**

The video below provides a detailed, step-by-step visual walkthrough of setting up your stack and code base to enable Live Preview in Client-Side Rendering (CSR) mode. Throughout this course, it will guide you from the basic implementation of Live Preview in your Contentstack stack to the necessary code modifications for enabling Live Preview in a CSR website built with Next.js 14, running locally. It will explain the specific changes required in the code, the reasoning behind them, and how they impact the Live Preview functionality. By the end of this walkthrough, you’ll see exactly how Live Preview will look and work once everything is set up.

### **Setting up and Understanding Live Preview in SSR Mode**

The video below provides a detailed, step-by-step visual walkthrough of setting up your stack and code base to enable Live Preview in Server-Side Rendering (SSR) mode. Throughout this course, it will guide you from the basic implementation of Live Preview in your Contentstack stack to the necessary code modifications for enabling Live Preview in a SSR website built with Next.js 14, running locally. It will explain the specific changes required in the code, the reasoning behind them, and how they impact the Live Preview functionality. By the end of this walkthrough, you’ll see exactly how Live Preview will look and work once everything is set up.

> Note: In the SSR video we used a sample SSR app made in NextJS14 with Live Preview 2.0. This might differ from the one present in Sample Starter Apps.
> 
> Sample Env For SSR:
> 
> #create environment file name as .env.local
> 
> #and place following configuration data.
> 
> 
> CONTENTSTACK\_API\_KEY=YOUR\_API\_KEY
> 
> CONTENTSTACK\_DELIVERY\_TOKEN=YOUR\_DELIVERY\_TOKEN
> 
> CONTENTSTACK\_ENVIRONMENT=YOUR\_PUBLISHING\_ENVIRONMENT
> 
> 
> # For live preview
> 
> CONTENTSTACK\_PREVIEW\_TOKEN=
> 
> CONTENTSTACK\_APP\_HOST=app.contentstack.com
> 
> CONTENTSTACK\_API\_HOST=cdn.contentstack.io
> 
> CONTENTSTACK\_PREVIEW\_HOST=rest-preview.contentstack.com
> 
> CONTENTSTACK\_LIVE\_PREVIEW=true
> 
> CONTENTSTACK\_LIVE\_EDIT\_TAGS=true
> 
> 
> #site-map
> 
> NEXT\_PUBLIC\_HOSTED\_URL=http://localhost:3000
> 
> # Requires host url for sitemap. Localhost:3000 is set as default value
> 
> 
> # For Live preview default value is to true to disable live preview set CONTENTSTACK\_LIVE\_PREVIEW=false
> 
> # For live edit tags default value is set to false to enable live edit tag set CONTENTSTACK\_LIVE\_EDIT\_TAGS=true
> 
> # For NA region add CONTENTSTACK\_APP\_HOST=app.contentstack.com
> 
> # For EU region add CONTENTSTACK\_APP\_HOST=eu-app.contentstack.com
> 
> 
> # For setting custom host add CONTENTSTACK\_API\_HOST=for(NA: cdn.contentstack.io, EU: eu-cdn.contentstack.com)

#### Key takeaways

- Connect **Comprehensive guide to setting up CSR and SSR for Live Preview** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 10 — Limitations of Live Preview

<!-- ai_metadata: {"lesson_id":"10","type":"text","duration_minutes":3,"topics":["Limitations","Live","Preview"]} -->

#### Lesson text

### **Limitations of Live Preview**

  

*   Incompatibility with websites using third-party website builders or CMS for HTML generation.
*   Previewing an individual component is only possible when it is referenced in a page entry.
*   Lack of compatibility with native mobile applications.
*   Restrictions on previewing content based on user role permissions for accessing entries, specific environments, and languages.
*   Requirement for websites to be Iframe-compatible to prevent CORS (Cross-Origin Resource Sharing) errors during preview.

#### Key takeaways

- Connect **Limitations of Live Preview** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

### Lesson 11 — Additional Resources and References

<!-- ai_metadata: {"lesson_id":"11","type":"text","duration_minutes":3,"topics":["Additional","Resources","and","References"]} -->

#### Lesson text

### **Additional Resources**  

*   Read the Contentstack Docs about [Live Preview](https://www.contentstack.com/docs/developers/set-up-live-preview)
*   Live Preview [FAQs](https://www.contentstack.com/docs/faqs#live-preview-faqs)
*   [Starter Apps](https://www.contentstack.com/docs/developers/sample-apps) which includes Live Preview implementation
*   Live Preview [Blog](https://www.contentstack.com/blog/product-updates/live-preview-paves-the-way-for-the-future)
*   Academy Playground [Github Repo](https://github.com/contentstack/contentstack-academy-playground)

#### Key takeaways

- Connect **Additional Resources and References** back to your stack configuration before moving to the next module.
- Capture one concrete artifact (screenshot, Postman call, or code snippet) that proves the step works in your environment.
- Re-read the delivery versus management boundary for anything you changed in the entry model.

## Resources & references

| Page | Companion Markdown |
| --- | --- |
| /courses/implementing-live-preview/how-to-complete-the-live-preview-course | /academy/md/courses/implementing-live-preview/how-to-complete-the-live-preview-course.md |
| /courses/implementing-live-preview/introduction-to-live-preview | /academy/md/courses/implementing-live-preview/introduction-to-live-preview.md |
| /courses/implementing-live-preview/untitled | /academy/md/courses/implementing-live-preview/untitled.md |
| /courses/implementing-live-preview/how-live-preview-works | /academy/md/courses/implementing-live-preview/how-live-preview-works.md |
| /courses/implementing-live-preview/live-preview-rest-delivery-sdk | /academy/md/courses/implementing-live-preview/live-preview-rest-delivery-sdk.md |
| /courses/implementing-live-preview/live-preview-graphql-api | /academy/md/courses/implementing-live-preview/live-preview-graphql-api.md |
| /courses/implementing-live-preview/live-edit-tags | /academy/md/courses/implementing-live-preview/live-edit-tags.md |
| /courses/implementing-live-preview/chrome-extension | /academy/md/courses/implementing-live-preview/chrome-extension.md |
| /courses/implementing-live-preview/comprehensive-guide-to-setting-up-csr-and-ssr-for-live-preview | /academy/md/courses/implementing-live-preview/comprehensive-guide-to-setting-up-csr-and-ssr-for-live-preview.md |
| /courses/implementing-live-preview/limitations-of-live-preview | /academy/md/courses/implementing-live-preview/limitations-of-live-preview.md |
| /courses/implementing-live-preview/additional-resources-references | /academy/md/courses/implementing-live-preview/additional-resources-references.md |

## Supplement for indexing

### Content summary

Hey there! Welcome to our course on the Live Preview feature in Contentstack! Get ready to explore a powerful tool that brings real-time content editing to your fingertips. In this course, we'll dive into the Live Previe… Hey there! Welcome to our course on the Live Preview feature in Contentstack! Get ready to explore a powerful tool that brings real-time content editing to your fingertips. In this course, we'll dive into the Live Preview feature within Contentstack. Live Preview allows you to see your content updates instantly as you make them, providing a seamless and dynamic editing experience. Whether you're tweaking text, adjusting images, or making layout changes, Live Preview lets you view your content exactly as it will appear to your audience, eliminating the guesswork and streamlining your content cr

### Retrieval tags

- Contentstack Academy
- implementing-live-preview
- How
- Complete
- the
- Live
- Preview
- Course
- Introduction
- Basic
- implementation
- works
- REST
- Delivery

### Indexing notes

Chunk at each "### Lesson NN — Title" heading; copy lesson_id and topics from the preceding HTML comment into chunk metadata for RAG filters.
Course slug: implementing-live-preview. Union of lesson topic tokens: How, Complete, the, Live, Preview, Course, Introduction, Basic, implementation, works, preview, REST, Delivery, SDK, GraphQL, API, Edit, Tags, Chrome, Extension, Comprehensive, guide, setting, CSR, and, SSR, Limitations, Additional, Resources, References.
Do not embed or retrieve LMS-only quiz items or mastery exam answer keys from this export.

### Asset references

| Label | URL |
| --- | --- |
| ImplementingLivePreview\_L3\_img-1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt83eed7e9d24e0d53/67e1ad0029f30c277bf8de60/ImplementingLivePreview_L3_img-1.png` |
| ImplementingLivePreview\_L3\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltd7f06a9a55b96fc3/67e1ad4db9f9a66e76dc40cf/ImplementingLivePreview_L3_img-2.png` |
| ImplementingLivePreview\_L3\_img-3.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt17620102d7b0b49e/67e1adc3c0d1f26cc60a3d03/ImplementingLivePreview_L3_img-3.png` |
| ImplementingLivePreview\_L3\_img-4.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltb0567501a748508b/67e1add8b9f9a60a39dc4132/ImplementingLivePreview_L3_img-4.png` |
| ImplementingLivePreview\_L4\_img-1.avif | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt42d7003887817022/67e1b16e914c2442924972c1/ImplementingLivePreview_L4_img-1.avif` |
| ImplementingLivePreview\_L4\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt79f0d34846849b01/67e1b6f367538e1ec22bd731/ImplementingLivePreview_L4_img-2.png` |
| ImplementingLivePreview\_L4\_img-3.avif | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc9d5f1526d39df0/67e1b791a352df6071697026/ImplementingLivePreview_L4_img-3.avif` |
| ImplementingLivePreview\_L4\_img-4.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltdc4fe0eae7f658a1/67e1b7c72fdf5e5ad0069dde/ImplementingLivePreview_L4_img-4.png` |
| ImplementingLivePreview\_L5\_img-1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt48250a2b71332476/67e1b9f2362ee30f7f55cbbd/ImplementingLivePreview_L5_img-1.png` |
| ImplementingLivePreview\_L5\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltc506e7b1bff7d46b/67e1bcb4d148edb993a3ff67/ImplementingLivePreview_L5_img-2.png` |
| ImplementingLivePreview\_L5\_img-3.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltaac121a05a27022e/67e1be35a352dfb810697091/ImplementingLivePreview_L5_img-3.png` |
| ImplementingLivePreview\_L5\_img-4.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt13ddff7eabd3ae7d/67e1bee194fe2fa63fdc79e8/ImplementingLivePreview_L5_img-4.png` |
| ImplementingLivePreview\_L5\_img-5.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blte9860aefeb60f424/67e1bf09a388fcb626812206/ImplementingLivePreview_L5_img-5.png` |
| ImplementingLivePreview\_L6\_img-1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltf9619548fdec8940/67e1bfd1b9f9a67f51dc4277/ImplementingLivePreview_L6_img-1.png` |
| ImplementingLivePreview\_L6\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltbc3ec508d7dc3b96/67e1c07b67538edd892bd7f1/ImplementingLivePreview_L6_img-2.png` |
| ImplementingLivePreview\_L7\_img-1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt9561e0d5f6257c5e/67e1c8296678fd4011aeaa06/ImplementingLivePreview_L7_img-1.png` |
| ImplementingLivePreview\_L7\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltb3ff4792d476ebc4/67e1c88d0b0fc52dadb4b1d4/ImplementingLivePreview_L7_img-2.png` |
| ImplementingLivePreview\_L7\_img-3.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc04529a9ee43a32/67e1c8ade6ff22567b0d1756/ImplementingLivePreview_L7_img-3.png` |
| ImplementingLivePreview\_L8\_img-1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt7e91b21db8560d2a/67e1cb4c29f30c8409f8e1c0/ImplementingLivePreview_L8_img-1.png` |
| ImplementingLivePreview\_L8\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt6eeb151ea083de4c/67e1cbf8848c63859acfd7b1/ImplementingLivePreview_L8_img-2.png` |

### External links

| Label | URL |
| --- | --- |
| Contentstack Academy home | `https://www.contentstack.com/academy/` |
| Training instance setup | `https://www.contentstack.com/academy/training-instance` |
| Academy playground (GitHub) | `https://github.com/contentstack/contentstack-academy-playground` |
| Contentstack documentation | `https://www.contentstack.com/docs/` |
| here | `https://www.contentstack.com/academy-old/` |
| Starter App via the CLI | `https://www.contentstack.com/docs/developers/cli/bootstrap-starter-apps` |
| Marketplace | `https://app.contentstack.com/#!/marketplace/starters` |
| Environment | `https://www.contentstack.com/docs/developers/set-up-environments/about-environments` |
| ImplementingLivePreview\_L3\_img-1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt83eed7e9d24e0d53/67e1ad0029f30c277bf8de60/ImplementingLivePreview_L3_img-1.png` |
| ImplementingLivePreview\_L3\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltd7f06a9a55b96fc3/67e1ad4db9f9a66e76dc40cf/ImplementingLivePreview_L3_img-2.png` |
| tokens | `https://www.contentstack.com/docs/developers/create-tokens/types-of-tokens` |
| Delivery Token | `https://www.contentstack.com/docs/developers/create-tokens/about-delivery-tokens` |
| ImplementingLivePreview\_L3\_img-3.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt17620102d7b0b49e/67e1adc3c0d1f26cc60a3d03/ImplementingLivePreview_L3_img-3.png` |
| Preview Token | `https://www.contentstack.com/docs/developers/create-tokens/about-delivery-tokens#about-preview-tokens` |
| ImplementingLivePreview\_L3\_img-4.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltb0567501a748508b/67e1add8b9f9a60a39dc4132/ImplementingLivePreview_L3_img-4.png` |
| SDKs and APIs | `https://www.contentstack.com/docs/developers/set-up-live-preview/how-live-preview-works-with-sdk` |
| ImplementingLivePreview\_L4\_img-1.avif | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt42d7003887817022/67e1b16e914c2442924972c1/ImplementingLivePreview_L4_img-1.avif` |
| ImplementingLivePreview\_L4\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt79f0d34846849b01/67e1b6f367538e1ec22bd731/ImplementingLivePreview_L4_img-2.png` |
| ImplementingLivePreview\_L4\_img-3.avif | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltfc9d5f1526d39df0/67e1b791a352df6071697026/ImplementingLivePreview_L4_img-3.avif` |
| ImplementingLivePreview\_L4\_img-4.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltdc4fe0eae7f658a1/67e1b7c72fdf5e5ad0069dde/ImplementingLivePreview_L4_img-4.png` |
| delivery SDK | `https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/about-javascript-delivery-sdk` |
| Live preview utils SDK | `https://www.contentstack.com/docs/developers/sdks/utils-sdk/javascript/about-javascript-live-preview-utils-sdk` |
| ImplementingLivePreview\_L5\_img-1.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/blt48250a2b71332476/67e1b9f2362ee30f7f55cbbd/ImplementingLivePreview_L5_img-1.png` |
| ImplementingLivePreview\_L5\_img-2.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltc506e7b1bff7d46b/67e1bcb4d148edb993a3ff67/ImplementingLivePreview_L5_img-2.png` |
| ImplementingLivePreview\_L5\_img-3.png | `https://images.contentstack.io/v3/assets/bltebc53cfaf0dd6403/bltaac121a05a27022e/67e1be35a352dfb810697091/ImplementingLivePreview_L5_img-3.png` |
