67 lines
2.6 KiB
JavaScript
67 lines
2.6 KiB
JavaScript
import { isValidLocale, LOCALE_COOKIE_NAME, negotiateLocale } from '../i18n/index.js';
|
|
/**
|
|
* First path segment of a URL pathname, or '' for root.
|
|
* '/pl/o-nas' → 'pl', '/o-nas' → 'o-nas', '/' → ''.
|
|
*/ function firstSegment(pathname) {
|
|
return pathname.split('/').filter(Boolean)[0] ?? '';
|
|
}
|
|
/**
|
|
* Builds locale-routing logic for Next.js middleware.
|
|
*
|
|
* Behavior:
|
|
* - path already starts with a valid locale (/pl/...) → pass through
|
|
* - any other path (/, /o-nas) → redirect to /{locale}{path}, where locale
|
|
* comes from negotiateLocale (cookie → Accept-Language → default)
|
|
* - the chosen locale is written to a cookie so the next visit is stable
|
|
*
|
|
* The plugin returns a decision; the thin next-middleware.ts in the client project
|
|
* turns it into a NextResponse. This keeps all logic in the plugin while
|
|
* respecting that next-middleware.ts must physically live in the client app.
|
|
*
|
|
* @example
|
|
* // next-middleware.ts (client project) — one wiring file, no logic:
|
|
* import { NextResponse } from 'next/server'
|
|
* import { localeMiddleware } from './ipal.middleware' // created from this factory
|
|
* export function middleware(req) {
|
|
* const r = localeMiddleware(req)
|
|
* if (r.type === 'next') return NextResponse.next()
|
|
* const res = NextResponse.redirect(r.location)
|
|
* res.cookies.set(r.cookie.name, r.cookie.value)
|
|
* return res
|
|
* }
|
|
*/ export function createLocaleMiddleware({ config, cookieName = LOCALE_COOKIE_NAME }) {
|
|
return function localeMiddleware(request) {
|
|
const { pathname } = request.nextUrl;
|
|
// Already locale-prefixed → nothing to do
|
|
if (isValidLocale(firstSegment(pathname), config)) {
|
|
return {
|
|
type: 'next'
|
|
};
|
|
}
|
|
// Resolve the locale to use
|
|
const locale = negotiateLocale({
|
|
acceptLanguage: request.headers.get('accept-language'),
|
|
config,
|
|
cookieLocale: request.cookies.get(cookieName)?.value ?? null
|
|
});
|
|
// Redirect to the locale-prefixed path, preserving the rest
|
|
const url = request.nextUrl.clone();
|
|
url.pathname = `/${locale}${pathname === '/' ? '' : pathname}`;
|
|
return {
|
|
type: 'redirect',
|
|
cookie: {
|
|
name: cookieName,
|
|
value: locale
|
|
},
|
|
location: url.toString()
|
|
};
|
|
};
|
|
}
|
|
/**
|
|
* Default Next.js middleware matcher: run on everything except API routes, the
|
|
* admin panel, Next internals, and files with an extension (static assets).
|
|
*/ export const DEFAULT_MIDDLEWARE_MATCHER = [
|
|
'/((?!api|admin|_next|.*\\..*).*)'
|
|
];
|
|
|
|
//# sourceMappingURL=localeMiddleware.js.map
|