---
title: "Add a Visual CMS with Live Previews to Next.js Sites"
description: "In this tutorial, learn how to add a visual CMS to your Next.js site, with live previews for content editing, with Magnolia DXP and Netlify."
source: "https://www.netlify.com/blog/visual-cms-nextjs-preview-mode/"
last_updated: "2026-07-11T05:28:12.000Z"
---
Serving static documents has all sorts of benefits for sites and project workflows (see [Why Jamstack?](https://jamstack.org/why-jamstack/)). But editing static sites isn’t fun without a visual editor, especially for content authors who have gotten accustomed to the WYSIWYG experience of traditional content management systems (CMSs). Running a full build of a static site only to see what a minor change looks like just isn’t good enough.

Developers have found an answer to this problem by improving their experience with static site generation (SSG) approaches, using, for example, Next.js’ Preview Mode. But what about the marketers?

A flexible visual editing experience that, for example, allows marketers to place components, control column layouts, and add content, gives them more control over the design of the experience.

In this blog post, I will look at how we can enable marketers to visually edit and preview static pages by connecting the [Magnolia Digital Experience Platform (DXP)](https://www.magnolia-cms.com/) to a Next.js app built with Netlify.

## Building Blocks

Let’s look at a tech stack that allows you to create and serve static sites while enabling authors to edit content visually.

### Framework: Next.js

This application is built with Next.js, a leading React framework. The framework allows us to take full advantage of static site generation and offers preview mode. Preview mode can bypass SSG and server-side render a draft page via any data fetching solution. This means we won’t have to run a full build to see a preview of the page. This is ideal if you’re using a content management system (CMS) for your web apps and your team wants to check what their content might look like before committing a change.

### Next.js Hosting and Deployment: Netlify

We’ll build and host the site with Netlify. Netlify [enhances the power of Next.js](https://www.netlify.com/blog/next.js-on-netlify-features/) by offering us additional developer experience benefits, as well as tools for release management. It also offers excellent Next.js support, including [full support for Next.js Preview Mode](https://www.netlify.com/blog/2020/10/27/preview-mode-for-next.js-now-fully-supported-on-netlify/), which will be important in this tutorial.

### Digital Experience Management: Magnolia DXP

Magnolia serves as the content hub and digital experience platform (DXP). Its [Visual SPA Editor](https://www.magnolia-cms.com/platform/solutions/visual-spa-editing.html) connects the modern SPA architecture with the concept of a traditional page editor, allowing content authors to create experiences in a WYSIWYG fashion.

Magnolia can also [integrate data and content](https://www.magnolia-cms.com/platform/solutions/integrations/connectors.html) from Digital Asset Management (DAM) systems, eCommerce platforms, or any other 3rd-party systems, offering non-technical users one central hub to manage digital experiences.

## Next.js

My [Next.js code for this app](https://github.com/bartoszstaryga/nextjs-magnolia-netlify) offers a 2-in-1 solution, and you can find it on GitHub.

### Static Site Generation

Next.js can export your Next.js application as static HTML files that can be run without a Node.js server.

I used both `getStaticProps` and `getStaticPaths` to generate the static site. Here are the links to where they live in the repo, and what each function does:

-   [`getStaticProps`](https://github.com/bartoszstaryga/nextjs-magnolia-netlify/blob/main/pages/%5B%5B...pathname%5D%5D.js#L65) - fetch page content from the headless CMS
-   [`getStaticPaths`](https://github.com/bartoszstaryga/nextjs-magnolia-netlify/blob/main/pages/%5B%5B...pathname%5D%5D.js#L51) - return page sitemap, telling Next.js which pages to build

### Preview Mode

To understand how Next.js Preview Mode works, I recommend you take a look at the following scripts:

-   `/pages/api/preview.js`
-   `/pages/[[...pathname]].js`

The first file creates an API route in our Next.js project that allows us to bypass static site generation:

```
export default function handler(req, res) { res.setPreviewData({   query: req.query, }); res.redirect(req.query.slug);}
```

Calling `setPreviewData` on the response object sets a preview cookie. Next.js will consider all requests containing this particular cookie as preview requests.

The argument we pass to `setPreviewData` should be an object. We can use `getStaticProps` to retrieve its content later.

If the preview cookie is set, the API redirects the request to the page defined by the query parameter `slug`.

The workflow looks like this:

1.  Open `/api?slug=/my-page`
2.  Set the cookie
3.  Redirect to `/my-page`

The next step is updating `getStaticProps` to support preview mode.

When the preview cookie is set, the supplied context object has these special properties:

-   `context.preview` is `true`
-   `context.previewData` equals the argument previously passed to `setPreviewData`

We can now modify the function to fetch the content of the page that we passed as `previewData`. In this example, we define which page should be rendered: the dynamically generated page or the static page returned by the `getStaticPaths` function.

```
export async function getStaticProps(context) { const resolvedUrl = context.preview   ? context.previewData.query.slug   : context.params.pathname     ? '/' + context.params.pathname.join('/')     : '';

 // ...

 // Find out page path in Magnolia let pagePath = context.preview   ? nodeName + resolvedUrl.replace(new RegExp('.*' + nodeName), '')   : nodeName + resolvedUrl;

 // ...

 // Fetching page content const pagesRes = await fetch(setURLSearchParams(pagesApi + pagePath, 'lang=' + currentLanguage));

 // ...}
```

## Setting Up Netlify

We have to set up two Netlify sites:

1.  To generate site previews for content authors
2.  To generate and serve the static site to the end user

### Next.js Preview Mode Instance on Netlify

For the Next.js Preview Mode instance, we follow the documentation of [How to Deploy Next.js Sites to Netlify](https://www.netlify.com/blog/2020/11/30/how-to-deploy-next.js-sites-to-netlify/). The [Next.js on Netlify Plugin](https://docs.netlify.com/integrations/frameworks/next-js/#essential-next-js-build-plugin) performs the required steps for us. Since Netlify will auto-detect if you’re building a Next.js app, it can install the plugin for you automatically.

We then only have to point the new site to our Git repository and let Netlify handle the rest.

![Point Magnolia Git Repo to Netlify](https://cdn.sanity.io/images/o0o2tn5x/production/5fe330ab73debca0033572134263993f1693d195-1860x1572.png?)

### Static Site Generation and Hosting

We point this site to the same Git repository.

To export the page as static HTML files, the build runs `npm run build && npm run export` and uses the publish directory `out`.

![Point Magnolia DXP GitHub Repo to Netlify](https://cdn.sanity.io/images/o0o2tn5x/production/4cc40eb7463838e78fb0d0a2229297879369a911-1856x1574.png?)

Next, we need to set two environment variables:

-   `NETLIFY_NEXT_PLUGIN_SKIP` - skip the Next on Netlify Plugin setup for static site hosting
-   `NEXT_PUBLIC_MGNL_HOST` - Magnolia public instance URL to fetch published content

![Setting Environment Variables for Nexjs Magnolia App](https://cdn.sanity.io/images/o0o2tn5x/production/9eb7ecd44c02008bdbbcacc0d4b20fe790fb7bad-1848x704.png)

Lastly, we create the build hook to trigger static site generation when an editor publishes new content in Magnolia.

![Create Build Hooks to trigger SSG](https://cdn.sanity.io/images/o0o2tn5x/production/e9d755b642eeda9f330adb497e7992d59f3a25a9-1860x672.png?)

## Magnolia

We need two Magnolia instances:

-   An author instance for content authors to manage their content
-   A public instance to serve published content

![magnolia Netlify Architecture Diagram](https://cdn.sanity.io/images/o0o2tn5x/production/161a5edc8008e950243bb151af2888d12fe19cf6-1200x666.jpg)

To use the Next.js Preview Mode instance, we have to set two properties in [Magnolia’s page template definition](https://docs.magnolia-cms.com/product-docs/6.2/Developing/Templating/Template-definition/Page-definition.html): `baseUrl` and `routeTemplate`.

```
title: 'Next.js SSG: Basic'baseUrl: https://nextjs-magnolia-netlify-preview.netlify.approuteTemplate: '/api/preview?slug=/{language}{{@path}}'
```

You can find these templates in [GitHub](https://github.com/bartoszstaryga/nextjs-magnolia-netlify/tree/main/magnolia).

Next, we set up [Magnolia’s Netlify extension](https://marketplace.magnolia-cms.com/detail/netlify.html) that enables content authors to trigger the generation of the static site in Netlify when they publish new content.

We have to add the Netlify API key to the YAML configuration file `/decorations/netlify-integration/config/config.yaml`.

```
apiToken: your_netlify_api_token;
```

Voila! We are now able to edit pages in Magnolia’s WYSIWYG editor and trigger a new Netlify build when new content is published.

![Magnolia CMS Live Preview of Nextjs Site](https://cdn.sanity.io/images/o0o2tn5x/production/79f46006ec141405b079755c1253a857520fefa1-1999x1221.png)

![Publish Content to Magnolia and Deploy on Netlify](https://cdn.sanity.io/images/o0o2tn5x/production/a361f2c58e2adae659ef8a5776ecce75ef611aef-1480x1060.png)

## ❤️ the Visual Authoring Experience for Headless

Despite the growing adoption of the headless approach, we must not forget about our colleagues, the content authors. It is high time to bring them back into the equation and make sure that their experience is just as smooth as the developer experience.

If you like this solution, feel free to check out the example in our [repository](https://github.com/bartoszstaryga/nextjs-magnolia-netlify).

### Share

-   [X (fka Twitter)](https://twitter.com/intent/tweet?text=Bringing Dynamic WYSIWYG Editing to Static Next.js Sites&url=https://www.netlify.com/blog/visual-cms-nextjs-preview-mode/)
-   [LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.netlify.com%2Fblog%2Fvisual-cms-nextjs-preview-mode%2F)
-   [Facebook](https://www.facebook.com/sharer.php?u=https://www.netlify.com/blog/visual-cms-nextjs-preview-mode/)
-   [Bluesky](https://bsky.app/intent/compose?text=Bringing Dynamic WYSIWYG Editing to Static Next.js Sites+https://www.netlify.com/blog/visual-cms-nextjs-preview-mode/)

* * *

### Tags

-   [Next.js](/blog/tags/next.js/)
-   [DXP](/blog/tags/dxp/)
-   [Magnolia](/blog/tags/magnolia/)
-   [CMS](/blog/tags/cms/)
-   [headless cms](/blog/tags/headless-cms/)

## Keep reading

![](/images/blog-fallback-thumbnail.svg)

Guides & Tutorials March 16, 2022

[

### Next.js on Netlify: a Powerful Combination

](/blog/next.js-on-netlify-features)

-   ![Profile picture of Charlotte Dillon](/_astro/ba092e80ad4e8fc41b238c66c3f472b477d1c53b-80x80_ZnCI2I.webp)
    
    Charlotte Dillon
    

![](/_astro/3f45eb6eda4ea8814be310e3df4a7883a5bd9ba0-1200x675_ZcBDUS.webp)

Guides & Tutorials May 15, 2026

[

### How to build a real-time AI chatbot in minutes with Netlify Agent Runners (no backend)

](/blog/how-to-build-a-real-time-ai-chatbot-in-minutes-with-netlify-agent-runners-no-backend)

-   ![Profile picture of Nahrin Jalal](/_astro/f0e7c8f227a03fe58340c99ef5439d5a896c0733-272x272_Z23kDpD.webp)
    
    Nahrin Jalal
    

## Recent posts

News & Announcements June 25, 2026

[

### Netlify Functions, designed for Agent Experience

](/blog/netlify-functions-designed-for-agent-experience)

-   ![Profile picture of Eduardo Bouças](/_astro/52958f21e8450baf6d8e60302341a984e220c0cd-512x512_13VDlu.webp)
    
    Eduardo Bouças
    

News & Announcements June 24, 2026

[

### How we measure Netlify’s Agent Experience

](/blog/how-we-measure-netlify-agent-experience)

-   ![Profile picture of Sean Roberts](/_astro/bbf2243f8171dbddd80ab2103622106cef84d125-512x512_Z1d2LKE.webp)
    
    Sean Roberts
    

Guides & Tutorials May 15, 2026

[

### How to build a real-time AI chatbot in minutes with Netlify Agent Runners (no backend)

](/blog/how-to-build-a-real-time-ai-chatbot-in-minutes-with-netlify-agent-runners-no-backend)

-   ![Profile picture of Nahrin Jalal](/_astro/f0e7c8f227a03fe58340c99ef5439d5a896c0733-272x272_Z23kDpD.webp)
    
    Nahrin Jalal
    

![](/_astro/3f255b372fa958df35802666ee33b4609b2d71bd-1200x1586_1VtE2D.webp)

### How do the best dev and marketing teams work together?

[Access the report](https://www.netlify.com/reports/2024-leadership-trend-report/access/)