import createMiddleware from 'next-intl/middleware'; import { NextRequest } from 'next/server'; // Create the internationalization middleware const intlMiddleware = createMiddleware({ // A list of all locales that are supported locales: ['en', 'de'], // Used when no locale matches defaultLocale: 'en', }); export default function middleware(request: NextRequest) { const { method, url, headers } = request; // Build header object for logging const headerObj: Record = {}; headers.forEach((value, key) => { headerObj[key] = value; }); // Defensive URL correction for internal container leakage (0.0.0.0, klz-app, localhost) // This prevents hydration mismatches and host poisoning in generated links/metadata. const urlObj = new URL(url); const internalHosts = ['0.0.0.0', 'klz-app', 'localhost', '127.0.0.1']; let effectiveRequest = request; if (internalHosts.includes(urlObj.hostname)) { const proto = headers.get('x-forwarded-proto') || 'https'; // Prioritize x-forwarded-host (passed by Traefik) over the local Host header const hostHeader = headers.get('x-forwarded-host') || headers.get('host') || 'testing.klz-cables.com'; hostHeader.split(':'); urlObj.protocol = proto; // urlObj.hostname = publicHostname; // Don't rewrite hostname yet as it breaks internal fetches in dev // urlObj.port = ''; // DON'T clear internal port (3000) anymore effectiveRequest = new NextRequest(urlObj, { headers: request.headers, method: request.method, body: request.body, }); console.log( `🛡️ Middleware: Fixed internal URL leak: ${url} -> ${urlObj.toString()} | Proto: ${proto} | Host: ${hostHeader}`, ); } try { // Apply internationalization middleware const response = intlMiddleware(effectiveRequest); return response; } catch (error) { console.error( `Request failed: method=${method} url=${url} headers=${JSON.stringify(headerObj)}`, error, ); throw error; } } export const config = { // Match only internationalized pathnames matcher: ['/((?!api|_next|_vercel|stats|errors|health|.*\\..*).*)', '/', '/(de|en)/:path*'], };