Next.js: Introduce a new `fallback: 'blocking'` ISG mode

Created on 29 Jul 2020  路  6Comments  路  Source: vercel/next.js

Feature request

Next.js should allow pages leveraging Incremental Static Generation (fallback: true in getStaticPaths) to opt-into a server-side rendering mode when an unknown path is encountered.

Currently, we serve a static HTML fallback that then loads the data client-side (via a fetch to the server).

While the static HTML fallback is generally considered to be better end-user UX and does not negatively affect SEO, it is incompatible with certain apps that rely on Facebook, Twitter, or other og:* crawlers that don't support JavaScript.

Like fallback: true, after the unknown route successfully renders for the first time, it's served as static HTML going forward and no longer will be a on-demand (blocking) render (SSR).

Describe the solution you'd like

Allow users to return fallback: 'blocking' from getStaticPaths, opting-out of the static HTML fallback.

story 21 p1

Most helpful comment

If the app is being hosted on Vercel too, does the combination of revalidate: 1 and fallback: 'blocking' provide any advantage over using setting a cache control header with max-age: 1 and a really long stale-while-revalidate?

As far as I can tell, setting cache-control this way would let me get the same behavior with getInitialProps?

One advantage is what @timneutkens mentioned above:
This feature it provider-agnostic and built-into Next.js, meaning it does not require a CDN to work.

The second difference is that you can prerender critical paths by returning them from paths: [...], this is not possible with getInitialProps. This feature is very important as it prevents new deployments from 500ing due to your database going down, etc.

All 6 comments

Great! Sounds like this would allow for AMP pages to make use of fallback now then as well?

Trying to wrap my head around how this interacts with incremental static generation.

If the app is being hosted on Vercel too, does the combination of revalidate: 1 and fallback: 'blocking' provide any advantage over using setting a cache control header with max-age: 1 and a really long stale-while-revalidate?

As far as I can tell, setting cache-control this way would let me get the same behavior with getInitialProps?

If the app is being hosted on Vercel too, does the combination of revalidate: 1 and fallback: 'blocking' provide any advantage over using setting a cache control header with max-age: 1 and a really long stale-while-revalidate?

Yeah it's a similar behavior, main difference is that it's integrated with Next.js and you don't have to know the exact cache-control header to set (which often goes wrong, e.g. forgetting to add stale-while-revalidate and such)

If the app is being hosted on Vercel too, does the combination of revalidate: 1 and fallback: 'blocking' provide any advantage over using setting a cache control header with max-age: 1 and a really long stale-while-revalidate?

As far as I can tell, setting cache-control this way would let me get the same behavior with getInitialProps?

One advantage is what @timneutkens mentioned above:
This feature it provider-agnostic and built-into Next.js, meaning it does not require a CDN to work.

The second difference is that you can prerender critical paths by returning them from paths: [...], this is not possible with getInitialProps. This feature is very important as it prevents new deployments from 500ing due to your database going down, etc.

How does one get access to the query that would be available under GetServerSidePropsContext if it's a page with fallback: 'blocking'? GetStaticPropsContext doesn't have it.

Sorry for hijacking a closed issue, I can move this to a Discussion if needed.

_For context, I'm using Next 9.5.5 and 9.5.6-canary.11 to test this and building my site locally using yarn next build as well as deploying to Vercel._

I know this feature is still marked as unstable, but I'm having some trouble getting it to work with incrementally generated pages. If you look at the code below, you can see I'm building a page with the slug about at build time. I'm able to access the amp page for about, but for any other page that is incrementally built, it returns a 404 page if I add .amp or ?amp=1.

After building the site, I tested it a bunch trying to get it to generate an AMP page incrementally. I have a page with slug oss. Initially accessing that page with oss.amp returned 404, but then it worked for about 30 seconds. After that, it went back to 404.

export const getStaticProps: GetStaticProps = async (ctx) => {  
  const slug = processNextQueryStringParam(ctx.params?.slug);

  const page = await getPage({
    slug
  });

  return {
    props: {
      page: page ?? null
    },
    revalidate: 60 // seconds
  }
};

export async function getStaticPaths() {
  return {
    paths: [
      { params: { slug: 'about' } }
    ],
    fallback: 'unstable_blocking'
  };
}

export const config = { amp: 'hybrid' }

_You can view the rest of the file in this repo._

When I look at my .next folder, I can see it successfully generating all the AMP pages, but for some reason, they still return 404 when I try and access them. This seems like a bug that it generates the page, but I'm unable to access it.

image

Update
I must have made a mistake. ISG hybrid AMP pages work with Next 9.5.5, but only locally and not on Vercel. If I update to 9.5.6-canary.11 it no longer works locally or on Vercel.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jesselee34 picture jesselee34  路  3Comments

kenji4569 picture kenji4569  路  3Comments

swrdfish picture swrdfish  路  3Comments

formula349 picture formula349  路  3Comments

flybayer picture flybayer  路  3Comments