Next JS app router with Prismic page builder showing 404 randomly on some pages even though they exist

Describe your question/issue in detail

Hello. I have been working on a NextJS app that implements Prismic SliceMachine and page builder. I have set up my routes in prismicio.ts as well as setting the cache option as recommended in the createClient fucntion:

import * as prismic from "@prismicio/client";
import * as prismicNext from "@prismicio/next";
import config from "../slicemachine.config.json";

/**
 * The project's Prismic repository name.
 */
export const repositoryName =
  process.env.NEXT_PUBLIC_PRISMIC_ENVIRONMENT || config.repositoryName;

/**
 * A list of Route Resolver objects that define how a document's `url` field is resolved.
 *
 * {@link https://prismic.io/docs/route-resolver#route-resolver}
 */
// TODO: Update the routes array to match your project's route structure.
const routes: prismic.ClientConfig["routes"] = [
  // Examples:
  {
  	type: "landingpage",
  	path: "/",
  },
  {
    type: "inner_page",
    path: "/:uid"
  },
  {
    type: 'survey_template_page',
    path: '/survey-templates/:uid',
  },
  {
    type: 'survey_landing_page',
    path: '/all-surveys/:uid',
  },
  {
    type: 'survey_page',
    path: '/all-surveys/:uid/survey',
  },
];

/**
 * Creates a Prismic client for the project's repository. The client is used to
 * query content from the Prismic API.
 *
 * @param config - Configuration for the Prismic client.
 */
export const createClient = (config: prismicNext.CreateClientConfig = {}) => {
  const client = prismic.createClient(repositoryName, {
    routes,
    fetchOptions:
      process.env.NODE_ENV === "production"
        ? { next: { tags: ["prismic"] }, cache: "force-cache" }
        : { next: { revalidate: 5 } },
    ...config,
  });

  prismicNext.enableAutoPreviews({
    client,
    previewData: config.previewData,
    req: config.req,
  });

  return client;
};

Impacted feature

For my /all-surveys/:uid as well as /all-surveys/:uid/survey pages, I randomly get 404 errors (These pages do exist - I am guessing the 404 happens after there is low or no traffic on those pages for a couple of hours - just a guess based on what I have observed). I have to go to the Prismic dashboard and manually trigger the webhook that I have set up for /api/revalidate:

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

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

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

Also, I have to use export const dynamic = "force-dynamic"; in the page.tsx file for /all-surveys/:uid/survey which is one of the problematic routes that show 404 sometimes.

Hosting provider

