This commit is contained in:
Andras Schmelczer 2026-05-14 08:09:19 +01:00
parent a8165249a4
commit a4103b0896
64 changed files with 5376 additions and 3832 deletions

View file

@ -1,5 +1,5 @@
import i18n from 'i18next';
import type { SeoContentKey, SeoLandingKey } from './seoRoutes';
import { SEO_TRANSLATIONS, type SeoTranslationLanguage } from './seoTranslations';
export type { SeoContentKey, SeoLandingKey, SeoPageKey } from './seoRoutes';
@ -49,7 +49,7 @@ export interface SeoContentPage {
cta?: string;
}
type SeoLanguage = 'en' | SeoTranslationLanguage;
type SeoLanguage = string;
const COMMON_RELATED_LINKS: SeoLink[] = [
{
@ -758,29 +758,31 @@ export const SEO_CONTENT_PAGES: Record<SeoContentKey, SeoContentPage> = {
};
function toSeoLanguage(language: string | undefined): SeoLanguage {
const code = language?.toLowerCase().split('-')[0];
if (code && Object.prototype.hasOwnProperty.call(SEO_TRANSLATIONS, code)) {
return code as SeoTranslationLanguage;
return language?.toLowerCase().split('-')[0] ?? 'en';
}
function getSeoMap(language: SeoLanguage): Record<string, string> | null {
if (language === 'en') return null;
const bundle = i18n.getResourceBundle(language, 'translation') as
| { seo?: { pages?: Record<string, string> } }
| undefined;
return bundle?.seo?.pages ?? null;
}
function localizeSeoValue<T>(value: T, map: Record<string, string> | null): T {
if (typeof value === 'string') {
if (!map || value.startsWith('/')) return value;
return (map[value] ?? value) as T;
}
return 'en';
}
function translateSeoString(value: string, language: SeoLanguage): string {
if (language === 'en' || value.startsWith('/')) return value;
return SEO_TRANSLATIONS[language][value] ?? value;
}
function localizeSeoValue<T>(value: T, language: SeoLanguage): T {
if (typeof value === 'string') return translateSeoString(value, language) as T;
if (Array.isArray(value)) {
return value.map((item) => localizeSeoValue(item, language)) as T;
return value.map((item) => localizeSeoValue(item, map)) as T;
}
if (!value || typeof value !== 'object') return value;
return Object.fromEntries(
Object.entries(value as Record<string, unknown>).map(([key, item]) => [
key,
localizeSeoValue(item, language),
localizeSeoValue(item, map),
])
) as T;
}
@ -788,13 +790,13 @@ function localizeSeoValue<T>(value: T, language: SeoLanguage): T {
export function getLocalizedSeoLandingPages(
language: string | undefined
): Record<SeoLandingKey, SeoLandingContent> {
return localizeSeoValue(SEO_LANDING_PAGES, toSeoLanguage(language));
return localizeSeoValue(SEO_LANDING_PAGES, getSeoMap(toSeoLanguage(language)));
}
export function getLocalizedSeoContentPages(
language: string | undefined
): Record<SeoContentKey, SeoContentPage> {
return localizeSeoValue(SEO_CONTENT_PAGES, toSeoLanguage(language));
return localizeSeoValue(SEO_CONTENT_PAGES, getSeoMap(toSeoLanguage(language)));
}
export function getLocalizedSeoLandingPage(