Guides & Tutorials

Bringing Dynamic WYSIWYG Editing to Static Next.js Sites

Guides & Tutorials

Bringing Dynamic WYSIWYG Editing to Static Next.js Sites

Serving static documents has all sorts of benefits for sites and project workflows (see 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) 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 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, 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 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 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 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:

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. The Next.js on Netlify 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

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

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

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

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

To use the Next.js Preview Mode instance, we have to set two properties in Magnolia’s page template definition: baseUrl and routeTemplate.

title: 'Next.js SSG: Basic'
baseUrl: https://nextjs-magnolia-netlify-preview.netlify.app
routeTemplate: '/api/preview?slug=/{language}'

You can find these templates in GitHub.

Next, we set up Magnolia’s Netlify extension 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

Publish Content to Magnolia and Deploy on Netlify

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

Keep reading

Recent posts

Book cover with the title Deliver web project 10 times faster with Jamstack enterprise

Deliver web projects 10× faster

Get the whitepaper