TheBird

Page.jsx

3.0 kB · jsx · 62 lines

1import site from "../../site.json";2import { SHOPIFY_CDN, THEME_COLORS } from "../config/shop.ts";3import { MODE_SCRIPT } from "../config/boot.ts";45const FONTS = "/fonts/fonts.css";67const json = (value) => JSON.stringify(value).replace(/[<\u2028\u2029]/g, (c) => "\\u" + c.charCodeAt(0).toString(16).padStart(4, "0"));89export function Page({ root, route, title, description, image, type = "website", meta = [], sheets = [], scripts = [], sky, data, noindex = false, preconnect, app = "", props }) {10  const url = root + route;11  return (12    <html lang="en">13      <head>14        <meta charSet="utf-8" />15        <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />16        <meta name="color-scheme" content="light dark" />17        <meta name="theme-color" content={THEME_COLORS.light} />18        <script dangerouslySetInnerHTML={{ __html: MODE_SCRIPT }} />19        <title>{title === site.name ? site.name : `${title} · ${site.name}`}</title>20        <meta name="description" content={description} />21        {noindex ? <meta name="robots" content="noindex" /> : null}22        <link rel="canonical" href={url} />23        <link rel="preconnect" href={SHOPIFY_CDN} />24        {preconnect ? <link rel="preconnect" href={preconnect} /> : null}25        <meta property="og:site_name" content={site.name} />26        <meta property="og:title" content={title} />27        <meta property="og:description" content={description} />28        <meta property="og:url" content={url} />29        <meta property="og:type" content={type} />30        {image ? <meta property="og:image" content={image} /> : null}31        {meta.map((one) => (32          <meta key={one.property || one.name} {...one} />33        ))}34        <meta name="twitter:card" content="summary_large_image" />35        {image ? <meta name="twitter:image" content={image} /> : null}36        <link rel="icon" href="/bird/bird-64.png" type="image/png" />37        <link rel="apple-touch-icon" href="/bird/square-180.png" />38        <link rel="manifest" href="/manifest.webmanifest" />39        <link rel="preload" href="/fonts/sans.woff2" as="font" type="font/woff2" crossOrigin="" />40        <link rel="preload" href="/fonts/icons.woff2" as="font" type="font/woff2" crossOrigin="" />41        <link rel="stylesheet" href={FONTS} />42        {sheets.map((href) => (43          <link key={href} rel="stylesheet" href={href} />44        ))}45        {data ? <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: json(data) }} /> : null}46      </head>47      <body>48        <a className="skip" href="#main">49          Skip to content50        </a>51        <div id="app" dangerouslySetInnerHTML={{ __html: app }}></div>52        <section className="sky" data-sky={sky} aria-label="The sky">53          <canvas id="sky"></canvas>54        </section>55        <script id="props" type="application/json" dangerouslySetInnerHTML={{ __html: json(props) }} />56        {scripts.map((src) => (57          <script key={src} type="module" src={src} />58        ))}59      </body>60    </html>61  );62}