09.29.2021

New Ticket: Astro Draft mode

The no-fluff answer to putting together preview mode for our one of our favorite web frameworks. Decrease technical dependency for non-technical content management teams. Read on to discover how we did it.

Two Adapt USA employees working with Contentful logo

Blocker: No Content Preview

At Adapt, we specialize in building sites that integrate with headless CMS platforms (we prefer Contentful), and one of the main issues we see with a headless CMS is the lack of a built-in content preview feature.

Why you need a content preview feature.

If you want to preview content in Contentful, you have to build it yourself.

To address this, we frequently implement NextJS's draft mode, which provides a simple and cost-effective way to preview content. Draft mode works by rendering a server-side version of the site that pulls content from Contentful’s preview API with each refresh - offering a reliable preview solution for content editors.

We love Astro, but up to this point the lack of a built in "Draft Mode" has deterred a couple of clients. Being able to preview content is a requirement for editors, and we didn't have a solution out of the box.

Until now.

To Do: Set up Astro Draft mode

As mentioned, NextJS's draft mode essentially involves server-rendering content. Coupled with Contentful's preview API, which is not cached and serves up published, changed, and draft content, we essentially have a preview site that can be up to date with every refresh.

That seems simple enough. Astro has options to server-render content and prebuilt SSR integrations for Vercel and Netlify, our hosts of choice. So we figured, let's get this done so it's not a blocker for future clients. Initial configurations for setting this up in Astro begin in the ‘astro.config.mjs’ file:

Code successfully copied to your clipboard!

Note: Astro deprecated the dynamic `prerender` export in v4.14, in favor of using the `astro:route:setup` hook that we're showing above. For example code that supports Astro 4.13 and below, see this gist.


This method takes advantage of Astro's new `astro:route:setup` hook, marking all routes as server rendered if we're in a preview environment, which can be configured using the `PREVIEW` environment variable.

Based on the rendering mode, we also have to specify the server config. When not in a preview, we use Astro's defaults, rendering all content via static generation. Where it gets interesting is when we are in preview mode. At this point, we need to specify an adapter.

An adapter in Astro is a special kind of integration that provides an entrypoint for server-side rendering based on the platform where the site is running. So, if the site is building on Netlify, we have to use the Netlify adapter. When we're running locally, we use the Node adapter. This gives us the opportunity to build and run the site on SSR locally in case we have a need to test the method, although it may be overkill as generally we will be running in dev mode on our local machines.

One useful note here, the ‘process.env.NETLIFY’ environment variable is available to us out of the box from Netlify. It requires no setup in our project’s ‘.env’ file, or in the site configuration settings in our Netlify dashboard.

In Progress

Let’s say we have a content type in Contentful called ‘Page’. It has a field on it called ‘Slug’, among other fields, and for each Page entry in Contentful we want to generate a unique page in our site that is based off of the slug. The dynamic page template for this kind of setup could look something like this:

Code successfully copied to your clipboard!

In the above file we can see many fundamental aspects of Astro in action: file-based page generation, relevant data retrieval scripts that run in the front matter section of the component, and Astro component composition for templating. 

The ‘getStaticPaths’ function in this component is worth further consideration. If we have enabled prerendering by leaving out the ‘PREVIEW’ environment variable, this function will be required as it is needed for static page generation. However, if we are in SSR mode, the ‘getStaticPaths’ function will simply be ignored, and the page will be built at request time.  

As currently constructed, we are requesting all page data when the page is being generated and are not passing any data except the slug from ‘getStaticPaths’.  This is flexible to either rendering mode, but could result in more queries than we want during a static build. In the future, we could reduce the number of queries made during static generation.  It would depend on build times and what we’re optimizing for, but as a proof of concept, we’re really happy to see that Astro can support multiple rendering modes in the same template.

Review/Testing: Final Steps

The last step in making this a true preview mode is to make sure that we query the correct API.  When defining the ‘getPageData’ function we determine which Contentful API should be queried: the delivery API or the preview API. By using the preview API, we can be sure that we’ll get draft, changed, and production data.  And because the preview API is uncached, we can be sure it will be the most recent content.

Let’s take a closer look:

Code successfully copied to your clipboard!

Done: Happy Content Editors

By coupling server-rendered Astro pages with the correct Contentful API, we can achieve the desired draft mode preview experience that content authors desire. 

For clients who emphasized to us the importance of a preview mode (like Ibotta), a solution like this could be the missing piece of the puzzle. Contentful empowers marketing teams like never before; allowing for freedom of experimentation without waiting for developers, and allowing for stakeholders to rest assured with concrete brand design guardrails imposed (Check out Contentful Studio). However, without a preview option, less technical teams can’t see the final product prior to publication, and firms with a high-profile presence must have this visual review process. 

Article by Jesse Day

Like this article? Read another by our devs.

Reach out to us.

Adapt Tech Director, Jesse

Hi, Adapt.

I'mfrom

I'm interested in enabling my content marketers.

You can reach me at

Looking forward to hearing from you!