auto-claude: subtask-1-9 - Extract HowToJsonLd component
This commit is contained in:
@@ -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<string, unknown> = {
|
||||||
|
'@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 (
|
||||||
|
<script
|
||||||
|
type="application/ld+json"
|
||||||
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user