Reputation: 463
I am migrating from Next.js /pages to /app and I have 2 languages en and es, the default language is en and the url structure is:
English
Spanish
But when integrating i18n on app router I created a [lang] folder, and after following any of these guides:
https://locize.com/blog/next-13-app-dir-i18n/
https://nextjs.org/docs/app/building-your-application/routing/internationalization
My structure on /app/[lang] is:
English
Spanish
If I go to example.com/ I will be redirected to example.com/en, if I don't solve this I will have problem with our current SEO because the majority of URLs will change.
Upvotes: 10
Views: 4810
Reputation: 1308
In my case, the solution was to add this if
statement
if (locale === "en") {
return NextResponse.rewrite(request.nextUrl);
} else {
return NextResponse.redirect(request.nextUrl);
}
in middleware.js
.
Complete file (default template copied from Next.js Docs):
import { NextResponse } from "next/server";
let locales = ['en', 'nl-NL', 'nl']
function getLocale(request) { ... }
export function middleware(request) {
const { pathname } = request.nextUrl
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
)
if (pathnameHasLocale) return
const locale = getLocale(request)
request.nextUrl.pathname = `/${locale}${pathname}`
if (locale === "en") {
return NextResponse.rewrite(request.nextUrl);
} else {
return NextResponse.redirect(request.nextUrl);
}
}
export const config = {
matcher: ['/((?!_next).*)'],
}
Upvotes: 0
Reputation: 41
This is the best and simple usage I found Doc - next-intl
Update the middle ware configuration like this.
import createMiddleware from 'next-intl/middleware'
export default createMiddleware({
locales: ['en', 'ja'],
defaultLocale: 'ja',
localePrefix: 'as-needed',
})
export const config = {
matcher: ['/((?!api|_next|.*\\..*).*)'],
}
Upvotes: 1
Reputation: 1
If you want to have this structure :
English
Spanish
example.com/es
example.com/es/blog/mi-articulo
2 options :
use rewrite api yourself
use next-international who do it for you
see docs
see the example here
and configure the middleware like this :
urlMappingStrategy: 'rewriteDefault',
import { createI18nMiddleware } from 'next-international/middleware';
import { NextRequest } from 'next/server';
const I18nMiddleware = createI18nMiddleware({
locales: ['en', 'es'],
defaultLocale: 'en',
urlMappingStrategy: 'rewriteDefault',
});
export function middleware(request: NextRequest) {
return I18nMiddleware(request);
}
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)'],
};
Upvotes: 0
Reputation: 86
Checkout the rewrite api of NextResponse.
So in the document of nextjs, the return value of the middleware is a Response.redirect(request.nextUrl)
which redirect the client to the url contains locale information.
Replace it with NextResponse.rewrite(request.nextUrl)
, the new url will be accepted to server internally only, without affecting client side. Kind of like a 'proxy' in some way.
* NextResponse can be imported from next/server.
Upvotes: 4