feat(seo): LocalBusiness + CollectionPage structured data schemas

- Add localBusinessSchema() with geo coords, phone, opening hours for
  Google Local Pack and Knowledge Panel visibility
- Add collectionPageSchema() with ItemList for article listing pages
- Inject LocalBusiness alongside Organization+WebSite in root layout
- Inject CollectionPage in /news hub page with article items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 18:06:12 -05:00
parent 8d80cbbc27
commit 7ec99734c5
3 changed files with 85 additions and 2 deletions
+64
View File
@@ -114,6 +114,70 @@ export function organizationSchema(opts?: { logoUrl?: string; sameAs?: string[]
};
}
export function localBusinessSchema(opts?: { logoUrl?: string; sameAs?: string[] }) {
const base = baseUrl();
return {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"@id": `${base}/#local-business`,
name: "FLUX Srl",
legalName: "FLUX Srl",
url: base,
logo: opts?.logoUrl ? absoluteUrl(opts.logoUrl) : `${base}/flux-logo.png`,
description:
"Manufacturer of solid-state Radio Frequency (RF), Microwave, and Infrared industrial equipment since 1978.",
foundingDate: "1978",
founder: { "@type": "Person", name: "Patrizio Grando" },
address: {
"@type": "PostalAddress",
streetAddress: "Via Benedetto Marcello 32",
addressLocality: "Romano d'Ezzelino",
addressRegion: "Vicenza",
postalCode: "36060",
addressCountry: "IT",
},
geo: {
"@type": "GeoCoordinates",
latitude: 45.7836,
longitude: 11.7677,
},
telephone: "+39 0424 287 492",
email: "info@rf-flux.com",
openingHoursSpecification: {
"@type": "OpeningHoursSpecification",
dayOfWeek: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
opens: "08:00",
closes: "17:00",
},
areaServed: { "@type": "Place", name: "Worldwide" },
...(opts?.sameAs ? { sameAs: opts.sameAs } : {}),
};
}
export function collectionPageSchema(opts: {
name: string;
description: string;
url: string;
items: { name: string; url: string; position: number }[];
}) {
return {
"@context": "https://schema.org",
"@type": "CollectionPage",
name: opts.name,
description: opts.description,
url: opts.url,
mainEntity: {
"@type": "ItemList",
itemListElement: opts.items.map((item) => ({
"@type": "ListItem",
position: item.position,
url: item.url,
name: item.name,
})),
},
};
}
export function websiteSchema() {
const base = baseUrl();
return {