Files
manoon-headless/src/app/[locale]/solutions/[slug]/page.tsx
T
Unchained 14d7a3e21a fix: ensure canonical URLs match actual URLs with locale prefix
- Update [slug]/page.tsx to always include locale in canonical URL
- Update by-oil/page.tsx to use consistent locale prefix
- Update by-concern/page.tsx to use consistent locale prefix
- All canonical URLs now match actual URLs: /{locale}/solutions/{slug}
2026-04-09 10:50:54 +02:00

110 lines
3.3 KiB
TypeScript

import {
getOilForConcernPageBySlug,
getAllSolutionSlugs,
getLocalizedString,
getLocalizedKeywords
} from "@/lib/programmatic-seo/dataLoader";
import { getProducts, filterOutBundles } from "@/lib/saleor";
import { OilForConcernPageTemplate } from "@/components/programmatic-seo/OilForConcernPage";
import { FAQSchema } from "@/components/programmatic-seo/FAQSchema";
import { isValidLocale, DEFAULT_LOCALE, type Locale } from "@/lib/i18n/locales";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
interface PageProps {
params: Promise<{ locale: string; slug: string }>;
}
export async function generateStaticParams() {
return await getAllSolutionSlugs();
}
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://manoonoils.com";
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { locale, slug } = await params;
const validLocale = isValidLocale(locale) ? locale : DEFAULT_LOCALE;
const page = await getOilForConcernPageBySlug(slug, validLocale);
if (!page) {
return {
title: "Page Not Found",
};
}
const metaTitle = getLocalizedString(page.metaTitle, validLocale);
const metaDescription = getLocalizedString(page.metaDescription, validLocale);
const keywords = getLocalizedKeywords(page.seoKeywords, validLocale);
const localePrefix = `/${validLocale}`;
const canonicalUrl = `${baseUrl}${localePrefix}/solutions/${slug}`;
return {
title: metaTitle,
description: metaDescription,
keywords: keywords.join(", "),
alternates: {
canonical: canonicalUrl,
languages: {
"sr": `${baseUrl}/sr/solutions/${page.localizedSlugs.sr}`,
"en": `${baseUrl}/en/solutions/${page.localizedSlugs.en}`,
"de": `${baseUrl}/de/solutions/${page.localizedSlugs.de}`,
"fr": `${baseUrl}/fr/solutions/${page.localizedSlugs.fr}`,
},
},
openGraph: {
title: metaTitle,
description: metaDescription,
type: "article",
url: canonicalUrl,
images: [{
url: `${baseUrl}/og-image.jpg`,
width: 1200,
height: 630,
alt: metaTitle,
}],
locale: validLocale,
},
twitter: {
card: "summary_large_image",
title: metaTitle,
description: metaDescription,
images: [`${baseUrl}/og-image.jpg`],
},
};
}
export default async function SolutionPage({ params }: PageProps) {
const { locale, slug } = await params;
const validLocale = isValidLocale(locale) ? locale : DEFAULT_LOCALE;
const [page, allProducts] = await Promise.all([
getOilForConcernPageBySlug(slug, validLocale),
getProducts(validLocale === "sr" ? "SR" : "EN", 20)
]);
if (!page) {
notFound();
}
// Filter out bundle products (2x, 3x versions) - only show original 4 products
const products = filterOutBundles(allProducts).slice(0, 4);
const basePath = `/${validLocale}`;
const faqQuestions = page.faqs.map((faq) => ({
question: getLocalizedString(faq.question, validLocale),
answer: getLocalizedString(faq.answer, validLocale),
}));
return (
<>
<FAQSchema questions={faqQuestions} />
<OilForConcernPageTemplate
page={page}
locale={validLocale as Locale}
basePath={basePath}
products={products}
/>
</>
);
}