Files
octto-engenharia/frontend/middleware.ts

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|.*\\..*).*)',
],
};