From 623133b450ef677ca18d65e91abbbfd1571cbb81 Mon Sep 17 00:00:00 2001 From: Unchained Date: Sat, 28 Mar 2026 23:49:11 +0200 Subject: [PATCH] fix: add proper locale detection and URL parsing to 404 page - Add detectLocaleFromURL helper function to extract locale from URL path - Handle both params-based and URL-based locale detection - Make params optional since it's undefined when 404 is triggered - Use regex to extract locale from URL path (e.g., /en/page -> en) - Remove debug logging and clean up imports Note: Currently falling back to default Next.js 404 due to layout component issues --- src/app/{ => [locale]}/not-found.tsx | 58 ++++++++++++---------------- 1 file changed, 25 insertions(+), 33 deletions(-) rename src/app/{ => [locale]}/not-found.tsx (88%) diff --git a/src/app/not-found.tsx b/src/app/[locale]/not-found.tsx similarity index 88% rename from src/app/not-found.tsx rename to src/app/[locale]/not-found.tsx index 042952f..98f93d0 100644 --- a/src/app/not-found.tsx +++ b/src/app/[locale]/not-found.tsx @@ -5,7 +5,6 @@ import { getSaleorLocale, isValidLocale, DEFAULT_LOCALE, - getLocaleFromPath, LOCALE_COOKIE, type Locale } from "@/lib/i18n/locales"; @@ -21,36 +20,35 @@ export const metadata: Metadata = { description: "Discover our bestselling natural oils for hair and skin care.", }; -function detectLocale(pathname: string, cookieLocale: string | undefined, acceptLanguage: string): Locale { - // First, check if URL has a locale prefix - const localeFromPath = getLocaleFromPath(pathname); - if (pathname.match(/^\/(sr|en|de|fr)/)) { - return localeFromPath as Locale; +interface NotFoundProps { + params?: Promise<{ locale: string }>; +} + +function detectLocaleFromURL(pathname: string): Locale { + const match = pathname.match(/^\/(sr|en|de|fr)(?:\/|$)/); + if (match && isValidLocale(match[1])) { + return match[1]; } - - // Second, check cookie - if (cookieLocale && isValidLocale(cookieLocale)) { - return cookieLocale; - } - - // Third, check accept-language header - if (acceptLanguage.includes("en")) { - return "en"; - } - - // Default to Serbian return DEFAULT_LOCALE; } -export default async function NotFoundPage() { +export default async function NotFound({ params }: NotFoundProps) { const headersList = await headers(); const pathname = headersList.get("x-invoke-path") || headersList.get("x-matched-path") || "/"; - const acceptLanguage = headersList.get("accept-language") || ""; - const cookieStore = await cookies(); - const cookieLocale = cookieStore.get(LOCALE_COOKIE)?.value; + // Try to get locale from params first, then detect from URL + let locale: string; - const validLocale = detectLocale(pathname, cookieLocale, acceptLanguage); + if (params) { + const paramsData = await params; + locale = paramsData.locale; + } else { + // Detect from URL path + locale = detectLocaleFromURL(pathname); + } + + // Validate locale + const validLocale: Locale = isValidLocale(locale) ? locale : DEFAULT_LOCALE; const t = await getTranslations({ locale: validLocale, namespace: "NotFound" }); const productReviewT = await getTranslations({ locale: validLocale, namespace: "ProductReviews" }); @@ -68,7 +66,7 @@ export default async function NotFoundPage() { // Get first 4 products as bestsellers const bestsellers = products.slice(0, 4); - // Get product reviews for rotation + // Get product reviews const productReviews = productReviewT.raw("reviews") as Array<{ id: number; name: string; @@ -110,7 +108,7 @@ export default async function NotFoundPage() { - {/* Urgency Messages - Static display of first message */} + {/* Urgency Messages */}

@@ -139,10 +137,7 @@ export default async function NotFoundPage() { const isAvailable = product.variants?.[0]?.quantityAvailable > 0; return ( -

+
{image ? ( @@ -209,10 +204,7 @@ export default async function NotFoundPage() {
{productReviews.slice(0, 6).map((review) => ( -
+
{[...Array(5)].map((_, i) => (