Skip to content
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

useCookieLocale() does not work in server context (SSR) #2975

Open
localusercamp opened this issue Jun 13, 2024 · 3 comments
Open

useCookieLocale() does not work in server context (SSR) #2975

localusercamp opened this issue Jun 13, 2024 · 3 comments
Assignees
Labels
bug 🐛 cookie help wanted 🔨 p3-minor-bug Priority 3: a bug in an edge case that only affects very specific usage PR Welcome ssr upstream issue v8

Comments

@localusercamp
Copy link

localusercamp commented Jun 13, 2024

Environment

  • Operating System: Linux
  • Node Version: v20.10.0
  • Nuxt Version: 3.11.2
  • CLI Version: 3.11.1
  • Nitro Version: 2.9.6
  • Package Manager: [email protected]
  • Builder: -
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

https://stackblitz.com/edit/bobbiegoede-nuxt-i18n-starter-hmdag5?file=middleware%2Fssr-context-cookie.ts

Describe the bug

useCookieLocale() always return ref with empty string in server context (SSR).

This is useCookieLocale() source code:

export function useCookieLocale(): Ref<string> {
  // Support for importing from `#imports` is generated by auto `imports` nuxt module, so `ref` is imported from `vue`
  const locale: Ref<string> = ref('')
  const detect = runtimeDetectBrowserLanguage()

  if (detect && detect.useCookie) {
    const cookieKey = detect.cookieKey!

    let code: string | null = null
    if (import.meta.client) {
      code = useNuxtCookie<string>(cookieKey).value
    } else if (import.meta.server) {
      const cookie = useRequestHeaders(['cookie'])
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      code = (cookie as any)[cookieKey]
    }

    if (code && localeCodes.includes(code)) {
      locale.value = code
    }
  }

  return locale
}

In server part there is a useRequestHeaders(['cookie']) call which always return type

{ cookie?: string | undefined }

Next we have this line:

code = (cookie as any)[cookieKey]

It is incorrect, because, cookie variable is object which only has one property which is cookie, but in this line we are trying to get cookieKey key from it.

For example in my app this code:

export default defineNuxtRouteMiddleware(() => {
  if (import.meta.server) {
    console.log(useCookieLocale(), useRequestHeaders(['cookie']));
  }
}

Prints this to console:
image

Additional context

Since Nuxt useCookie() is SSR friendly, i think that useCookieLocale could be rewritten as such:

export function useCookieLocale(): Ref<string> {
  // Support for importing from `#imports` is generated by auto `imports` nuxt module, so `ref` is imported from `vue`
  const locale: Ref<string> = ref('')
  const detect = runtimeDetectBrowserLanguage()

  if (detect && detect.useCookie) {
    const cookieKey = detect.cookieKey!

    const code = useNuxtCookie<string>(cookieKey).value ?? null
    
    if (code && localeCodes.includes(code)) {
      locale.value = code
    }
  }

  return locale
}

Logs

No response

@kazupon kazupon added cookie v8 bug 🐛 ssr PR Welcome help wanted 🔨 p3-minor-bug Priority 3: a bug in an edge case that only affects very specific usage and removed pending triage labels Jun 24, 2024
@john-psina
Copy link

Any updates on this?

My project sends requests to the backend (Django) to get localized product names, etc. Django determines the user's language from cookies.
The problem is that if a user opens a localized link immediately (i.e. via SSR), when backend requests are sent, there will either be nothing in the cookies (if the user is visiting the site for the first time) or there will be the language that the user has previously selected, and not the one that should be used at the moment.

I would be very grateful to the development team if this issue could be fixed in the next update

@john-psina
Copy link

I also believe that this issue should have a higher priority, as it causes a serious problem using i18n with data that is loaded from the backend

@BobbieGoede
Copy link
Collaborator

I agree, your rewrite looks better but unfortunately it will have the same functionality as the current implementation, setting the cookie using Nuxt's useCookie server side will only set the set-cookie header, so we probably need to add some logic to sync a Ref as well as the set-cookie header.

Related issue: nuxt/nuxt#22631

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 cookie help wanted 🔨 p3-minor-bug Priority 3: a bug in an edge case that only affects very specific usage PR Welcome ssr upstream issue v8
Projects
None yet
Development

No branches or pull requests

4 participants