vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.83k stars 26.96k forks source link

Different query params in getStaticProps cause ignore cache #27638

Closed inacior closed 3 years ago

inacior commented 3 years ago

What version of Next.js are you using?

11.0.1

What version of Node.js are you using?

14.17.1

What browser are you using?

Chrome

What operating system are you using?

macOS

How are you deploying your application?

Vercel

Describe the Bug

Hello, when I enter in my application like https://myapp.com/offer/1?utm_source=twitter then I receive a cached page (I'm using ISR), the code:

// File: pages/offer/[id]/index.js

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

export async function getStaticProps(context) {
  const { offer } = await getOffer(context.params.id);

  return {
    props: {
      offer,
    },
    revalidate: 300,
  };
}

BUT, if I enter in https://myapp.com/offer/1?utm_source=facebook, the getOffer function is called again, even with revalidate prop. How do avoid this? I need the same page without a new api call.

Expected Behavior

The same page without a new api call

To Reproduce

// File: pages/offer/[id]/index.js

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

export async function getStaticProps(context) {
  const { offer } = await getOffer(context.params.id);

  return {
    props: {
      offer,
    },
    revalidate: 300,
  };
}
hatsumatsu commented 3 years ago

This is a valid concern. Many sites face randomized query parameters from third parties they can not control which produces a huge amount of computation on hosts like vercel.

hatsumatsu commented 3 years ago

The ideal solution would be a config for an allowlist and/or blocklist for query parameters affecting ISR.

styfle commented 3 years ago

We have a fix for this under an experimental flag.

You can try it out today by setting NEXT_EXPERIMENTAL_ALLOW_QUERY=1 in your Vercel project environment variables and deploying again.

Let me know if this does or doesn't solve the issue, thanks!

hatsumatsu commented 3 years ago

@styfle this sounds promising! _ALLOW_QUERY=1 means query params do or don't trigger revalidation?

And I guess it's a Vercel-specific global setting without the option to specify which params to revalidate?

Would still be great to have a fix for this in nextjs to account for generic nodejs hosting solutions.

styfle commented 3 years ago

Would still be great to have a fix for this in nextjs to account for generic nodejs hosting solutions.

I tried the steps to reproduce and it only reproduces on Vercel, not with next start. Therefore, the fix is only for Vercel.

hatsumatsu commented 3 years ago

@styfle This is great, can confirm that the issue appears only on Vercel but not in a generic nodejs env.

Could you clarify the effects of NEXT_EXPERIMENTAL_ALLOW_QUERY=1 vs. NEXT_EXPERIMENTAL_ALLOW_QUERY=0. 1 means params trigger revalidation and 0 they are ignored?

ijjk commented 3 years ago

Hi, NEXT_EXPERIMENTAL_ALLOW_QUERY=1 enables an experimental flag on Vercel that prevents the query params from busting the cache (a bit confusing from this point of view 😄).

Please give it a try and confirm it's working for you.

styfle commented 3 years ago

In hindsight, the name of the env var should have been ALLOWLIST_QUERY.

But the good news is, that env var is no longer necessary.

Starting today, all new Vercel deployments will have this behavior, thanks!

hatsumatsu commented 3 years ago

@styfle does ALLOWLIST_QUERY suggest that we can somehow selectively allow/ignore certain query params on Vercel?

styfle commented 3 years ago

No, you cannot select which query string parameters to ignore.

getStaticProps() doesn't provide access to the query string since it runs at build time and at runtime (during revalidation) so we can safely ignore all query string parameters.

balazsorban44 commented 2 years ago

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.