How can I clear the cache for GetStaticPaths in NextJs and remove a dynamic route?

This question may seem basic, but I can't seem to find the answer anywhere online.

Currently, I am diving into NextJs (using TypeScript) and I have successfully set up a site with dynamic routes, SSR, and incremental regeneration deployed on Vercel. Below is an example of the code in my dynamic route handler for GetStaticProps and GetStaticPaths:

export const getStaticPaths: GetStaticPaths = async () => {
    const routes = new CmsHelper().GetRoutes();

    const paths = (await routes).items.map((item, index, items) => {
        return item.fields.urlPath;
    })

    return {
        paths: paths,
        fallback: 'blocking',
    };
}

export const getStaticProps: GetStaticProps = async (context) => {
    const urlParts = context.params?.url as string[] || [];
    const urlPath = `/${urlParts.join('/')}`;
    const article = await new CmsHelper().GetArticle(urlPath);
    return {
        props: {
            article
        },
        revalidate: 10,
    }
}

If I request a new path added after build time in the CMS, it regenerates successfully and shows the page.

Everything seems fine so far.

However, if I unpublish a route in the CMS... it still shows up in the app unless I rebuild and redeploy (in development).

So here's my question: how can I dynamically remove a dynamic route from NextJs' GetStaticPaths cache?

I know that GetStaticProps is called at most once every 10 seconds due to the revalidate setting. But as far as I understand, GetStaticPaths is only triggered when a request comes in from a route that is not already cached(?).

In essence, for integration with a headless CMS, how can I handle unpublishing or renaming pages in NextJs without needing a rebuild/deploy?

Thank you in advance!

Answer №1

Perhaps consider trying out this method detailed here.

Additionally, I have included the code here for your reference.

// pages/blog/[slug].js

import {useRouter} from 'next/router'
import DefaultErrorPage from 'next/error'

export async function getStaticProps({ params }) {
  // fetch data from CMS through params
  const post = await getBlogItem(params.slug)
  return {
    props: {
      post
    }
  }
}

export async function getStaticPaths() {
  return {
    fallback: true,
    paths: []
  }
}

export default function MyPage({post}) {
  const router = useRouter()

  if(router.isFallback) {
     return <h1>Loading...</h1>
  }

  // This includes setting the noindex header because static files always return a status 200 but the rendered not found page page should obviously not be indexed
  if(!post) {
    return <>
      <Head>
        <meta name="robots" content="noindex">
      </Head>
      <DefaultErrorPage statusCode={404} />
    </>
  }

  return <h1>{post.title}</h1>
}

Instead of clearing the cache, perhaps handle scenarios where the fetched content is marked as "unpublished," and in that case, display a 404 Not Found page or any other desired outcome.

You can use something like this:

export async function getStaticProps(context) {

    const {params: {id}} = context

    let data;
    try {
        data = await httpClient...
    } catch (err) {
        if (not err is caused due to content being unpublished){
            // re throw it
            throw err;
        }
        // Else handle it gracefully
        data = null;
    }

    return {
        props: {
            data,
        },
        revalidate: 1
    };
}

Then, implement this on your view component:

export default function Data(props) {
    const {data} = props;

    const router = useRouter()

    // If the page is not yet generated, this will be displayed initially until getStaticProps() finishes running
    if (router.isFallback) {
        return <div>Loading...</div>
    }

    if (!data) {
        return (
            <>
                <Head>
                    <meta name="robots" content="noindex"/>
                </Head>
                <DefaultErrorPage statusCode={404}/>
            </>
        )
    }

    return <DataView {...data} />;

}

Answer №2

My issue was somewhat similar, yet slightly different: I encountered difficulties deploying my project's generated URL from the data, particularly when attempting to add new URLs as the data in the database changed.

The solution to my dilemma lay in realizing that I had set the fallback option to false within my getStaticPaths method. Once I switched it to true, the deployment process in production mirrored that of my local development environment.

I noticed that you're providing a string value for your fallback property. Perhaps consider using a boolean value instead, which is outlined in more detail here: https://nextjs.org/docs/basic-features/data-fetching#the-fallback-key-required

Answer №3

Experience the power of On-Demand Incremental Static Regeneration with the latest release of Next.js 12.2 in the summer of 2022. This feature allows you to update generated pages on demand by simply publishing changes in your headless CMS and utilizing its webhook functionalities.

// pages/api/revalidate.js

export default async function handler(req, res) {
  // Verify the secret token for authentication
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' })
  }

  try {
    // Provide the actual path that needs revalidation
    // For example, use "/blog/post-1" instead of rewritten paths like "/blog/[slug]"
    await res.revalidate('/path-to-revalidate')
    return res.json({ revalidated: true })
  } catch (err) {
    // In case of an error, Next.js will continue to display the last successfully generated page
    return res.status(500).send('Error revalidating')
  }
}

Explore more about using On-Demand Revalidation here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

After extraction from local storage, the type assertion is failing to work properly

I have a unique situation in my Angular project where I have stored an array of data points in the local storage. To handle this data, I have created a custom class as follows: export class Datapoint { id: number; name: string; // ... additional pr ...

The message shown on items.map stating that parameter 'item' is implicitly assigned the type 'any'

Currently, I am delving into the world of Ionic React with Typescript by developing a basic app for personal use. My current challenge involves dynamically populating an IonSegment from an array. Here is the relevant code snippet: const [items, setItems] ...

Looking to retrieve CloudWatch logs from multiple AWS accounts using Lambda and the AWS SDK

Seeking guidance on querying CloudWatch logs across accounts using lambda and AWS SDK Developing a lambda function in typescript Deploying lambda with CloudFormation, granting necessary roles for reading from two different AWS accounts Initial exe ...

Tips for importing a .geojson document in TypeScript using webpack?

I am trying to extract data from a .geojson file but faced some challenges while attempting two different methods: const geojson = require('../../assets/mygeojson.geojson'); The first method resulted in an error message stating: Module parse f ...

I am having difficulty accessing the values stored in my cardTiles variable

I am facing an issue with a variable called cardTiles in my Angular 9 component. The variable is defined as cardTitles:Product[] = []; The Product class is defined as follows export class Product{ productName: string;} When I console.log(this.cardTi ...

Tips for incorporating the "build" directory into the Travis-CI build process and deployment of an npm module

Currently, I am working with a Typescript module that has a directory ./src And I also have travis-ci set up for the project. language: node_js node_js: - 5.1.0 install: - npm install - npm install -g mocha - npm install -g gulp - npm install -g tsd - ...

Issue with blueprintjs/core type in JupyterLab Extension after running npm install

Developed a JLab extension and saved it to Git repository. Established a new environment and successfully pulled the code, which was also verified by a friend. Subsequently, included a new react object to the extension and pushed it back to Git in a fresh ...

Do I need to generate a sitemap for data retrieved from a database in NextJS?

I'm currently working with Prisma and NextJS to fetch data through dynamic routes. However, I am unsure about the functionality of SEO and sitemaps. Would it be necessary for me to generate a sitemap for each individual post such as /post/1? ...

Encountering the error "gapi-script causing a ReferenceError: window is not defined in Next.js"

Despite trying numerous solutions, I continue to encounter the error shown in the screenshot below... puzzled as to why? Server Error ReferenceError: window is not defined This error occurred during page generation. Any console logs will be visible in the ...

What is the best way to trigger a mat-menu to open with just one click, while also automatically closing any other open menus at

I've encountered an issue where if there are multiple menus in the header, opening a menu for the first time works fine. However, if a menu is already open and I try to open another one, it doesn't work as expected. It closes the previously opene ...

Customizing AxiosRequestConfig with Axios in TypeScript can greatly enhance the functionality and

Currently working with React and Axios. Lately, I've been experimenting with custom configurations in Axios as shown below: import $axios from 'helpers/axiosInstance' $axios.get('/customers', { handlerEnabled: false }) However, wh ...

The module for the class could not be identified during the ng build process when using the --

Encountering an error when running: ng build --prod However, ng build works without any issues. Despite searching for solutions on Stack Overflow, none of them resolved the problem. Error: ng build --prod Cannot determine the module for class X! ...

Tips on postponing 'next/link' in Next.js

How can I implement a delay for page transitions using Route link in Nextjs Version 12.1.0? <Link href="/"> <a className='logo-home'></a> </Link>{' '} This is the approach I took: In my App.js file ...

Developing a specialized collection of React components for efficient web development

I am currently in the process of developing my own library package for the first time. However, I have encountered a particular issue where despite successful compilation, the page fails to locate the module associated with my component within the library. ...

When a const variable is declared within the composition-api setup(), it remains unchanged unless redeclared within the function scope

Being primarily a back-end developer, the front-end side of things is still relatively new to me. I'm aware that there are concepts in this domain that I haven't fully grasped yet, and despite my efforts, I'm unable to resolve a particular i ...

I am experiencing an issue with my service provider when it comes to displaying multiple navigator stacks

Currently, I am developing a provider to manage the user's state across different views. The primary function of this provider is to display either one stack navigator or another based on whether a certain variable is filled or empty. This setup allow ...

How to import an HTML file using TypeScript

I need to load an html file located in the same directory as the typescript file and return it from the function. public ...(... ) : angular.IHttpPromise<string> { ... return $http({ method: 'GET', url: &apos ...

Tips for obtaining the accurate HTML code format using Angular 2's input feature:

I am looking to retrieve all the code with an input as [input] and a tag as #tag. When attempting to obtain HTML code with jQuery using console.log($("#content")[0].outerHTML);, this is an example of how the code looks: <div dnd-droppable [dropZones]= ...

Learn how to capture complete stack traces for errors when using Google Cloud Functions

In the codebase I am currently working on, I came across a backend service that I would like to utilize for logging all errors along with their corresponding Http statuses. If possible, I also want to retrieve the full stack trace of these errors from this ...

Is there a way to eliminate text from a barcode image using JavaScript or TypeScript?

This is my unique html code <div class="pr-2" style="width: 130px"> <div *ngIf="!element.editing" > <span class="ss">{{element.barcode}}</span> </di ...