The i18n architecture (config, routing, translation files, locale pages) was already built but non-functional due to three missing pieces: 1. next-intl not listed in package.json 2. middleware.ts not using createMiddleware from next-intl/middleware 3. next.config.js not wrapped with createNextIntlPlugin Co-Authored-By: Paperclip <noreply@paperclip.ing>
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import { NextResponse, type NextRequest } from 'next/server';
|
|
import createIntlMiddleware from 'next-intl/middleware';
|
|
import { routing } from '@/i18n/routing';
|
|
|
|
const intlMiddleware = createIntlMiddleware(routing);
|
|
|
|
const publicPaths = ['/login', '/register', '/search', '/auth/callback'];
|
|
const publicExactPaths = ['/'];
|
|
const authOnlyPaths = ['/login', '/register'];
|
|
|
|
function isPublicPath(pathname: string): boolean {
|
|
return (
|
|
publicExactPaths.includes(pathname) ||
|
|
publicPaths.some((path) => pathname.startsWith(path))
|
|
);
|
|
}
|
|
|
|
function stripLocale(pathname: string): string {
|
|
const localePattern = /^\/(vi|en)(\/|$)/;
|
|
return pathname.replace(localePattern, '/') || '/';
|
|
}
|
|
|
|
export function middleware(request: NextRequest) {
|
|
const { pathname } = request.nextUrl;
|
|
const strippedPath = stripLocale(pathname);
|
|
|
|
const hasAuthCookie = request.cookies.has('goodgo_authenticated');
|
|
|
|
if (!isPublicPath(strippedPath) && !hasAuthCookie) {
|
|
const loginUrl = new URL('/login', request.url);
|
|
loginUrl.searchParams.set('redirect', strippedPath);
|
|
return NextResponse.redirect(loginUrl);
|
|
}
|
|
|
|
const isAuthOnly = authOnlyPaths.some((path) =>
|
|
strippedPath.startsWith(path),
|
|
);
|
|
if (isAuthOnly && hasAuthCookie) {
|
|
return NextResponse.redirect(new URL('/dashboard', request.url));
|
|
}
|
|
|
|
return intlMiddleware(request);
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ['/((?!api|_next/static|_next/image|favicon.ico|public).*)'],
|
|
};
|