92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import type { NextRequest } from 'next/server';
|
|
|
|
// Definir locales diretamente aqui para evitar problemas com edge runtime
|
|
const locales = ['pt', 'en', 'es'] as const;
|
|
type Locale = (typeof locales)[number];
|
|
const defaultLocale: Locale = 'pt';
|
|
|
|
// Rotas que NÃO devem ter prefixo de idioma
|
|
const publicPaths = ['/api', '/admin', '/acesso', '/_next', '/favicon', '/icon'];
|
|
|
|
function getLocaleFromPath(pathname: string): Locale | null {
|
|
const segments = pathname.split('/');
|
|
const possibleLocale = segments[1];
|
|
|
|
if (locales.includes(possibleLocale as Locale)) {
|
|
return possibleLocale as Locale;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getLocaleFromHeader(request: NextRequest): Locale {
|
|
const acceptLanguage = request.headers.get('accept-language') || '';
|
|
|
|
// Verificar se o navegador prefere algum dos nossos idiomas
|
|
for (const locale of locales) {
|
|
if (acceptLanguage.toLowerCase().includes(locale)) {
|
|
return locale;
|
|
}
|
|
}
|
|
|
|
return defaultLocale;
|
|
}
|
|
|
|
export function middleware(request: NextRequest) {
|
|
const { pathname } = request.nextUrl;
|
|
|
|
// Ignorar rotas públicas (API, admin, etc)
|
|
if (publicPaths.some(path => pathname.startsWith(path))) {
|
|
return NextResponse.next();
|
|
}
|
|
|
|
// Ignorar arquivos estáticos
|
|
if (pathname.includes('.')) {
|
|
return NextResponse.next();
|
|
}
|
|
|
|
// Verificar se já tem locale na URL
|
|
const pathnameLocale = getLocaleFromPath(pathname);
|
|
|
|
if (pathnameLocale) {
|
|
// URL já tem locale, continuar
|
|
const response = NextResponse.next();
|
|
response.headers.set('x-locale', pathnameLocale);
|
|
return response;
|
|
}
|
|
|
|
// Verificar cookie de preferência
|
|
const cookieLocale = request.cookies.get('locale')?.value as Locale | undefined;
|
|
|
|
// Determinar locale: cookie > navegador > padrão
|
|
let locale: Locale;
|
|
|
|
if (cookieLocale && locales.includes(cookieLocale)) {
|
|
locale = cookieLocale;
|
|
} else {
|
|
locale = getLocaleFromHeader(request);
|
|
}
|
|
|
|
// Se for o locale padrão (pt), não adiciona prefixo na URL
|
|
// Isso mantém as URLs limpas: occto.com.br/ ao invés de occto.com.br/pt/
|
|
if (locale === defaultLocale) {
|
|
const response = NextResponse.next();
|
|
response.headers.set('x-locale', locale);
|
|
return response;
|
|
}
|
|
|
|
// Redirecionar para URL com locale
|
|
const newUrl = new URL(`/${locale}${pathname}`, request.url);
|
|
newUrl.search = request.nextUrl.search;
|
|
|
|
return NextResponse.redirect(newUrl);
|
|
}
|
|
|
|
export const config = {
|
|
matcher: [
|
|
// Todas as rotas exceto arquivos estáticos
|
|
'/((?!_next/static|_next/image|favicon.ico|icon.svg|.*\\..*).*)',
|
|
],
|
|
};
|