I am hosting my application on Heroku (a paid plan so the servers don't go to sleep).

Package.json file

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "slicemachine": "start-slicemachine"
  },
  "dependencies": {
    "@emotion/react": "^11.11.4",
    "@emotion/styled": "^11.11.5",
    "@googlemaps/markerclusterer": "^2.5.3",
    "@headlessui/react": "^1.7.18",
    "@hello-pangea/dnd": "^16.6.0",
    "@hookform/resolvers": "^3.3.4",
    "@lucia-auth/adapter-mongodb": "^1.0.3",
    "@mui/material": "^5.15.15",
    "@prismicio/client": "^7.3.1",
    "@prismicio/next": "^1.5.0",
    "@prismicio/react": "^2.7.3",
    "@radix-ui/react-accordion": "^1.1.2",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-popover": "^1.0.7",
    "@radix-ui/react-separator": "^1.0.3",
    "@radix-ui/react-slot": "^1.0.2",
    "@radix-ui/react-switch": "^1.1.0",
    "@radix-ui/react-tooltip": "^1.0.7",
    "@vis.gl/react-google-maps": "^1.0.2",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.1.0",
    "date-fns": "^3.6.0",
    "dayjs": "^1.11.11",
    "echarts": "^5.5.0",
    "echarts-for-react": "^3.0.2",
    "email-validator": "^2.0.4",
    "embla-carousel-react": "^8.1.5",
    "framer-motion": "^11.0.14",
    "google-map-react": "^2.2.1",
    "libphonenumber-js": "^1.10.60",
    "lucia": "^3.2.0",
    "lucide-react": "^0.358.0",
    "mobile-drag-drop": "^3.0.0-rc.0",
    "mongodb": "^6.5.0",
    "next": "14.1.3",
    "next-themes": "^0.3.0",
    "oslo": "^1.2.0",
    "react": "^18",
    "react-countup": "^6.5.3",
    "react-datepicker": "^6.6.0",
    "react-day-picker": "^8.10.0",
    "react-device-detect": "^2.2.3",
    "react-dom": "^18",
    "react-dropzone": "^14.2.3",
    "react-hook-form": "^7.51.2",
    "react-markdown": "^9.0.1",
    "react-phone-input-2": "^2.15.1",
    "react-textarea-autosize": "^8.5.3",
    "remark-gfm": "^4.0.0",
    "remark-math": "^6.0.0",
    "swiper": "^11.0.7",
    "tailwind-merge": "^2.2.1",
    "tailwindcss-animate": "^1.0.7",
    "use-debounce": "^10.0.1",
    "usehooks-ts": "^3.0.2",
    "uuid": "^9.0.1",
    "validator": "^13.11.0",
    "vaul": "^0.9.0",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@slicemachine/adapter-next": "^0.3.38",
    "@tailwindcss/aspect-ratio": "^0.4.2",
    "@tailwindcss/forms": "^0.5.7",
    "@types/google-map-react": "^2.1.10",
    "@types/google.maps": "^3.55.5",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-datepicker": "^6.2.0",
    "@types/react-dom": "^18",
    "@types/validator": "^13.11.9",
    "autoprefixer": "^10.4.18",
    "eslint": "^8",
    "eslint-config-next": "14.1.3",
    "eslint-config-prettier": "^9.1.0",
    "postcss": "^8",
    "prettier": "^3.2.5",
    "prettier-plugin-tailwindcss": "^0.5.12",
    "slice-machine-ui": "^1.26.0",
    "tailwindcss": "^3.4.1",
    "typescript": "^5"
  },
  "cacheDirectories": [
    "node_modules/",
    ".next/cache/"
  ]
}

Note that I added the cacheDirectories in package.json because of this: Heroku: Warning: No build cache found. Please configure build caching for faster rebuilds. · vercel/next.js · Discussion #12286 · GitHub

Anyone has any idea why this is happening and what my options are? Thank you.

Hi @akbarbakhshiwebdev ,

My guess here is that because you are caching the master ref is stale and you aren't getting the most up to date content.

Please remove any cache set-ups from your project as it's something we don't recommend for this reason.

Thanks.

Hi @Phil . Thanks for your response. Just to make sure I understand correctly, are you referring to the fetchOptions in the createClient function in the prismicio.ts file? Like changing it to "next: { tags: ["prismic"] }, cache: "no-cache" ?

No I was talking about this cache:

If it's only a warning and not a blocker, I'd remove it.

1 Like

@Phil I remove that and it seems like in the past two days I haven't got the 404 anymore. I will keep an eye to make sure it stays the same way, but your suspicion seems to be right. Thanks for the insight.

1 Like

As it turns out, the issue is actually not resolved yet. The pages started showing 404 again today. So the issue was not with the master ref being stale. Any other thoughts? probably need to check with Heroku support as well

I would need more information than a 404. Do you have any build errors in Heroku?

Since it worked and came back, I would guess there's still a cache being built in Heroku for your Next project, which isn't being revalidated.

No build errors in Heroku. Since i removed the cacheDependencies, I ma now getting that warning again.

 ⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache

I have asked Heroku support too about my issue awaiting their response. In the meantime do you think clearing Heroku build cache as mentioned below can be something to try?

https://help.heroku.com/18PI5RSY/how-do-i-clear-the-build-cache

I think so; I think you also need to set up revalidation as suggested here.

More than that I would recommend using Vercel for Next.js deployments.