One of the first challenges you’ll face when you try out Headless WordPress is the lack of preview support. You cannot retrieve unpublished content through an API without the user authenticating first. On a traditional WordPress site, this isn’t an issue because the frontend is on the same domain as the backend, so you can use a cookie for authorization. When you use a frontend hosted on a separate domain from WordPress, your WordPress cookies will not work. To see unpublished content, you will need to set up a way to make authenticated requests to the WordPress API. This can be tricky because you do not want to allow unauthenticated users to see your unpublished content, so you need to avoid hard coding authentication secrets into your frontend code. This post will help you show you a few tools you can use to get previews working in NextJS.
Setting Up WordPress For Headless
If you haven’t already, check out our post about setting up WordPress for headless. For this post you will need to install and configure the following plugins (outlined in the post linked above):
Make sure you follow the instructions in the post for configuring Faust.js. In the Faust.js settings (found in Settings > Headless), set
Front-end site URL to
http://localhost:3000/. This will eventually be the URL where our frontend site is served.
The next thing you will want to grab and store from the WPEngine Headless settings is the
Secret Key. Below is an example screenshot that shows the Front-end site URL and Secret Key:
Your Faust.js settings will look something like this. Make sure to note the Secret Key as you will need it later.
Building The Frontend Site With NextJS
Before building out your frontend site, you will need to make sure you have Node.js and NPM installed on your computer. If you are using a Mac, it is recommended that you install NVM, which will help you manage your Node versions.
Once you have Node and NPM installed on your machine, run the following commands:
npx create-next-app previews cd previews rm -r ./pages/* npm i @wpengine/headless @apollo/client graphql npm i typescript @types/react @types/react-dom @types/node -DCode language: PHP (php)
Now your site is set up, but you still need to enable authentication with WordPress and build out a home page.
To view previews in WordPress, you need to have higher access to your WordPress site. WordPress won’t show previews to you unless you are an authenticated user. You don’t notice this with a traditional WordPress site because the URL you preview posts typically shares the same domain and cookies as your WordPress admin panel. For headless WordPress, you have to find another way of authenticating and making requests for previews. This is where the WPEngine Headless plugin comes in handy.
The WPEngine Headless plugin exposes routes that allow for an OAuth flow to obtain an access token used for authenticated requests such as previews. The flow looks as follows:
- User requests a secure route (i.e., draft post).
- User redirects to WordPress to login.
- WordPress redirects back to the frontend with a temporary code.
- The frontend server exchanges the code for an access token.
- The access token stores in a cookie.
- The user finally redirects back to the original URL and uses the access token in the cookie to make the authenticated request.
Lucky for us, the @wpengine/headless plugin provides a Node authorization handler to facilitate exchanging the authorization code for an access token, storing the token in a cookie, and redirecting back to the appropriate frontend route.
To take advantage of the authorization handler in your NextJS app with
@wpengine/headless you can create a new NextJS API route in
/pages/api/auth/wpe-headless.ts with the following code:
authorizeHandler accepts a Node request (i.e.
IncomingMessage) and response (i.e.,
ServerResponse) and will work with any Node-based server library. This is all you need to get authentication working in your NextJS app. Now let’s get started building out the application.
Building Your Frontend NextJS Page For Previews
NextJS is a React-based framework, and
@wpengine/headless is written to work alongside NextJS and React.
The first thing you need to do in order to integrate with
@wpengine/headless is invoke the
HeadlessProvider in your
/pages/_app.tsx. Use the following code:
HeadlessProvider is the glue that allows the framework to communicate with WordPress. It needs to exist at the top level of your application wherever you want to hook into WordPress and take advantage of the GraphQL API.
Routes and Hooks
To support previews, you need two pages. One page handles all public routes (
/pages/[[…page]].tsx) and another will handle private preview routes (
[[…page]].tsx is how you describe a catch-all route in Next. Put the following code in
Ignore the errors you get about
<Posts /> and
<Post /> for now, we will create those components soon. A couple interesting things to note with this component:
getNextStaticPropsis used to enable Static Site Generation (SSG) with Next. It knows how to get the URL information on the server-side and make the necessary query for a list or single post. It will then cache the queries so the queries can be used client-side without making network requests. This is crucial for site performance and SEO.
useUriInfois a hook provided by
@wpengine/headless. It will get the current URL and query the WordPress GraphQL API to get information about the URL. If the route has a list of posts (i.e.
pageInfo.isPostsPagewe’ll show the
Postscomponent, otherwise we show the
Let’s create the
Post component. In
/lib/components/Post.tsx place the following code:
The component above is used to render an individual post. It takes advantage of the
usePost hook provided by
Next, let’s create the
Posts component. In
/lib/components/Posts.tsx put the following code:
The component above is used to render a list of posts. It uses the
usePosts hook provided by
@wpengine/headless to get the appropriate list of posts.
Running The Application
Now you should have a public page to display both a list of posts. Before you can run it, you will need to configure a
.env.local file with the appropriate environment variables needed by
@wpengine/headless. Create a file in the root of your project called
.env.local and configure it as follows:
# Base URL for WordPress NEXT_PUBLIC_WORDPRESS_URL=http://yourwpsite.com # Plugin secret found in WordPress Settings->Headless WP_HEADLESS_SECRET=YOUR_PLUGIN_SECRETCode language: PHP (php)
You will need to set the
NEXT_PUBLIC_WORDPRESS_URL to the root URL of your WordPress site. If you remember earlier in this post, you were asked to save your
Secret Key from your WordPress headless settings, that should go in your
.env.local as your
NOTE: It is important to only put
NEXT_PUBLIC_ in front of environment variables if you intend for them to be available to the client. You do not want
WP_HEADLESS_SECRET visible to the client, so it does not need the prefix.
Now that you have your
.env.local configured, run your site with the following command:
npm run dev
A Node server will start on port 3000 by default: http://localhost:3000.
Adding A Page For Previews
After verifying that your site works and you can see a list of posts and individual posts, the last step is to set up a page for previews. Create a file called
/pages/preview/[[…page]].tsx and put the following code in it:
The code for previews is a little bit cleaner than the public page, and for good reason. You only need to preview individual posts, so there is no need to do anything else. Also, note that the preview page does not use
getStaticPaths. This is intentional, as we only need to get previews client-side.
Now that you have this component in place, you can run your site and then test if previews work by going to your list of posts in
wp-admin and clicking to preview a draft post (you might have to create a draft post if you don’t have one already).
That’s all there is to it, you have successfully set up a headless WordPress site with a NextJS frontend, and you can preview unpublished posts!