Files
BelgianBitcoinEmbassy/frontend/app/layout.tsx
bbe 78271ea110 feat: organizers, meetups UI, Plausible analytics, and migration tooling
- Add organizer model/API, admin and public organizer pages, meetup cards
- Refresh events/home/contact; add calendar dialog and carousel components
- Optional Plausible via NEXT_PUBLIC_PLAUSIBLE_* env vars in root layout
- Prisma migration, seed updates, baseline-and-migrate script

Made-with: Cursor
2026-04-04 21:55:34 +02:00

112 lines
3.1 KiB
TypeScript

import type { Metadata, Viewport } from "next";
import Script from "next/script";
import { ClientProviders } from "@/components/providers/ClientProviders";
import { OrganizationJsonLd, WebSiteJsonLd } from "@/components/public/JsonLd";
import "./globals.css";
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://belgianbitcoinembassy.org";
const plausibleDomain = process.env.NEXT_PUBLIC_PLAUSIBLE_DOMAIN?.trim();
const plausibleAnalyticsOrigin = process.env.NEXT_PUBLIC_PLAUSIBLE_ANALYTICS_ORIGIN?.trim().replace(
/\/$/,
"",
);
const plausibleScriptSrc =
plausibleDomain && plausibleAnalyticsOrigin
? `${plausibleAnalyticsOrigin}/js/script.js`
: null;
export const metadata: Metadata = {
metadataBase: new URL(siteUrl),
title: {
default: "Belgian Bitcoin Embassy | Bitcoin Meetups & Education in Belgium",
template: "%s | Belgian Bitcoin Embassy",
},
description:
"Belgium's sovereign Bitcoin community. Monthly meetups in Antwerp, Bitcoin education, and curated Nostr content. No hype, just signal.",
keywords: [
"Bitcoin",
"Belgium",
"Antwerp",
"Bitcoin meetup",
"Bitcoin education",
"Nostr",
"Belgian Bitcoin Embassy",
"Bitcoin community Belgium",
"Bitcoin events Antwerp",
],
authors: [{ name: "Belgian Bitcoin Embassy" }],
creator: "Belgian Bitcoin Embassy",
publisher: "Belgian Bitcoin Embassy",
openGraph: {
type: "website",
locale: "en_BE",
siteName: "Belgian Bitcoin Embassy",
title: "Belgian Bitcoin Embassy | Bitcoin Meetups & Education in Belgium",
description:
"Belgium's sovereign Bitcoin community. Monthly meetups, education, and curated Nostr content.",
images: [
{
url: "/og-default.png",
width: 1200,
height: 630,
alt: "Belgian Bitcoin Embassy - Bitcoin Meetups & Education in Belgium",
},
],
},
twitter: {
card: "summary_large_image",
title: "Belgian Bitcoin Embassy",
description:
"Belgium's sovereign Bitcoin community. Monthly meetups, education, and curated Nostr content.",
images: ["/og-default.png"],
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
},
icons: {
icon: [
{ url: "/favicon.svg", type: "image/svg+xml" },
{ url: "/favicon.ico", sizes: "32x32" },
],
apple: "/apple-touch-icon.png",
},
alternates: {
canonical: "/",
},
};
export const viewport: Viewport = {
themeColor: "#F7931A",
width: "device-width",
initialScale: 1,
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" dir="ltr" className="dark">
<body>
{plausibleScriptSrc && plausibleDomain ? (
<Script
defer
src={plausibleScriptSrc}
data-domain={plausibleDomain}
strategy="afterInteractive"
/>
) : null}
<OrganizationJsonLd />
<WebSiteJsonLd />
<ClientProviders>{children}</ClientProviders>
</body>
</html>
);
}