200 lines
4.6 KiB
TypeScript
200 lines
4.6 KiB
TypeScript
interface JsonLdProps {
|
|
data: Record<string, unknown>;
|
|
}
|
|
|
|
export function JsonLd({ data }: JsonLdProps) {
|
|
return (
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
|
|
/>
|
|
);
|
|
}
|
|
|
|
const siteUrl =
|
|
process.env.NEXT_PUBLIC_SITE_URL || "https://belgianbitcoinembassy.org";
|
|
|
|
export function OrganizationJsonLd() {
|
|
return (
|
|
<JsonLd
|
|
data={{
|
|
"@context": "https://schema.org",
|
|
"@type": "Organization",
|
|
name: "Belgian Bitcoin Embassy",
|
|
url: siteUrl,
|
|
logo: `${siteUrl}/og-default.png`,
|
|
description:
|
|
"Belgium's sovereign Bitcoin community. Monthly meetups, education, and curated Nostr content.",
|
|
sameAs: ["https://t.me/belgianbitcoinembassy"],
|
|
address: {
|
|
"@type": "PostalAddress",
|
|
addressLocality: "Antwerp",
|
|
addressCountry: "BE",
|
|
},
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function WebSiteJsonLd() {
|
|
return (
|
|
<JsonLd
|
|
data={{
|
|
"@context": "https://schema.org",
|
|
"@type": "WebSite",
|
|
name: "Belgian Bitcoin Embassy",
|
|
url: siteUrl,
|
|
description:
|
|
"Belgium's sovereign Bitcoin community. Monthly meetups, education, and curated Nostr content.",
|
|
publisher: {
|
|
"@type": "Organization",
|
|
name: "Belgian Bitcoin Embassy",
|
|
logo: { "@type": "ImageObject", url: `${siteUrl}/og-default.png` },
|
|
},
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
interface BlogPostingJsonLdProps {
|
|
title: string;
|
|
description: string;
|
|
slug: string;
|
|
publishedAt?: string;
|
|
authorName?: string;
|
|
}
|
|
|
|
export function BlogPostingJsonLd({
|
|
title,
|
|
description,
|
|
slug,
|
|
publishedAt,
|
|
authorName,
|
|
}: BlogPostingJsonLdProps) {
|
|
return (
|
|
<JsonLd
|
|
data={{
|
|
"@context": "https://schema.org",
|
|
"@type": "BlogPosting",
|
|
headline: title,
|
|
description,
|
|
url: `${siteUrl}/blog/${slug}`,
|
|
...(publishedAt ? { datePublished: publishedAt } : {}),
|
|
author: {
|
|
"@type": "Person",
|
|
name: authorName || "Belgian Bitcoin Embassy",
|
|
},
|
|
publisher: {
|
|
"@type": "Organization",
|
|
name: "Belgian Bitcoin Embassy",
|
|
logo: { "@type": "ImageObject", url: `${siteUrl}/og-default.png` },
|
|
},
|
|
image: `${siteUrl}/og?title=${encodeURIComponent(title)}&type=blog`,
|
|
mainEntityOfPage: {
|
|
"@type": "WebPage",
|
|
"@id": `${siteUrl}/blog/${slug}`,
|
|
},
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
interface EventJsonLdProps {
|
|
name: string;
|
|
description?: string;
|
|
startDate: string;
|
|
location?: string;
|
|
url: string;
|
|
imageUrl?: string;
|
|
}
|
|
|
|
export function EventJsonLd({
|
|
name,
|
|
description,
|
|
startDate,
|
|
location,
|
|
url,
|
|
imageUrl,
|
|
}: EventJsonLdProps) {
|
|
return (
|
|
<JsonLd
|
|
data={{
|
|
"@context": "https://schema.org",
|
|
"@type": "Event",
|
|
name,
|
|
description: description || `Bitcoin meetup: ${name}`,
|
|
startDate,
|
|
eventAttendanceMode: "https://schema.org/OfflineEventAttendanceMode",
|
|
eventStatus: "https://schema.org/EventScheduled",
|
|
...(location
|
|
? {
|
|
location: {
|
|
"@type": "Place",
|
|
name: location,
|
|
address: {
|
|
"@type": "PostalAddress",
|
|
addressLocality: location,
|
|
addressCountry: "BE",
|
|
},
|
|
},
|
|
}
|
|
: {}),
|
|
organizer: {
|
|
"@type": "Organization",
|
|
name: "Belgian Bitcoin Embassy",
|
|
url: siteUrl,
|
|
},
|
|
image:
|
|
imageUrl || `${siteUrl}/og?title=${encodeURIComponent(name)}&type=event`,
|
|
url,
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
interface FaqJsonLdProps {
|
|
items: { question: string; answer: string }[];
|
|
}
|
|
|
|
export function FaqPageJsonLd({ items }: FaqJsonLdProps) {
|
|
if (items.length === 0) return null;
|
|
return (
|
|
<JsonLd
|
|
data={{
|
|
"@context": "https://schema.org",
|
|
"@type": "FAQPage",
|
|
mainEntity: items.map((item) => ({
|
|
"@type": "Question",
|
|
name: item.question,
|
|
acceptedAnswer: {
|
|
"@type": "Answer",
|
|
text: item.answer,
|
|
},
|
|
})),
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
interface BreadcrumbItem {
|
|
name: string;
|
|
href: string;
|
|
}
|
|
|
|
export function BreadcrumbJsonLd({ items }: { items: BreadcrumbItem[] }) {
|
|
return (
|
|
<JsonLd
|
|
data={{
|
|
"@context": "https://schema.org",
|
|
"@type": "BreadcrumbList",
|
|
itemListElement: items.map((item, index) => ({
|
|
"@type": "ListItem",
|
|
position: index + 1,
|
|
name: item.name,
|
|
item: `${siteUrl}${item.href}`,
|
|
})),
|
|
}}
|
|
/>
|
|
);
|
|
}
|