Files
bootnode/console/app/layout.tsx
T

63 lines
2.4 KiB
TypeScript

import type { Metadata } from "next"
import { ThemeProvider } from "@/components/theme-provider"
import { AuthProvider } from "@/lib/auth"
import { Providers } from "@/app/providers"
import { Toaster } from "@/components/ui/sonner"
import { BrandProvider } from "@/components/brand-provider"
import { getBrand } from "@/lib/brand"
import "@hanzo/font/css"
import "@/app/globals.css"
// `output: "export"` prerenders this at build time, where there is no request
// and therefore no Host header — so the static <head> can only carry the
// default brand, and the real one is resolved from the hostname after
// hydration by BrandProvider (which sets document.title and the favicon).
//
// This is the one honest way to white-label a static export. Baking a brand in
// at build time via NEXT_PUBLIC_BRAND is the alternative, and it is what this
// app used to do: it produced four near-identical images, three of which were
// wrong for whichever host they happened to be serving.
const fallback = getBrand("")
export const metadata: Metadata = {
title: { default: `${fallback.name} — ${fallback.tagline}`, template: `%s | ${fallback.name}` },
description: fallback.description,
keywords: ["blockchain", "RPC", "API", "Web3", "NFT", "DeFi", "smart contracts", "developer tools"],
openGraph: {
type: "website",
locale: "en_US",
url: `https://${fallback.domain}`,
siteName: fallback.name,
title: `${fallback.name} — ${fallback.tagline}`,
description: fallback.description,
},
twitter: {
card: "summary_large_image",
title: `${fallback.name} — ${fallback.tagline}`,
description: fallback.description,
},
icons: { icon: fallback.favicon, apple: fallback.favicon, shortcut: fallback.favicon },
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body className="min-h-screen bg-background font-sans antialiased">
<Providers>
{/* BrandProvider wraps ThemeProvider: the brand owns the default
colour scheme, so the theme cannot be resolved before the brand
is. */}
<BrandProvider>
<AuthProvider>
<ThemeProvider>
{children}
<Toaster />
</ThemeProvider>
</AuthProvider>
</BrandProvider>
</Providers>
</body>
</html>
)
}