feat: CMS com limites de caracteres, traduções auto e painel de notificações
This commit is contained in:
91
frontend/middleware.ts
Normal file
91
frontend/middleware.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
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|.*\\..*).*)',
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user