I have a multi-lang site, I would like to make sure that single-lang sites do not have the "/{lang}
Unanswered
Long-legged ant posted this in #help-forum
Long-legged antOP
This is my file /src/app/[locale], i would like to make single langues site do not have have the "/locale" on the url. I will post you my middleware.ts, i m using i18, i wanted to make, i do a condition if locales.lenght === 1 (one lang), but i have an infinite url redirection loop. do you have an idea ? thank you !
4 Replies
Long-legged antOP
This is the middleware.ts :
import NodeCache from 'node-cache'
import { NextRequest, NextResponse } from 'next/server'
import createMiddleware from 'next-intl/middleware'
import { defineRouting } from 'next-intl/routing'
import { getCountryLanguages } from '@lib/utils/get-country-languages'
import { routing } from '@i18n/routing'
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|svg|favicon.ico|robots.txt|test.png|sitemaps).*)',
],
}
const cache = new NodeCache()
export async function middleware(request: NextRequest) {
const localesCacheKey = `locales`
let locales: string[] = cache.get(localesCacheKey) || []
const defaultLocaleCacheKey = `default-locale`
let defaultLocale: string = cache.get(defaultLocaleCacheKey)
if (locales.length === 0 || !defaultLocale) {
const languages = await getCountryLanguages(false)
locales = Object.keys(languages)
defaultLocale = locales[0]
cache.set(localesCacheKey, locales)
cache.set(defaultLocaleCacheKey, defaultLocale)
}
const handleI18nRouting = createMiddleware(
defineRouting({
locales: locales,
defaultLocale: defaultLocale,
pathnames: routing.pathnames,
})
)
const url = new URL(request.url)
const pathnameParts = url.pathname.split('/').filter(Boolean)
if (locales.length === 1) {
if (pathnameParts[0] === defaultLocale) {
const newPath = `/${pathnameParts.slice(1).join('/')}`
const cleanedPath = newPath === '/' ? '/' : newPath
if (url.pathname !== cleanedPath) {
const response = NextResponse.redirect(new URL(cleanedPath, url.origin))
response.cookies.set('redirected', 'true', { path: '/', maxAge: 5 }) // Empêcher une boucle
return response
}
}
}
const response = handleI18nRouting(request)
return response
}
@Long-legged ant This is the middleware.ts : import NodeCache from 'node-cache'
import { NextRequest, NextResponse } from 'next/server'
import createMiddleware from 'next-intl/middleware'
import { defineRouting } from 'next-intl/routing'
import { getCountryLanguages } from '@lib/utils/get-country-languages'
import { routing } from '@i18n/routing'
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|svg|favicon.ico|robots.txt|test.png|sitemaps).*)',
],
}
const cache = new NodeCache()
export async function middleware(request: NextRequest) {
const localesCacheKey = `locales`
let locales: string[] = cache.get(localesCacheKey) || []
const defaultLocaleCacheKey = `default-locale`
let defaultLocale: string = cache.get(defaultLocaleCacheKey)
if (locales.length === 0 || !defaultLocale) {
const languages = await getCountryLanguages(false)
locales = Object.keys(languages)
defaultLocale = locales[0]
cache.set(localesCacheKey, locales)
cache.set(defaultLocaleCacheKey, defaultLocale)
}
const handleI18nRouting = createMiddleware(
defineRouting({
locales: locales,
defaultLocale: defaultLocale,
pathnames: routing.pathnames,
})
)
const url = new URL(request.url)
const pathnameParts = url.pathname.split('/').filter(Boolean)
if (locales.length === 1) {
if (pathnameParts[0] === defaultLocale) {
const newPath = `/${pathnameParts.slice(1).join('/')}`
const cleanedPath = newPath === '/' ? '/' : newPath
if (url.pathname !== cleanedPath) {
const response = NextResponse.redirect(new URL(cleanedPath, url.origin))
response.cookies.set('redirected', 'true', { path: '/', maxAge: 5 }) // Empêcher une boucle
return response
}
}
}
const response = handleI18nRouting(request)
return response
}
It looks like you're using next-intl. If so, you just need to configure:
https://next-intl.dev/docs/getting-started/app-router/with-i18n-routing#i18n-routing
https://next-intl.dev/docs/getting-started/app-router/with-i18n-routing#i18n-routing
import {defineRouting} from 'next-intl/routing';
import {createNavigation} from 'next-intl/navigation';
export const routing = defineRouting({
// A list of all locales that are supported
locales: ['en', 'de'],
// Used when no locale matches
defaultLocale: 'en'
});
defaultLocale is the solution for your case.