From dc72234434a8408e08c8c7c0c0f73f52aa4e222c Mon Sep 17 00:00:00 2001 From: Damjan Savic Date: Sun, 25 Jan 2026 11:18:17 +0100 Subject: [PATCH] auto-claude: subtask-1-12 - Extract SoftwareAppJsonLd component --- .auto-claude-status | 4 +- .../seo/schemas/SoftwareAppJsonLd.tsx | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/components/seo/schemas/SoftwareAppJsonLd.tsx diff --git a/.auto-claude-status b/.auto-claude-status index 98e7331..01f4314 100644 --- a/.auto-claude-status +++ b/.auto-claude-status @@ -18,8 +18,8 @@ "max": 1 }, "session": { - "number": 1548, + "number": 1556, "started_at": "2026-01-25T06:23:19.101802" }, - "last_update": "2026-01-25T11:16:43.611638" + "last_update": "2026-01-25T11:18:16.694552" } \ No newline at end of file diff --git a/src/components/seo/schemas/SoftwareAppJsonLd.tsx b/src/components/seo/schemas/SoftwareAppJsonLd.tsx new file mode 100644 index 0000000..f355ec0 --- /dev/null +++ b/src/components/seo/schemas/SoftwareAppJsonLd.tsx @@ -0,0 +1,65 @@ +import { type Locale } from '@/i18n/config'; + +interface SoftwareAppJsonLdProps { + name: string; + description: string; + applicationCategory: string; + operatingSystem?: string; + offers?: { + price: string; + priceCurrency: string; + }; + aggregateRating?: { + ratingValue: string; + ratingCount: string; + }; + locale: Locale; +} + +export function SoftwareAppJsonLd({ + name, + description, + applicationCategory, + operatingSystem = 'Web', + offers, + aggregateRating, + locale, +}: SoftwareAppJsonLdProps) { + const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com'; + + const schema: Record = { + '@context': 'https://schema.org', + '@type': 'SoftwareApplication', + name: name, + description: description, + applicationCategory: applicationCategory, + operatingSystem: operatingSystem, + author: { + '@id': `${baseUrl}/#person`, + }, + inLanguage: locale === 'de' ? 'de-DE' : locale === 'sr' ? 'sr-RS' : 'en-US', + }; + + if (offers) { + schema.offers = { + '@type': 'Offer', + price: offers.price, + priceCurrency: offers.priceCurrency, + }; + } + + if (aggregateRating) { + schema.aggregateRating = { + '@type': 'AggregateRating', + ratingValue: aggregateRating.ratingValue, + ratingCount: aggregateRating.ratingCount, + }; + } + + return ( +