From 6043aca819cb576ea138969183ec05d970f05821 Mon Sep 17 00:00:00 2001 From: Damjan Savic Date: Sun, 25 Jan 2026 06:40:04 +0100 Subject: [PATCH] auto-claude: subtask-1-9 - Extract HowToJsonLd component --- src/components/seo/schemas/HowToJsonLd.tsx | 87 ++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/components/seo/schemas/HowToJsonLd.tsx diff --git a/src/components/seo/schemas/HowToJsonLd.tsx b/src/components/seo/schemas/HowToJsonLd.tsx new file mode 100644 index 0000000..98d022b --- /dev/null +++ b/src/components/seo/schemas/HowToJsonLd.tsx @@ -0,0 +1,87 @@ +import { type Locale } from '@/i18n/config'; + +interface HowToStep { + name: string; + text: string; + url?: string; + image?: string; +} + +interface HowToJsonLdProps { + name: string; + description: string; + steps: HowToStep[]; + totalTime?: string; // ISO 8601 duration format, e.g., "PT30M" for 30 minutes + estimatedCost?: { currency: string; value: string }; + tools?: string[]; + supplies?: string[]; + image?: string; + locale: Locale; +} + +export function HowToJsonLd({ + name, + description, + steps, + totalTime, + estimatedCost, + tools, + supplies, + image, + locale, +}: HowToJsonLdProps) { + const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com'; + + const schema: Record = { + '@context': 'https://schema.org', + '@type': 'HowTo', + name: name, + description: description, + step: steps.map((step, index) => ({ + '@type': 'HowToStep', + position: index + 1, + name: step.name, + text: step.text, + ...(step.url && { url: step.url.startsWith('http') ? step.url : `${baseUrl}${step.url}` }), + ...(step.image && { image: step.image.startsWith('http') ? step.image : `${baseUrl}${step.image}` }), + })), + inLanguage: locale === 'de' ? 'de-DE' : locale === 'sr' ? 'sr-RS' : 'en-US', + }; + + if (totalTime) { + schema.totalTime = totalTime; + } + + if (estimatedCost) { + schema.estimatedCost = { + '@type': 'MonetaryAmount', + currency: estimatedCost.currency, + value: estimatedCost.value, + }; + } + + if (tools && tools.length > 0) { + schema.tool = tools.map((tool) => ({ + '@type': 'HowToTool', + name: tool, + })); + } + + if (supplies && supplies.length > 0) { + schema.supply = supplies.map((supply) => ({ + '@type': 'HowToSupply', + name: supply, + })); + } + + if (image) { + schema.image = image.startsWith('http') ? image : `${baseUrl}${image}`; + } + + return ( +