Open huskyjp opened 10 months ago
Do you reproduce the issue when running locally? AFAIK this is a bug with CodeSandbox, they don't preserve cookies correctly.
@QuiiBz Thanks for the response! Yes it also does the same behavior in my local environment. But I also noticed that this problem is related to the cookies.
The thing is my current middleware.ts
has some rewrite condition like below
import { NextRequest } from "next/server"
import { createI18nMiddleware } from "next-international/middleware"
export const I18nMiddleware = createI18nMiddleware({
locales: ["en", "jp"],
defaultLocale: "en",
urlMappingStrategy: "rewriteDefault",
})
export default function middleware(request: NextRequest) {
const url = request.nextUrl.clone()
const pathname = url.pathname
// Check if the URL does not contain any of the specified locales
// It basically works but did not change the nextjs cookie locale info so when we use `Link` component, it behaves strange.
// if (!pathname.startsWith("/en/") && !pathname.startsWith("/jp/")) {
// url.pathname = `/en${pathname}`
// console.log("Redirecting to: ", url.toString())
// return NextResponse.rewrite(url)
// }
return I18nMiddleware(request)
}
export const config = {
matcher: ["/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)"],
}
The reason why I added if (!pathname.startsWith("/en/") && !pathname.startsWith("/jp/"))
is when we try to dynamically access the path without specifying the default locale (in this case, dynamically typing & changing the URL path from localhost:3000/jp/admin/
to localhost:3000/admin/
), nextjs stays the locale as is since the cookie is still the same so I can't basically change the locale from the URL bar.
So basically I want to know if there is a way to handle user can type and dynamically change the locale & route to the correct path from URL bar without above if statement in the middleware.ts?
Ok so finally I could manage the cookies correctly via middlware.ts
like so.
import { NextRequest, NextResponse } from "next/server"
import { createI18nMiddleware } from "next-international/middleware"
export const I18nMiddleware = createI18nMiddleware({
locales: ["en", "jp"],
defaultLocale: "en",
urlMappingStrategy: "rewriteDefault",
})
export default function middleware(request: NextRequest) {
const url = request.nextUrl.clone()
const pathname = url.pathname
const currentLocale = pathname.startsWith("/jp/") ? "jp" : "en"
const cookieLocale = request.cookies.get("Next-Locale")?.value || "en"
// Check if the current locale does not match the cookie locale, then update the cookie and rewrite the URL
if (currentLocale !== cookieLocale && cookieLocale !== undefined) {
// Update the cookie to match the current locale
const response = NextResponse.next()
response.cookies.set("Next-Locale", currentLocale, { path: "/" })
// Rewrite to include the default locale if not already present
if (!pathname.startsWith(`/${currentLocale}/`)) {
url.pathname = `/${currentLocale}${pathname}`
const response = NextResponse.rewrite(url)
response.cookies.set("Next-Locale", currentLocale, { path: "/" })
return response
}
// Special case: If URL explicitly starts with '/en/' (bascially call from /jp/ route to /en/),
// remove it and call I18nMiddleware
if (pathname.startsWith("/en/")) {
url.pathname = pathname.replace("/en", "")
NextResponse.rewrite(url)
return I18nMiddleware(request)
}
return response
}
return I18nMiddleware(request)
}
export const config = {
matcher: ["/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)"],
}
With this, the cookies should be always align with the current locale. But I found that I still have to explicitly tell nextjs Link component to include locale prefix in the href, otherwise it always navigates me to the pure href link even we include the locale props like below.
For example we are in: http://localhost:3000/jp/admin/settings/
export function PricingTable() {
const locale = useCurrentLocale()
console.log("locale : " + locale) < the out put is "locale: jp"
.....some code.....
<Link href={"/admin/settings/billing/"} locale={locale}>Click me</Link>
After click the Link component, it navigates me to the admin/settings/billing/
and changed the locale to en
...
And of course if we specify the locale prefix like, it works correctly and keeps the cookie fine as well.
<Link href={`/${locale}` + "/admin/settings/billing/} locale={locale}>
Am I missing something?
I'm not able to reproduce the issue using the example in the repo: https://github.com/QuiiBz/next-international/tree/main/examples/next-app
The steps I did:
/
, automatically redirected to /en
, cookie set to en
fr
, redirected to /fr
, cookie updated to fr
fr
, cookie is still fr
Does this work on your side, and if no could share the steps to reproduce in this example above? CodeSandbox has issues with cookies so that's why I'd like to reproduce outside of it.
Hello @QuiiBz
I experiment an issue which could be related to this one.
To reproduce:
Source code: https://github.com/Tirraa/dashboard_rtm
Maybe this is due to my middlewares chain?
I think the onClick={() => signIn('discord', { callbackUrl: ROUTES_ROOTS.DASHBOARD })}
on the Login button, is redirecting to Discord OAuth "Before" something in next-international which saves the user locale choice...
Btw: I also cheat one rewrite in my middleware, without having any issue about it.
Describe the bug Maybe related to #138 & #140, when I click nextjs
<Link>
component, it forces to go back to the default locale. To Reproduce Steps to reproduce the behavior:en
->fr
Link component
en
even we pass the locale prop in theExpected behavior Should keep the locale
About (please complete the following information):