Skip to content

Preset vercel: query params are ignored by cache #1880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
fmoessle opened this issue Nov 3, 2023 · 13 comments
Open

Preset vercel: query params are ignored by cache #1880

fmoessle opened this issue Nov 3, 2023 · 13 comments

Comments

@fmoessle
Copy link

fmoessle commented Nov 3, 2023

Environment

nitro: 2.7.0
node: v18.18.0
nuxt: 3.8.0

Reproduction

not available

Describe the bug

I use query params to figure out what page in a pagination the server should render, e.g. /?page=1

When configuring cache like this

routeRules: {
  '/**': {
    cache: {
      swr: true,
      maxAge: 60 * 60 * 48,
      staleMaxAge: 60 * 60 * 96
    }
  }
}

vercel's cache seems to ignore the query param "page". When loading "/?page=2" I receive the cached version for "/".

This doesn't seem the be an issue with Vercel, because other pages (not nuxt/nitro) don't suffer from this issue.

So my assumption is this is an issue with nitro's vercel preset.

Additional context

No response

Logs

No response

@Blemming
Copy link

This happens in node environment also, but only in production I believe

@BrocksiNet
Copy link

I can confirm this issue. And also can provide a reproduction if needed.

@Alex--C
Copy link

Alex--C commented Apr 17, 2024

Also running into this.
Interestingly, the issue does not appear on nuxt's vercel demo: https://nuxt-vercel-isr.vercel.app/static vs https://nuxt-vercel-isr.vercel.app/static?foobar
Makes me think it might be a Vercel config issue?

@aethr
Copy link

aethr commented Aug 19, 2024

I've run into this in a Vercel preview environment when trying to migrate my API endpoints from manual configuration via defineCachedEventHandler to a generic config in nuxt.config.ts:

export default defineNuxtConfig({
  routeRules: {
    '/api/**': {
      swr: 60 * 60, // 1h
    },
  },
});

A bunch of API endpoints started throwing errors because they were missing a required query param. I added a log line to one of the endpoints:

  console.log('query:', JSON.stringify(getQuery(event)));

This shows up in the Vercel runtime logs for each request:

// /api/grid/10/ch4-emission?ch4Threshold=1.0276462172345253e-10&period=2024-01&page%5Blimit%5D=19
query: {}

A similar request against the dev server results in:

 query: {"ch4Threshold":"1.0276462172345253e-10","period":"2024-01","page[limit]":"195220"}

@aethr
Copy link

aethr commented Aug 19, 2024

As an additional note to the previous comment, although my app makes several calls to the above endpoint for each view (something like paginating through a large result set with requests like ?period=2024-01 and ?period=2023-12 etc), there was only one log line with query: {} even though there were 20+ requests to the endpoint.

I would guess that setting { swr: true } in routeRules is ignoring search/query params when establishing the cache key, and therefor query params are not being sent to the request handler. This probably makes sense for static pages (lots of people visiting URLs with random google tracking rubbish like /about/?gtm_source=12321321431), but doesn't work as well for API routes.

@20x-dz
Copy link

20x-dz commented Sep 5, 2024

We just got stung by this (on Vercel with isr enabled), as our paginated blog index page (?page=2, ?page=3, …) was having hydration mismatches for subsequent pages. Took quite some time to get to the root of this…

While #2375 seems promising, we're probably going to migrate the query param to a route param.

@Baroshem
Copy link

Baroshem commented Feb 5, 2025

I am having the same issue but with my case, the problem is that I cannot migrate to a route param.

In my setup, we have a Nuxt 3 app deployed to Vercel and Storyblok as a CMS. Storyblok adds _storyblok query param to the url and based on that, I detect if a website is displayed in Storyblok (if so, the draft content version should be used). I tried using allowQuery: ['_storyblok'] but it does not work for me while passQuery: true results in 500 error from Vercel.

Does anyone have any other idea on how this could be acomplished?

@20x-dz
Copy link

20x-dz commented Feb 5, 2025

You need to use both passQuery and allowQuery, see https://nitro.build/deploy/providers/vercel#fine-grained-isr-config-via-route-rules

E.g. for my paginated blog index page

    "/blog": {
      isr: {
        allowQuery: ["page"],
        expiration: 3600,
        passQuery: true,
      },
    },

@Baroshem
Copy link

Baroshem commented Feb 5, 2025

Do you use vercel preset or vercel-edge? In my case when I added both allowQuery and passQuery it resulted in 500 :(

I managed to make it work by instead of watching for query param to get information from the ssrContext?.event.node.req.headers.referer which works for me. Not perfect but still.

@20x-dz
Copy link

20x-dz commented Feb 5, 2025

We use the vercel preset (with vercel-edge we had some issues on our stack we didn't bother looking into - but that was roughly a year ago).

You might want to open a dedicated issue for the 500 error you're seeing with some details?

Would you mind sharing the respective route rule?

@mkucmus
Copy link

mkucmus commented Feb 5, 2025

We use the vercel preset (with vercel-edge we had some issues on our stack we didn't bother looking into - but that was roughly a year ago).

we encountered the similar behavior:

with vercel-edge it works properly (but slower than serverless functions, as if the data wasn't located in Europe's cdn's where I'm located - not really important right now).

with vercel serverless functions enabled, the route doesn't serve the dynamic data depended on query params (filtering and stuff like that) - like the nuxt config was ignored for allowQuery setting .

I discovered that route.query is not accessible or empty - as If it was cached using a key made of only route path, without taking params into account.

when passQuery is enabled, there is an url query glued to the URL, and the 404 is being thrown.

@20x-dz
Copy link

20x-dz commented Feb 5, 2025

I tried implementing an ISR cache busting middleware and adding a query param to a wildcard route (like below) triggered a 404 as well on all pages. Did you try it on a dedicated/know URL?

    "/**": {
      isr: {
        allowQuery: ["forceRefresh"],
        expiration: 3600,
        passQuery: true,
      },
    },

@mkucmus
Copy link

mkucmus commented Feb 6, 2025

I created a little nitro plugin to ensure what request comes in the serverless function:

export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook("request", (event) => {
    const queryParams = getQuery(event);
    console.log(
      "on request ----------------------",
      queryParams,
      event.path,
      event.headers,
      event.context,
      event.node.req,
    );
  });
});

and found that the queryParams are not present inside the function - despite of being discovered by vercel gateway at the beginning (blue rectangle):

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants