import { Metadata } from 'next'; import { getSiteInfo } from './i18n'; import type { Locale } from './i18n'; export interface SEOParams { title?: string; description?: string; locale?: Locale; canonical?: string; ogType?: 'website' | 'article' | 'product'; ogImages?: string[]; publishedTime?: string; updatedTime?: string; author?: string; } export function generateSEOMetadata({ title, description, locale = 'en', canonical, ogType = 'website', ogImages = [], publishedTime, updatedTime, author, }: SEOParams): Metadata { const site = getSiteInfo(locale); const pageTitle = title ? `${title} | ${site.title}` : site.title; const pageDescription = description || site.description; const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || site.baseUrl; const path = canonical || '/'; const fullUrl = `${baseUrl}${path}`; // Generate alternate URLs for both locales const alternates = { canonical: fullUrl, languages: { 'en': `${baseUrl}${path.replace('/de/', '/')}`, 'de': `${baseUrl}${path.startsWith('/de') ? path : `/de${path}`}`, }, }; const openGraph = { title: pageTitle, description: pageDescription, url: fullUrl, siteName: site.title, locale: locale === 'de' ? 'de_DE' : 'en_US', type: ogType, ...(ogImages.length > 0 && { images: ogImages }), ...(publishedTime && { publishedTime }), ...(updatedTime && { updatedTime }), ...(author && { authors: [author] }), }; const twitter = { card: 'summary_large_image', title: pageTitle, description: pageDescription, ...(ogImages.length > 0 && { images: ogImages }), }; return { title: pageTitle, description: pageDescription, alternates, openGraph, twitter, authors: author ? [{ name: author }] : undefined, metadataBase: new URL(baseUrl), }; } // Helper for blog posts export function getPostSEO(post: any, locale: Locale): Metadata { return generateSEOMetadata({ title: post.title, description: post.excerptHtml?.replace(/<[^>]*>/g, '') || '', canonical: post.path, locale: locale, ogType: 'article', ogImages: post.featuredImage ? [post.featuredImage] : [], publishedTime: post.datePublished, updatedTime: post.updatedAt, author: 'KLZ Cables Team', }); } // Helper for products export function getProductSEO(product: any, locale: Locale): Metadata { return generateSEOMetadata({ title: product.name, description: product.shortDescriptionHtml?.replace(/<[^>]*>/g, '') || '', canonical: product.path, locale: locale, ogType: 'product', ogImages: product.images || [], }); } // Helper for categories export function getCategorySEO(category: any, locale: Locale): Metadata { return generateSEOMetadata({ title: category.name, description: category.description || `Products in ${category.name}`, canonical: category.path, locale: locale, ogType: 'website', }); } export function generateSitemapItem({ path, lastmod, priority = 0.7, }: { path: string; lastmod?: string; priority?: number; }) { return { url: path, lastmod: lastmod || new Date().toISOString().split('T')[0], changefreq: 'weekly', priority, }; }