WP engine’s headless WordPress hosting platform is the go-to end-to-end solution for the headless approach. In this article, I will discuss and guide you through the easy implementation of the latest feature on the platform: Support for On-Demand ISR on Next.js/Faust.js. By the end of this article, you will have a better understanding of On-Demand ISR and using the headless WP platform to support it with Next.js/Faust.js.
Table of Contents
If you prefer the video format of this video, you can access it here:
Prerequisites
Before reading this article, you should have the following prerequisites checked off:
- Basic knowledge of Next.js and Faust.js.
- A WP engine headless WordPress account and environment set up.
- Node.js and npm are installed on your local machine.
If you do not and need a basic understanding of Next.js and Faust.js, please visit the docs:
https://faustjs.org/tutorial/get-started-with-faust
Headless
Platform
The all-in-one platform for
radically fast headless sites.
What is On-Demand ISR?
On-Demand Incremental Static Regeneration (ISR) is a feature that allows you to manually purge the Next.js cache for specific pages, enabling more dynamic and timely updates to your site. Typically, in regular ISR when you set a revalidate time, such as 60 seconds, all visitors will see the same generated version of your site for that duration. The cache is only invalidated when someone visits the page after the revalidation period has passed.
With the introduction of On-Demand ISR in Next.js version 12.2.0, you can now trigger cache invalidation manually, providing greater flexibility in updating your site. This is particularly useful when:
- Content from your headless CMS is created or updated.
- E-commerce metadata changes, such as price, description, category, or reviews, are made.
This feature streamlines the process of reflecting changes on your site in real-time, ensuring that your content is always fresh and up-to-date.
Why Use it in headless WordPress?
In headless WordPress, the front end is decoupled from the WordPress backend, often using Next.js and Faust.js to render the website. This architecture offers several advantages, such as potential for improved performance, enhanced security, and greater flexibility in choosing front-end technologies.
However, one challenge with headless WordPress is ensuring that content changes in WordPress are reflected on the front end without sacrificing performance. This is where On-Demand ISR becomes crucial. By leveraging On-Demand ISR, you can achieve the following benefits:
Up-to-date Content: On-Demand ISR allows your site to fetch the latest content updates from WordPress manually, as needed. Unlike regular ISR, which checks for updates at specified intervals, On-Demand ISR lets you trigger cache invalidation whenever content is created or updated in WordPress. This ensures that users see the most recent content without waiting for a revalidation period.
Enhanced Performance: Since On-Demand ISR updates only the specific pages that need regeneration at the moment they are triggered, your site remains fast and responsive. Initial load times are minimized, and only the changed content is updated, reducing server load and build times.
SEO Benefits: Static pages are highly favored by search engines due to their speed and reliability. With On-Demand ISR, you maintain the SEO advantages of static generation while ensuring that your content is always fresh and relevant, as updates are reflected immediately after they are triggered.
Scalability: On-Demand ISR enables your site to handle large volumes of content efficiently. Whether you’re running a blog with frequent updates or an e-commerce site with dynamic product listings, On-Demand ISR ensures that your site scales seamlessly.
All those benefits got me stoked! Let’s get it on our Next.js and Faust.js sites!
Configuring Next.js with the headless WP Platform for On-Demand ISR
Let’s configure our Next.js application to work with On-Demand ISR.
Here is the docs link to the headless WordPress platform support for On-Demand ISR.
Atlas-Next Package
In your Next.js project, go to your terminal and install the @wpengine/atlas-next package:
npm install --save @wpengine/atlas-next
This package provides improved support on the headless WP platform. Once you install it, ensure it is in your project by navigating to your package.json
file at the root of your project:
{
"name": "atlas-on-demand-isr",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@wpengine/atlas-next": "^1.3.0-beta.0",
"next": "14.2.4",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"eslint": "^8",
"eslint-config-next": "14.2.4",
"postcss": "^8",
"tailwindcss": "^3.4.1"
}
}
Code language: JSON / JSON with Comments (json)
Now that you have verified the proper installation, staying at the root of your project, modify your next.config.js
file like so:
const { withAtlasConfig } = require("@wpengine/atlas-next");
/** @type {import('next').NextConfig} */
const nextConfig = {
// Your existing Next.js config
};
module.exports = withAtlasConfig(nextConfig);
Code language: PHP (php)
Faust.js Wrapper and Next.js/React.js Versions
If you are using Faust.js, please note that you need to update your Next.js to a minimum of 13.5.1 and React versions to 18.3.1 for this feature to work in Faust. The npx
utility command that pulls down the Faust.js boilerplate from the Faust docs comes with Next.js 12 by default. So please change this if using that package.
Following the update to your versions, all you need to do is modify your next.config.js
file using the withFaust
wrapper:
const { withFaust } = require("@faustwp/core")
const { withAtlasConfig } = require("@wpengine/atlas-next")
/** @type {import('next').NextConfig} */
const nextConfig = {
// Your existing Next.js config
}
module.exports = withFaust(withAtlasConfig(nextConfig))
Code language: PHP (php)
Next, we need to verify that it works. Run your app in dev mode via npm run dev and you should see this output in your terminal:
Stoked! It works!
Create an API route
The first thing we need to do is create an API route. This will allow you to pass the path to be revalidated as a parameter.
Step 1. Create the API route file: Navigate to the pages/api
directory in your Next.js project and create a new file named revalidate.js
.
Step 2. Add the API Route code: Open revalidate.js
and add the following code:
export default async function handler(req, res) {
// Check for a secret token to authenticate the request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' });
}
const path = req.query.path;
// Ensure the path parameter is provided
if (!path) {
return res.status(400).json({ message: 'Path query parameter is required' });
}
try {
// Revalidate the specified path
await res.revalidate(path);
return res.json({ revalidated: true });
} catch (err) {
return res.status(500).json({ message: 'Error revalidating', error: err.message });
}
}
Code language: JavaScript (javascript)
Step 3. Configure the environment variables: Create a .env.local
file in the root of your project if it does not exist already.
Step 4. Next, create a secret token. This code sets up an API route that checks for a secret token for security, validates the presence of the path parameter, and triggers the revalidation of the specified path.
Once you have Node.js installed, you can use it to generate a secret token.
Open Your Terminal: Start by opening your terminal or command prompt.
Generate a Secret Token: Run the following command in your terminal:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))
This command uses the crypto module to generate a 32-byte random string in hexadecimal format. The output will be your secret token.
Once the token is generated, copy and paste it into your .env.local
file and give it an environment variable name e.g. `REVALIDATION_SECRET`
It should look like this: REVALIDATION_SECRET=your-secret-key
Use the API route to configure cache revalidation
To configure cache revalidation in the headless WordPress setup, you could follow one of the approaches below:
Use a webhook plugin: You can use plugins like WP Webhooks to enable webhook functionality and trigger the API endpoint you’ve just created when relevant events occur, such as when a post is published or updated.
When you have your secret key generated and need an API endpoint, append a query string parameter to it with the key and value pair, where the key is secret and the value is the secret token. For instance:
https://your-wordpress-site.com/api/revalidate?secret=your-secret-key&path=/your-route
This is the endpoint you can embed in a field that requires it when using a plugin like WP Webhooks. The field will correlate to whatever action will happen when the endpoint that is associated with this path is hit such as updating a post.
Just a note, if you are developing locally and want to test it, you will have to manually visit the endpoint which typically spins up on port 3000 since the app will only know when to revalidate it on your local machine.
Set up WordPress hooks: You can also add actions in your WordPress theme or plugin to send requests to your Next.js API route. Here’s an example using the wp_remote_post
function in php
, which will send a POST request to the Next.js API route whenever a post is saved in WordPress, triggering the revalidation of the corresponding path:
function trigger_revalidation($post_id) {
$url = 'https://your-nextjs-site.com/api/revalidate?secret=your-secret-token&path=' . get_permalink($post_id);
$response = wp_remote_post($url);
if (is_wp_error($response)) {
error_log('Error triggering revalidation: ' . $response->get_error_message());
}
}
add_action('save_post', 'trigger_revalidation');
Code language: PHP (php)
Headless WordPress Platform User Portal
We now have On-Demand ISR set up with the proper configuration. The last steps are to connect our remote repository to WP engine’s headless WP platform, git push any changes, and observe On-Demand ISR working in all its cache invalidation glory.
If you have not connected your local project to a remote repository, go ahead and do so. WP engine headless platform supports GitHub, Bitbucket, and GitLab.
Once you have connected your remote repository and added all your necessary environment variables, go ahead and build the app. If you have done this with an existing repo, you can git push
the change, which will trigger a build.
When the application is finished in the build step, you are on the main page of the WP engine headless WP portal. Navigate over to the Logs subpage:
In the Logs subpage, click the “Show logs” button on the Runtime option:
You should see the same output focusing on line 6 as you did in your terminal to ensure it’s working properly:
Awesome!!! It is implemented and working in runtime. Now, when you edit or input new content in your WP backend, and then visit the live URL of the WP engine headless WP site you just deployed, the ISR should work on demand like so:
Limitations
At the moment, the headless WP platform supports On-Demand ISR with the following limitations:
- Requires @wpengine/atlas-next package: To enable On-Demand ISR on Atlas, you must use the
@wpenngine/atlas-next
package and follow the setup steps outlined in the previous sections of this document. - On-demand ISR for App Router is not supported: The App Router is a new routing system in Next.js that enhances routing capabilities with features like server components and nested layouts. However, Atlas currently supports On-Demand ISR only in the context of the traditional Pages Router. This means that methods like
revalidatePath
andrevalidateTag
, which are used for revalidation in the App Router, are not compatible with the headless WP platform’s ISR mechanism. For more details on the App Router and its data fetching methods, you can refer to the Next.js documentation here. - Rewrites are not supported: Rewrites in Next.js allow you to change the destination URL of a request without altering the URL visible to the user. However, On-Demand ISR on the headless WP platform does not support rewrites. This means that if your Next.js application relies on rewrites, the On-Demand ISR feature might not function as expected. You can learn more about rewrites here.
- Not compatible with Next.js I18N: Since Next.js uses rewrites for internationalization, this feature is not supported on the headless WP platform due to the rewrite limitation mentioned above.
- Next.js >=13.5 is required: To be able to use this feature, you need to update your application to Next.js version 13.5 or higher.
Note: Redirects (which, unlike rewrites, actually change the URL in the user’s browser to the specified destination) are supported.
If you want to give us feedback on how we can make things better for this feature or anything else with the platform, please visit our feedback form.
Conclusion
Implementing On-Demand Incremental Static Regeneration (ISR) with Next.js and Faust.js on WP engine’s headless WP platform is a game-changer for maintaining performance and up-to-date content in a headless WordPress setup. By following the steps outlined in this guide, you can leverage On-Demand ISR to ensure your site remains both fast and current, without the need for full rebuilds.
The integration with the platform also simplifies the deployment and management process, providing a seamless workflow from development to production.
As always, we look forward to hearing your feedback, thoughts, and projects so hit us up in our headless Discord!