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}