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
This commit is contained in:
79
src/lib/programmatic-seo/dataLoader.ts
Normal file
79
src/lib/programmatic-seo/dataLoader.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { readFile } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import type {
|
||||
OilForConcernPage,
|
||||
LocalizedSEOKeywords
|
||||
} from "./types";
|
||||
|
||||
const DATA_DIR = join(process.cwd(), "data");
|
||||
|
||||
export function getLocalizedString(
|
||||
localized: { sr: string; en: string; de: string; fr: string },
|
||||
locale: string
|
||||
): string {
|
||||
return localized[locale as keyof typeof localized] || localized.en;
|
||||
}
|
||||
|
||||
export function getLocalizedArray(
|
||||
localized: { sr: string[]; en: string[]; de: string[]; fr: string[] },
|
||||
locale: string
|
||||
): string[] {
|
||||
return localized[locale as keyof typeof localized] || localized.en;
|
||||
}
|
||||
|
||||
export function getLocalizedKeywords(
|
||||
seoKeywords: LocalizedSEOKeywords,
|
||||
locale: string
|
||||
): string[] {
|
||||
const keywords = seoKeywords[locale as keyof LocalizedSEOKeywords] || seoKeywords.en;
|
||||
return [...keywords.primary, ...keywords.secondary, ...keywords.longTail];
|
||||
}
|
||||
|
||||
export async function getOilForConcernPage(slug: string): Promise<OilForConcernPage | null> {
|
||||
try {
|
||||
const filePath = join(DATA_DIR, "oil-for-concern", `${slug}.json`);
|
||||
const content = await readFile(filePath, "utf-8");
|
||||
return JSON.parse(content) as OilForConcernPage;
|
||||
} catch (error) {
|
||||
console.error(`Failed to load oil-for-concern page: ${slug}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAllOilForConcernSlugs(): Promise<string[]> {
|
||||
try {
|
||||
const { readdir } = await import("fs/promises");
|
||||
const dirPath = join(DATA_DIR, "oil-for-concern");
|
||||
const files = await readdir(dirPath);
|
||||
return files
|
||||
.filter((file) => file.endsWith(".json"))
|
||||
.map((file) => file.replace(".json", ""));
|
||||
} catch (error) {
|
||||
console.error("Failed to load oil-for-concern slugs:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAllOilForConcernPages(): Promise<OilForConcernPage[]> {
|
||||
const slugs = await getAllOilForConcernSlugs();
|
||||
const pages = await Promise.all(
|
||||
slugs.map((slug) => getOilForConcernPage(slug))
|
||||
);
|
||||
return pages.filter((page): page is OilForConcernPage => page !== null);
|
||||
}
|
||||
|
||||
export async function getAllSolutionSlugs(): Promise<Array<{ locale: string; slug: string }>> {
|
||||
const slugs = await getAllOilForConcernSlugs();
|
||||
const result: Array<{ locale: string; slug: string }> = [];
|
||||
|
||||
for (const slug of slugs) {
|
||||
for (const locale of ["sr", "en", "de", "fr"] as const) {
|
||||
result.push({
|
||||
locale,
|
||||
slug
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user