Skip to content

Payload extraction ignores query parameters #34496

Description

@joaolisboa

Environment

Operating system macOS 24.6.0
CPU Apple M1 Pro (8 cores)
Node.js version v20.20.1
nuxt/cli version 3.33.1
Package manager npm@10.8.2
Nuxt version 4.3.1
Nitro version 2.13.1
Builder vite@7.3.1
Config compatibilityDate, devtools, experimental, routeRules
Modules -

Reproduction

https://stackblitz.com/edit/github-mbxtgd4q?file=app%2Fapp.vue

  1. Enter website
  2. Defaults to page 1
  3. Click to go to next page which adds the ?page=2
  4. Refresh (or hard-refresh without cache) - at this point in the client there's an hydration issue because the extracted payload.json doesn't include the ?page=2

Page code

<script setup lang="ts">
import type { NuxtApp } from 'nuxt/app'

const route = useRoute()

const page = computed(() => route.query?.page ? parseInt(route.query.page as string) : 1)

const key = computed(() => {
  const key = `app-${page.value}`
  console.log('key evaluated as', key)
  return key
})

const { data } = await useAsyncData(key, async (_nuxtApp, { signal }) => {

  return {
    page: page.value
  }
}, {
  server: true,
  getCachedData: (key: string, nuxtApp: NuxtApp) => {
    const cached = nuxtApp.payload.data[key] || nuxtApp.static.data[key]
    console.log('getCachedData hit?', !!cached, 'key:', key)
    console.log('available payload keys:', Object.keys(nuxtApp.payload.data))
    return cached
  },
})

</script>
<template>
  <div>
    page: {{ data?.page }}
  </div>
  <div>
    <NuxtLink :to="{ query: { page: page + 1 } }">Go to next page</NuxtLink>
  </div>
</template>

routeRules:

routeRules: {
    "/**": {
      cache: {
        swr: true,
        maxAge: 1800, // serve fresh content for 30 minutes
        staleMaxAge: 1800,
      },
    },
  },

Describe the bug

I'm having an issue with the payload extraction where it seems to ignore all query params in the payload.json request
This happens with SWR
The SSR page returns with the correct info. It's just the payload.json request that is made that comes without the query. This then gives an incorrect payload to the client because it expects page=2 and gets page=1 data

You can see from the logs during hydration it shows an incorrect existing key.

The behaviour this has on a real project is:

  1. SSR loads page correctly (HTML is as expected)
  2. On the client hydration runs, the getChacedData reports there's not payload for the given data (because it's using the payload.json instead of the payload inside HTML) and so the fetch reruns
  3. Tons of hydration errors because we're now loading again

This also means additional load on the server because we're making a new request on the client, since it assumes the payload doesn't exist

SSR:

Image

payload.json:

Image

Additional context

I've not managed to find an exact issue describing this issue, but if there's an existing error please close this issue.
One thing, I created this repo but the ecommerce project I'm writing where I'm facing this issue I really need query params to work because it's unmanageable to use route params for dynamic filters

Logs

index.vue:10 key evaluated as app-2
index.vue:23 getCachedData hit? false key: app-2
index.vue:24 available payload keys: ['app-1']

Metadata

Metadata

Assignees

No one assigned

    Labels

    🔨 p3-minorMinor issue, should be fixed

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions