Next.js: 404 pages in a SSG site are not revalidated in Next 10

Created on 2 Nov 2020  路  5Comments  路  Source: vercel/next.js

Bug report

Describe the bug

When using Next 9.5, I had an optional catch all route in the root of my pages directory [[...slug]].tsx which made use of getStaticPaths (fallback: false) and getStaticProps (revalidate: 30).

This meant that any pages that did not exist in my site would throw the 404 page, which I had a template for in pages/404.tsx. That also had a revalidate: 30.

With this set up, if I visited mysite.com/cool-page and it 404'd, it would 404. However, if I created /cool-page and revisited it after it had the change to revalidate, I would then see /cool-page.

In Next 10, this is not happening and is preventing me from being able to upgrade to the latest version. When I try in Next 10, I am stuck with a 404 page all of the time, even after creating /cool-page.

To Reproduce

If you require access to my test Contentful, please reach out and I can provide log in to the CMS and also provide access keys for the env vars (privately)

Run the below code in Next 9.5.5 and also in Next 10

Build the site npm run build and run it npm run start

go to a non-existent page, you should get a 404 (e.g. /my-page)

In the CMS, change one the pages to have the url from above (e.g. /my-page)

Reload the page, let it revalidate, reload again.

in 9.5.5 it fetches /my-page
in 10 it still 404's

pages/[[...slug]].tsx

const Index = ({page}) => {
  return (
    <div>
      {page.title}
    </div>
  )
}

const parsedUrlQueryAsUrlString = (params) => {
  const { slug, ...query } = params
  let url = '/'

  if (Array.isArray(slug)) {
    url = `/${slug.join('/')}`
  }
  else if (typeof slug === 'string') {
    url = `/${slug}`
  }

  return {
    url,
    query
  }
}

export const getStaticProps = async ({ params }) => {
  const req = await fetch(`https://cdn.contentful.com/spaces/${process.env.C_SPACE_ID}/environments/master/entries?access_token=${process.env.C_ACCESS_TOKEN}&content_type=standardPage`)
  const routes = await req.json()
  let { url } = parsedUrlQueryAsUrlString(params)
  console.log('url', url)
  let pageData

  const page = routes.items.find((item) => {
    console.log('item', item)
    return item.fields.urlPath === url
  })

  if (page) {
    const reqPage = await fetch(`https://cdn.contentful.com/spaces/${process.env.C_SPACE_ID}/environments/master/entries?access_token=${process.env.C_ACCESS_TOKEN}&sys.id=${page.sys.id}`)

    pageData = await reqPage.json()
  }

  return {
    props: pageData && {page: pageData.items[0].fields} || {},
    revalidate: 5,
  }
}

export async function getStaticPaths() {
  const req = await fetch(`https://cdn.contentful.com/spaces/${process.env.C_SPACE_ID}/environments/master/entries?access_token=${process.env.C_ACCESS_TOKEN}&content_type=standardPage`)
  const routes = await req.json()

  const params = routes.items.map((route) => {
    // We need to supply false for the root most route
    // (e.g. "/" and not "/some/page")
    if (route.fields.urlPath === '/') {
      return { params: { slug: false } }
    }

    return {
      params: {
        slug: route.fields.urlPath.replace('/', '').split('/'),
      },
    }
  })

  return {
    paths: params,
    fallback: false,
  }
}

export default Index

404.tsx

const NotFound = () => {
  return (
    <div>
      <p>not found</p>
    </div>
  )
}

export async function getStaticProps() {
  return {
    props: {},
    revalidate: 5
  }
}

export default NotFound

Expected behavior

In Next 10, I was expecting to have the 404.tsx revalidate pages when they become existant like in version 9.5.5

System information

  • OS: macOs
  • Browser (if applies) [e.g. chrome, safari]
  • Version of Next.js: 9.5.5 and 10
  • Version of Node.js: 12.19.0
bug 2

Most helpful comment

Can confirm it works using fallback: true in getStaticPaths and revalidate and notFound set in getStaticProps. Thanks so much 馃憤

All 5 comments

I experienced it too. Here is my reproduction: next.js-bug-revalidate-not-found. It looks like it is being re-validated in dev mode, but not in prod.

Hi, this should be updated in v10.0.2-canary.17 of Next.js, please update to give it a try!

Can confirm it works using fallback: true in getStaticPaths and revalidate and notFound set in getStaticProps. Thanks so much 馃憤

The docs clearly state: https://nextjs.org/docs/advanced-features/static-html-export

The fallback: true mode of getStaticPaths is not supported when using next export.

wondering why it seems to be the solution for @anthwinter

The docs clearly state: https://nextjs.org/docs/advanced-features/static-html-export

The fallback: true mode of getStaticPaths is not supported when using next export.

wondering why it seems to be the solution for @anthwinter

Your link is not relevant to the issue.

Was this page helpful?
0 / 5 - 0 ratings