opral / inlang-paraglide-js

Tree-shakable i18n library build on the inlang ecosystem.
https://inlang.com/m/gerre34r/library-inlang-paraglideJs
48 stars 1 forks source link

[Paraglide-Next] NEXT_LOCALE cookie incorrectly set on the home page (/, root app page) #171

Closed coderfin closed 2 months ago

coderfin commented 4 months ago

I setup a project using npx @inlang/paraglide-next init with two locales en and es (English and Spanish). English is the default. When running next dev the NEXT_LOCALE cookie always gets set to the en on the home page regardless of locale that I am in. The locale brefiely flashes the correct locale and then is set back to en when looking at a non-english home page.

Subpaths do show the correct locale.

The middleware does log the correct local on all pages.

Messages are still translated correctly on all pages.


Here is a breakdown of what I am seeing Path --> NEXT_LOCALE value / --> en */es --> es --> en /about --> en /es/about --> es

Screenshot 0006-07-11 at 9 59 11 PM

*Screenshot 0006-07-11 at 9 59 58 PM

* This is the problem path, the locale very brefiely changes to the correct locale and then back to the default

r0skar commented 2 months ago

I think what happens is that your middleware matcher includes static files. When they are requested, the Paraglide middleware is not able to infer the correct lanuage and will fallback to the default and set a cookie in the process.

coderfin commented 2 months ago

I think what happens is that your middleware matcher includes static files. When they are requested, the Paraglide middleware is not able to infer the correct language and will fallback to the default and set a cookie in the process.

To test this I rewrote my middleware.ts file to only contain:

import { type NextRequest } from 'next/server'
import { middleware as paraglide } from '@/lib/i18n'

export function middleware(request: NextRequest) {
  return paraglide(request)
}

There is no config or matcher. I still see the issue.

r0skar commented 2 months ago

I meant to use the matcher config to limit the middleware to not run at all for any static file. I use this for example:

export const config = {
  matcher: [
    // Skip Next.js internals and all static files, unless found in search params.
    "/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
    // And always run for API routes.
    "/(api|trpc)(.*)",
  ],
};

You can also try to log what request resolves to which language?

export function middleware(request: NextRequest) {
  console.log(request.url, paraglide.detectLanguage(request))
  return paraglide.getResponse(request, paraglide.detectLanguage(request))
}
coderfin commented 2 months ago

@r0skar Thank you for the additional information. This helped me come up with a solution that fits my use case.

I am using Serwist and Partytown. The Serwist and Partytown scripts require that cross-origin headers be set. I set these headers in the middleware. By not excluding these scripts in the matcher it causes the cookie issue.

My solution is to only set the response to the paraglide response on requests that are not Serwist or Partytown requests otherwise I just use a NextResponse.

Basically:

let response = NextResponse.next()

const useParaglideResponse = !request.url.includes('~partytown') && !request.url.includes('/swe-worker-')
if (useParaglideResponse) {
  response = paraglide(request)
}

// Headers needed to enable Partytown Atomics and for the swe-worker
// See: https://partytown.builder.io/atomics
response.headers.set('Cross-Origin-Embedder-Policy', 'credentialless')
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin')

return response

Is this issue something that is known of by the nature of NextJS or documented in Paraglide? Is this an issue that others are aware of and can quickly identify a solution for? Would it make sense to document this somewhere?

Since there is a workaround or solution, this issue could probably be closed unless others think it is worth making any adjustments or changes.

samuelstroschein commented 2 months ago

Thanks you two for coming up with a solution. I'll close the issue for now to get an overview of outstanding issues for paraglide. (I am taking over Paraglide JS this week)