feat: implement programmatic SEO for solutions pages
- Add 10 oil-for-concern solution pages with localized slugs - Support 4 languages: sr, en, de, fr with proper canonical URLs - Add solutions hub, by-concern, and by-oil directory pages - Filter bundle products from solutions pages - Add hideLangSwitcher prop to Header component - Update translations for all languages - Fix canonical URLs to include locale prefix
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import {
|
||||
getOilForConcernPage,
|
||||
getOilForConcernPageBySlug,
|
||||
getAllSolutionSlugs,
|
||||
getLocalizedString,
|
||||
getLocalizedKeywords
|
||||
} from "@/lib/programmatic-seo/dataLoader";
|
||||
import { getProducts } from "@/lib/saleor";
|
||||
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";
|
||||
@@ -24,7 +24,7 @@ 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 getOilForConcernPage(slug);
|
||||
const page = await getOilForConcernPageBySlug(slug, validLocale);
|
||||
|
||||
if (!page) {
|
||||
return {
|
||||
@@ -36,7 +36,7 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
|
||||
const metaDescription = getLocalizedString(page.metaDescription, validLocale);
|
||||
const keywords = getLocalizedKeywords(page.seoKeywords, validLocale);
|
||||
const localePrefix = validLocale === DEFAULT_LOCALE ? "" : `/${validLocale}`;
|
||||
const canonicalUrl = `${baseUrl}${localePrefix}/solutions/${page.slug}`;
|
||||
const canonicalUrl = `${baseUrl}${localePrefix}/solutions/${page.localizedSlugs[validLocale as "sr" | "en" | "de" | "fr"]}`;
|
||||
|
||||
return {
|
||||
title: metaTitle,
|
||||
@@ -45,10 +45,10 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
|
||||
alternates: {
|
||||
canonical: canonicalUrl,
|
||||
languages: {
|
||||
"sr": `${baseUrl}/solutions/${page.slug}`,
|
||||
"en": `${baseUrl}/en/solutions/${page.slug}`,
|
||||
"de": `${baseUrl}/de/solutions/${page.slug}`,
|
||||
"fr": `${baseUrl}/fr/solutions/${page.slug}`,
|
||||
"sr": `${baseUrl}/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: {
|
||||
@@ -76,15 +76,18 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
|
||||
export default async function SolutionPage({ params }: PageProps) {
|
||||
const { locale, slug } = await params;
|
||||
const validLocale = isValidLocale(locale) ? locale : DEFAULT_LOCALE;
|
||||
const [page, products] = await Promise.all([
|
||||
getOilForConcernPage(slug),
|
||||
getProducts(validLocale === "sr" ? "SR" : "EN", 4)
|
||||
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 === DEFAULT_LOCALE ? "" : `/${validLocale}`;
|
||||
|
||||
const faqQuestions = page.faqs.map((faq) => ({
|
||||
|
||||
Reference in New Issue
Block a user