import { ProductSchema } from './types'; import { Locale } from '../keywords/types'; import { getBrandKeywords, getCategoryKeywords } from '../keywords'; interface ProductData { name: string; slug: string; description: string; images: string[]; price: { amount: number; currency: string; }; sku?: string; availability?: 'InStock' | 'OutOfStock' | 'PreOrder'; category?: string; rating?: { value: number; count: number; }; } /** * Generate Product schema (JSON-LD) * Pure function - takes product data, returns schema object * * @param baseUrl - Site base URL * @param locale - Locale code * @param product - Product data * @returns ProductSchema object */ export function generateProductSchema( baseUrl: string, locale: Locale, product: ProductData ): ProductSchema { const brandKeywords = getBrandKeywords(locale); const productUrl = `${baseUrl}/${locale === 'sr' ? '' : locale + '/'}products/${product.slug}`; // Build full image URLs const imageUrls = product.images.map(img => img.startsWith('http') ? img : `${baseUrl}${img}` ); const schema: ProductSchema = { '@context': 'https://schema.org', '@type': 'Product', name: product.name, image: imageUrls, description: product.description.slice(0, 5000), // Schema.org limit sku: product.sku, brand: { '@type': 'Brand', name: brandKeywords.companyName, }, offers: { '@type': 'Offer', url: productUrl, price: product.price.amount.toString(), priceCurrency: product.price.currency, availability: `https://schema.org/${product.availability || 'InStock'}`, itemCondition: 'https://schema.org/NewCondition', }, }; // Add aggregate rating if available if (product.rating && product.rating.count > 0) { schema.aggregateRating = { '@type': 'AggregateRating', ratingValue: product.rating.value.toString(), reviewCount: product.rating.count.toString(), }; } return schema; } /** * Generate Product schema with category context * Uses category-specific keywords for enhanced SEO * * @param baseUrl - Site base URL * @param locale - Locale code * @param product - Product data * @param categoryKey - Category key for keyword targeting * @returns ProductSchema object */ export function generateCategorizedProductSchema( baseUrl: string, locale: Locale, product: ProductData, categoryKey: 'antiAging' | 'hydration' | 'glow' | 'sensitive' | 'natural' | 'organic' ): ProductSchema { const categoryKeywords = getCategoryKeywords(locale, categoryKey); // Enhance description with category keywords const enhancedDescription = product.description + ' ' + categoryKeywords.slice(0, 3).join('. '); return generateProductSchema(baseUrl, locale, { ...product, description: enhancedDescription, }); }