Skip to content

Commit

Permalink
fix: create proper redirect for non-locale paths
Browse files Browse the repository at this point in the history
When the path didn’t have a locale but the `localePrefix` was set to
`always` we let next-intl redirect the user to
`/${defaultLocale}/${path}`. On visit we then rewrote that to
`/${defaultPathLocale}/${path}` and redirect the client again.

This makes sure we do the redirect ourselves skipping an extra redirect
  • Loading branch information
mvantellingen committed Jan 22, 2024
1 parent c3358ea commit 667d8c4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/violet-otters-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@labdigital/next-intl-custom-paths": minor
---

Fix double redirect bug when path has no locale
3 changes: 3 additions & 0 deletions src/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe("rewrite request for ", () => {

const result = processRequest(request, {
defaultLocale: "en-US",
localePrefix: "as-needed",
localePrefixForRoot: "as-needed",
pathToLocaleMapping: {
en: "en-US",
Expand All @@ -33,6 +34,7 @@ describe("rewrite request for ", () => {

it.each([
["http://example.org/", "/en"],
["http://example.org/foobar", "/en/foobar"],
["http://example.org/en-US", "/en"],
["http://example.org/en-US/", "/en"],
["http://example.org/en-US/foobar", "/en/foobar"],
Expand All @@ -43,6 +45,7 @@ describe("rewrite request for ", () => {

const result = processRequest(request, {
defaultLocale: "en-US",
localePrefix: "always",
localePrefixForRoot: "always",
pathToLocaleMapping: {
en: "en-US",
Expand Down
17 changes: 17 additions & 0 deletions src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export function createNextIntlCustomPathMiddleware<Locales extends AllLocales>({

const info = processRequest(request, {
defaultLocale,
localePrefix: nextIntlMiddlewareOptions.localePrefix,
localePrefixForRoot,
pathToLocaleMapping,
});
Expand All @@ -61,6 +62,7 @@ type processRequestResult = {

type processRequestArgs<Locales extends AllLocales> = {
defaultLocale: Locales[number];
localePrefix?: "always" | "as-needed" | "never";
localePrefixForRoot?: "always" | "as-needed";
pathToLocaleMapping: Record<string, Locales[number]>;
};
Expand All @@ -69,6 +71,7 @@ export const processRequest = <Locales extends AllLocales>(
request: NextRequest,
{
defaultLocale,
localePrefix,
localePrefixForRoot,
pathToLocaleMapping,
}: processRequestArgs<Locales>
Expand Down Expand Up @@ -132,8 +135,22 @@ export const processRequest = <Locales extends AllLocales>(
targetURL: request.nextUrl,
};
}

// if pathLocale is not a path locale or locale (e.g. /foo) then the
// next-intl will redirect to the default locale (/nl-NL). However we want
// to intercept that and redirect to the localePath (/nl) instead. OTherwise
// we get a double redirect (e.g. /foo -> /nl-NL/foo -> /nl/foo)
const locale = pathToLocale(pathLocale, pathToLocaleMapping);
if (pathLocale && locale === undefined && localePrefix === "always") {
request.nextUrl.pathname = `/${defaultLocalePath}` + request.nextUrl.pathname;
return {
statusCode: 308,
targetURL: request.nextUrl,
};
}

// If there is a locale in the path and we have mapped that to a locale path
// then just update the url to the locale path
if (pathLocale && locale && request.nextUrl.pathname !== "/") {
request.nextUrl.pathname = request.nextUrl.pathname.replace(
new RegExp(`^/${pathLocale}`, "i"),
Expand Down

0 comments on commit 667d8c4

Please sign in to comment.