Files
manoon-headless/src/app/sitemap.ts
Unchained f6609f07d7 feat: implement programmatic SEO solutions hub
- Add /solutions hub page with 10 category cards
- Add /solutions/by-concern directory page
- Add /solutions/by-oil directory page
- Add Solutions section to Footer with navigation links
- Add Breadcrumb component for solution pages
- Add translations for all solution pages (sr, en, de, fr)
- Fix ExitIntentDetector JSON parsing error
- Update sitemap with solution pages
- Create 3 sample solution pages with data files
2026-04-05 05:21:57 +02:00

141 lines
4.2 KiB
TypeScript

import { MetadataRoute } from "next";
import { getProducts, filterOutBundles } from "@/lib/saleor";
import { getAllOilForConcernPages } from "@/lib/programmatic-seo/dataLoader";
import { SUPPORTED_LOCALES, type Locale } from "@/lib/i18n/locales";
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://manoonoils.com";
interface SitemapEntry {
url: string;
lastModified: Date;
changeFrequency: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
priority: number;
alternates?: {
languages?: Record<string, string>;
};
}
export default async function sitemap(): Promise<SitemapEntry[]> {
let products: any[] = [];
try {
products = await getProducts("SR", 100);
} catch (e) {
console.log("Failed to fetch products for sitemap during build");
}
const staticPages: SitemapEntry[] = [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: "daily",
priority: 1,
alternates: {
languages: Object.fromEntries(
SUPPORTED_LOCALES.map((locale) => [locale, locale === "sr" ? baseUrl : `${baseUrl}/${locale}`])
),
},
},
{
url: `${baseUrl}/products`,
lastModified: new Date(),
changeFrequency: "daily",
priority: 0.9,
alternates: {
languages: Object.fromEntries(
SUPPORTED_LOCALES.map((locale) => [locale, locale === "sr" ? `${baseUrl}/products` : `${baseUrl}/${locale}/products`])
),
},
},
{
url: `${baseUrl}/about`,
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.6,
alternates: {
languages: Object.fromEntries(
SUPPORTED_LOCALES.map((locale) => [locale, locale === "sr" ? `${baseUrl}/about` : `${baseUrl}/${locale}/about`])
),
},
},
{
url: `${baseUrl}/contact`,
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.6,
alternates: {
languages: Object.fromEntries(
SUPPORTED_LOCALES.map((locale) => [locale, locale === "sr" ? `${baseUrl}/contact` : `${baseUrl}/${locale}/contact`])
),
},
},
{
url: `${baseUrl}/checkout`,
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.5,
alternates: {
languages: Object.fromEntries(
SUPPORTED_LOCALES.map((locale) => [locale, locale === "sr" ? `${baseUrl}/checkout` : `${baseUrl}/${locale}/checkout`])
),
},
},
];
const filteredProducts = filterOutBundles(products);
const productUrls: SitemapEntry[] = [];
for (const product of filteredProducts) {
const hreflangs: Record<string, string> = {};
for (const locale of SUPPORTED_LOCALES) {
const path = locale === "sr" ? `/products/${product.slug}` : `/${locale}/products/${product.slug}`;
hreflangs[locale] = `${baseUrl}${path}`;
}
for (const locale of SUPPORTED_LOCALES) {
const localePrefix = locale === "sr" ? "" : `/${locale}`;
productUrls.push({
url: `${baseUrl}${localePrefix}/products/${product.slug}`,
lastModified: new Date(),
changeFrequency: "weekly",
priority: 0.8,
alternates: {
languages: hreflangs,
},
});
}
}
let solutionPages: any[] = [];
try {
solutionPages = await getAllOilForConcernPages();
} catch (e) {
console.log("Failed to fetch solution pages for sitemap during build");
}
const solutionUrls: SitemapEntry[] = [];
for (const page of solutionPages) {
const hreflangs: Record<string, string> = {};
for (const locale of SUPPORTED_LOCALES) {
const path = locale === "sr" ? `/solutions/${page.slug}` : `/${locale}/solutions/${page.slug}`;
hreflangs[locale] = `${baseUrl}${path}`;
}
for (const locale of SUPPORTED_LOCALES) {
const localePrefix = locale === "sr" ? "" : `/${locale}`;
solutionUrls.push({
url: `${baseUrl}${localePrefix}/solutions/${page.slug}`,
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.7,
alternates: {
languages: hreflangs,
},
});
}
}
return [...staticPages, ...productUrls, ...solutionUrls];
}