From 5b33ede980d60662b0fe2e47d7f30e6cc660b070 Mon Sep 17 00:00:00 2001 From: Unchained Date: Sat, 28 Mar 2026 22:44:41 +0200 Subject: [PATCH] fix: make 404 page fully server-side compatible - Remove TrustBadges and UrgencyMessages client components - Convert to pure Server Component with no client dependencies - Remove onClick handlers and use div elements instead of buttons - Simplify product card hover to use CSS-only transitions - Remove [locale]/not-found.tsx (root one handles all locales) - Static display of first urgency message instead of rotation --- src/app/[locale]/not-found.tsx | 279 --------------------------------- src/app/not-found.tsx | 70 ++++----- 2 files changed, 27 insertions(+), 322 deletions(-) delete mode 100644 src/app/[locale]/not-found.tsx diff --git a/src/app/[locale]/not-found.tsx b/src/app/[locale]/not-found.tsx deleted file mode 100644 index 5616de8..0000000 --- a/src/app/[locale]/not-found.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import { Metadata } from "next"; -import { getTranslations } from "next-intl/server"; -import { getProducts, getProductImage, getProductPrice } from "@/lib/saleor"; -import { getSaleorLocale, isValidLocale, DEFAULT_LOCALE } from "@/lib/i18n/locales"; -import type { Locale } from "@/lib/i18n/locales"; -import type { Product } from "@/types/saleor"; -import Link from "next/link"; -import Image from "next/image"; -import { Star, ArrowRight } from "lucide-react"; -import TrustBadges from "@/components/home/TrustBadges"; -import UrgencyMessages from "@/components/404/UrgencyMessages"; -import { headers } from "next/headers"; - -export const metadata: Metadata = { - title: "Page Not Found | ManoonOils", - description: "Discover our bestselling natural oils for hair and skin care.", -}; - -export default async function NotFoundPage() { - // Get locale from URL path - const headersList = await headers(); - const pathname = headersList.get("x-invoke-path") || headersList.get("x-matched-path") || "/"; - - // Extract locale from path (e.g., /en/products → en, /sr/products → sr) - const pathSegments = pathname.split("/").filter(Boolean); - const potentialLocale = pathSegments[0]; - const validLocale = isValidLocale(potentialLocale) ? potentialLocale : DEFAULT_LOCALE; - - const t = await getTranslations({ locale: validLocale, namespace: "NotFound" }); - const productReviewT = await getTranslations({ locale: validLocale, namespace: "ProductReviews" }); - - const saleorLocale = getSaleorLocale(validLocale as Locale); - - // Fetch products - let products: Product[] = []; - try { - products = await getProducts(saleorLocale); - } catch (error) { - console.error("Error fetching products for 404 page:", error); - } - - // Get first 4 products as bestsellers - const bestsellers = products.slice(0, 4); - - // Get product reviews for rotation - const productReviews = productReviewT.raw("reviews") as Array<{ - id: number; - name: string; - location: string; - text: string; - rating: number; - }>; - - // Track 404 page view via OpenPanel (client-side will handle this) - const referer = headersList.get("referer") || ""; - - return ( -
- {/* Hero Section */} -
-
-
-

- {t("title")} -

-

- {t("subtitle")} -

- - - {t("shopBestsellers")} - - -
-
-
- - {/* Trust Badges */} - - - {/* Urgency Messages */} - - - {/* Bestsellers Section */} -
-
-
- - Popular - -

- {t("bestsellersTitle")} -

-
- - {bestsellers.length > 0 ? ( -
- {bestsellers.map((product, index) => { - const image = getProductImage(product); - const price = getProductPrice(product); - const isAvailable = product.variants?.[0]?.quantityAvailable > 0; - - return ( -
- -
- {image ? ( - {product.name} - ) : ( -
- No Image -
- )} - - {!isAvailable && ( -
- - Out of Stock - -
- )} - -
- -
-
- -
-

- {product.name} -

-

- {price || "Contact for price"} -

-
- -
- ); - })} -
- ) : ( -
-

No products available at the moment.

-
- )} -
-
- - {/* Testimonials Section */} -
-
-
- - Testimonials - -

- {t("testimonialsTitle")} -

-
- -
- {productReviews.slice(0, 6).map((review, index) => ( -
-
- {[...Array(5)].map((_, i) => ( - - ))} -
-

- “{review.text}” -

-
-
- {review.name.charAt(0)} -
-
-

{review.name}

-

{review.location}

-
-
-
- ))} -
-
-
- - {/* Final CTA Section */} -
-
-
-

- {t("finalCTATitle")} -

-

- {t("finalCTASubtitle")} -

- - - {t("viewAllProducts")} - - -
-
-
- - {/* OpenPanel Tracking Script */} -