Sitecore JSS SDK Deep Dive: Next.js Edit Mode
Sitecore CM has awesome editing capabilities. Sitecore developers did a great job supporting the same editing interface starting from XSLT, WebForms, and MVC and continuing it to a headless development approach with Next.js.
Next.js Preview Mode
Before starting the explanation, of how Edit Mode works with Next.js, we need to understand the other things that it relies on. The essential thing for us is Next.js Preview mode. If you are familiar with Next.js Preview Mode then scroll ahead to the Sitecore part. Also, I recommend you read the official documentation. I will describe parts that are essential for Sitecore. And please, do not mix up Sitecore Preview Mode and Next.js Preview Mode. Both, Sitecore Edit and Preview Modes will work with Next.js Preview Mode.
Next.js has two rendering modes Static Site Generation(SSG) and Server Side Rendering(SSR). We consider Incremental Static Regeneration(ISR) as a sub-type of SSG for simplification. Static Sitecore Generation is a very useful approach for sites based on headless CMS. You can generate your pages in advance and make them very fast. However, sometimes, you want to preview your page before publishing data. Next.js Preview Mode allows you to achieve it.
Next.js Preview mode requires changes in your implementation. It needs an additional endpoint that will be responsible for a preview. And we will need to change getStaticProps
to get data differently for the preview mode.
Preview Endpoint
Next.js preview mode requires an additional endpoint that will be responsible for “previewing” the site. It should accept:
- The path that we want to preview
- Secret to protect the site from accessing the preview endpoint by everyone
- Data that we want to preview (optional)
This preview endpoint should call Next.js API to enable preview mode res.setPreviewData({})
. It accepts three arguments:
maxAge
- the number in seconds for the preview session to last for.path
- the path that we want to previewdata
- additional data that we want to use during preview. Important, that it is stored in a cookie. And the size limit is only 2KB. We can’t pass too much.
This API will set specific cookies to make Next.js know that you are in the preview mode. Then you need either redirect your request to the actual page or read the cookies and use them in your requests.
getStaticProps
getStaticProps
Next.js API is used to get data for rendering the page. We can figure out if we are in preview mode using context.preview
and get the preview data using context.previewData
. Then, based on the current mode, we can get static props in different ways.
Sitecore Next.js Edit Mode
Here is a diagram of how the Next.js Edit Mode part works.
It only looks scary, but actually, it is quite simple and can be described in one paragraph.
There is a render.ts
API endpoint that accepts POST
requests with Layout Service and Dictionary data. This data is passed to Editing Render Middleware. As Sitecore Layout Service contains a lot of details about presentation and datasources, it can easily be bigger than 2KB. That is why, saving it using setPreviewData
is not an option. Sitecore uses sync-disk-cache
NPM package that can save temporary data on the disk with unique identifiers. It saves Layout Service(presentation and datasources) and Dictionary data on the disk and gets the unique identifier for this set of data. Then it enables Next.js Preview mode and passes this unique identifier. It makes requests to the page itself with preview mode cookies. [[...path.tsx]]
get request, understand that request in the Next.js Preview Mode. It reads presentation, datasources, and dictionary data from the cache saved on the disk and uses it to render the page. Then Editing Render Middleware post-processes the HTML and returns it to the Sitecore CM.
Architectural Considerations
Sitecore developers made a clever architecture by passing data to Next.js Preview Mode in this tricky way. But dependency on sync-disk-cache
, makes it hosting-dependent. It works with Node containers and with Vercel. But may cause problems with other hosting platforms. As for me, it would be better to save this state on the Sitecore CM side. It will make Sitecore Next.js Headless less dependent on hosting. It will make the adoption of frameworks other than Next.js much easier.