Troubleshooting: Caching with Next.js & Vercel

This guide (a summary of this original topic) provides solutions for resolving caching issues when deploying a Next.js application using the App Router on Vercel. If you're experiencing stale content or unexpected caching behavior, follow these steps to troubleshoot and resolve the issue.

Common associated errors:

  • ForbiddenError: Access to this Ref requires an access token
  • RefNotFoundError: Ref not found
  • RefExpiredError: The provided ref is no longer accessible, it has expired

1. Understand the Caching Issue

When deploying a Next.js app using the App Router on Vercel, you might notice that changes made to the Prismic content are not immediately reflected in the live app. This typically happens due to how Vercel and Next.js handle caching, especially with Incremental Static Regeneration (ISR). By default, Vercel’s Edge Network caches pages to optimize performance, which can lead to outdated content if not configured properly.

2. Set Up On-Demand Revalidation

To ensure your app fetches new content immediately after publishing documents in Prismic, set up on-demand revalidation:

-Solution: Configure your app to clear Next.js’ network cache upon content changes by setting up on-demand revalidation.

Create an /api/revalidate Route Handler:

  1. Create a directory: At src/app/api/revalidate.
  2. Create a file: Within that directory, create a file named route.ts and paste in the following code:
    // src/app/api/revalidate/route.ts

    import { revalidateTag } from 'next/cache';
    import { NextResponse } from 'next/server';

    export async function POST() {
      revalidateTag('prismic');

      return NextResponse.json({ revalidated: true, now: Date.now() });
    }

Set up on-demand revalidation in Prismic:

Once your app is deployed and has a public URL, create a Prismic webhook pointed to the /revalidate endpoint:

  • Go to your Prismic repository.
  • Open the settings page using the gear icon in the bottom left corner.
  • Select Webhooks in the sidebar.
  • Fill out the fields with these values:
    • Name of the Webhook: Next.js on-demand revalidation
    • URL: Your app’s deployed URL + /api/revalidate (example: https://example.com/api/revalidate)
    • Triggers: Only check “A document is published” and “A document is unpublished”
  • Click “Add this webhook”.

You can test if everything is working by publishing an edit to a document and viewing its page on your deployed website. Changes should be reflected almost immediately after publishing.

3. Add Fetch Options to Prismic Client Configuration

Configuring the fetch options in the Prismic client can help manage caching behavior more effectively:

Solution: Add a fetchOptions parameter to the createClient function to control caching based on the environment:

  // src/prismicio.js

  import * as prismic from '@prismicio/client';
  import * as prismicNext from '@prismicio/next';

  export const createClient = (config = {}) => {
    const client = prismic.createClient(repositoryName, {
      fetchOptions:
        process.env.NODE_ENV === "production"
          ? { next: { tags: ["prismic"] }, cache: "force-cache" }
          : { next: { revalidate: 5 } },
      ...config,
    });

    prismicNext.enableAutoPreviews({ client });

    return client;
  }

This configuration helps control how your app fetches data, optimizing for both production and development environments.

4. Ensure Proper Access Token Configuration

An access token might be necessary to resolve caching issues and ensure fresh content is fetched from Prismic:

Solution:
Generate an access token for Prismic. More information on generating an access token can be found here. Update your Prismic client setup to include the access token:

    const client = prismic.createClient(repositoryName, {
      routes,
      accessToken: process.env.PRISMIC_ACCESS_TOKEN,
      fetchOptions:
        process.env.NODE_ENV === "production"
          ? { next: { tags: ["prismic"] }, cache: "force-cache" }
          : { next: { revalidate: 5 } },
      ...config,
    });

Add the following line to your .env.local file and your environment settings on Vercel:
PRISMIC_ACCESS_TOKEN=YOUR_TOKEN

5. Clear the Cache on Vercel Manually

If the above steps do not resolve the issue and you need to get unblocked right away, you can manually clear the cache on Vercel:

6. Automate Cache Clearing on Build

To ensure the cache is cleared every time you build your Next.js application, modify your build script to remove the .next/cache/fetch-cache directory:

Solution: Add the following script to your package.json to clear the fetch cache before each build:

"scripts": {
  "build": "rm -rf .next/cache/fetch-cache && next build"
},

This script reduces the chances of serving stale content after a new build by clearing the cache.

7. Adjust Environment Variables

Another option is to use the Environment Variable VERCEL_FORCE_NO_BUILD_CACHE with a value of 1. You can find limited info on that here.

VERCEL_FORCE_NO_BUILD_CACHE=1 .

8. Check for Incorrect dynamicParams Configuration

Incorrect usage of dynamicParams can cause caching issues:

Solution: If you have set dynamicParams to false in your page.tsx file, this might prevent dynamic routing and parameterization, leading to stale content:

export const dynamicParams = false;

Remove this setting or adjust it as needed to allow Next.js to handle dynamic segments more flexibly. Read more about dynamicParams in the Next.js documentation.

9. Test Your Configuration

After implementing the changes, test your deployed application:

Solution: Update content in Prismic and check how quickly these changes are reflected in your live application.
Use browser developer tools to inspect network requests and verify that the correct cache headers (Cache-Control, x-vercel-cache) are being sent.

10. Disabling Caching (Not Recommended)

If you prefer to disable caching entirely:

Solution: Set Cache-Control: no-store in your headers. However, use this approach cautiously, as it can significantly impact performance and load times.

By following these troubleshooting steps, you should be able to address most caching issues when using Next.js with Prismic and deploying on Vercel. Be sure to review your configuration settings and consult documentation from both Prismic and Vercel for the most up-to-date advice.

More support:

Each project's specific code may have different caching/revalidating setups.

The issue is actually around Vercel's cache system, so the best help you might receive here could be through their help centre.

1 Like