Skip to main content

Setting Up Post and Page Previews

Faust supports page and post previews, allowing you to view your WordPress content on the headless frontend as drafts or even before publishing.

Set Your Headless Secret

Your headless secret is a value that authenticates requests to WordPress. This secret enables you to view content that doesn't publish on your Next.js frontend.

Copy your Headless Secret

Find your Headless Secret in WP-Admin -> Settings -> Faust. Copy this value:

The Faust plugin admin interface with a red rectangle around the Secret Key field

Add Your Headless Secret to Your .env.local File

Add the FAUSTWP_SECRET_KEY key to your .env.local file with the headless secret as the value. Your .env.local file should already have a value for NEXT_PUBLIC_WORDPRESS_URL. The file should look something like this:

.env.local
# Your WordPress site URL
NEXT_PUBLIC_WORDPRESS_URL=http://localhost:8080

# Plugin secret found in WordPress Settings->Faust
FAUSTWP_SECRET_KEY=xxxx

Create Your faust.config.js File and Import It In _app.js

Like the next/getting-started Faust example, your faust.config.js file.

You'll need to import it at the top of your _app.js file to ensure the config is set, and your Faust app initializes appropriately.

pages/_app.js
import '../faust.config';
import React from 'react';
import { useRouter } from 'next/router';
import { FaustProvider } from '@faustwp/core';
import '../styles/global.scss';

export default function MyApp({ Component, pageProps }) {
const router = useRouter();

return (
<FaustProvider pageProps={pageProps}>
<Component {...pageProps} key={router.asPath} />
</FaustProvider>
);
}

Create the Faust API Router

Next, you will need to create the apiRouter. This sets up the Faust API endpoints needed to authenticate requests from WordPress. Create a page at pages/api/faust/[[...route]].js with the following:

import '../../../faust.config';
import { apiRouter } from '@faustwp/core';

export default apiRouter;

Create Your Preview Page

With your headless secret set and the authorizeHandler ready to handle requests, you can now create a Next.js page for previews. Create a file at pages/preview.js with the following:

pages/preview.js
import { WordPressTemplate } from '@faustwp/core';

export default function Preview(props) {
return <WordPressTemplate {...props} />;
}

Let's break down what is going on here:

We are using the WordPressTemplate component from @faustwp/core that will determine the correct page or post type to render based on the wp-templates hierarchy exports.

NOTE: We don't use the getWordPressProps here as opposed in some other wp-template pages as we want to perform post previews in the client using CSRs.

Now in the wp-template pages, Faust will propagate a special boolean property asPreview=true so your component needs to pass it on the Page query and variables.

Here is an example taken from the next/getting-started Faust example of what you should do in your template hierarchy components if you wish to render previews:

wp-templates/single.js
export default function Component(props) {
// Loading state for previews
if (props.loading) {
return <>Loading...</>;
}
// Code to render Single Post template hierachy type
}
Component.query = gql`
query GetPost(
$databaseId: ID!,
$asPreview: Boolean = false
) {
post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {
...
}
`;
Component.variables = ({ databaseId }, ctx) => {
return {
databaseId,
asPreview: ctx?.asPreview,
};
};

The variables property function accepts a context parameter ctx that includes the boolean value asPreview. This will be true when you are previewing a page and false otherwise. We can leverage this parameter by inserting it in the query for requesting post or page previews.

We also need to consider the case when the component is still loading due to the CSR request. In such case, we can render an empty or loading component when the post preview data is still in-flight:

if (props.loading) {
return <>Loading...</>;
}

If you don't handle the loading state you may find that the post/page data will be undefined.

Is the asPreview Property Necessary?

If you wish to disable post/page previews for a particular template hierarchy page you can simply ignore the asPreview parameter.

Start by logging into your WordPress Admin. For this example, we'll create a new post.

So far, I've added a title and a simple line of text for the content. To view this post as a preview on your front end, click the Preview link (1). From there, click, Preview in new tab (2):

WordPress post page using the Gutenberg editor with a red arrow to the preview and preview in new tab dropdowns

Notice the Publish button is also visible, meaning that you still need to publish the post. Therefore you can now view the post on the frontend without being authenticated.

Clicking on Preview in new tab should take you to your post preview page with the current preview content:

Post preview on the frontend in Next.js