diff --git a/astro.config.mjs b/astro.config.mjs index 4e02846..03870d1 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,4 +1,4 @@ -import { defineConfig, sessionDrivers } from "astro/config"; +import { defineConfig, fontProviders, sessionDrivers } from "astro/config"; import cloudflare from "@astrojs/cloudflare"; import tailwindcss from "@tailwindcss/vite"; @@ -13,10 +13,38 @@ export default defineConfig({ // Cloudflare-KV session driver so no (id-less) SESSION KV binding is emitted // into the generated deploy config. session: { driver: sessionDrivers.memory() }, + // Self-host the two webfonts (downloaded + subset at build time, served as + // static /_astro assets by the platform). This removes the render-blocking + // cross-origin Google Fonts stylesheet from the critical path; the + // component instead inlines @font-face CSS and preloads the body font. + fonts: [ + { + provider: fontProviders.google(), + name: "Inter", + cssVariable: "--font-inter", + weights: ["400 800"], + styles: ["normal"], + subsets: ["latin"], + fallbacks: ["system-ui", "sans-serif"], + }, + { + provider: fontProviders.google(), + name: "Playfair Display", + cssVariable: "--font-playfair", + weights: ["700 900"], + styles: ["normal", "italic"], + subsets: ["latin"], + fallbacks: ["Georgia", "serif"], + }, + ], adapter: cloudflare({ // Plain with build-emitted assets — no runtime image service / IMAGES binding. imageService: "passthrough", }), + // Inline the (small, ~6KB) global stylesheet into each page's instead + // of emitting a render-blocking . Pages are SSR'd per request, so there + // is no shared-CSS-cache benefit to give up, and FCP/LCP improve. + build: { inlineStylesheets: "always" }, vite: { plugins: [tailwindcss()], resolve: { diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index a897513..cae8917 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,4 +1,5 @@ --- +import { Font } from "astro:assets"; import "../styles/global.css"; interface Props { @@ -101,12 +102,11 @@ const telemetryConfig = Astro.locals.telemetry?.clientConfig() ?? null; - - - + {/* Self-hosted, served from /_astro — no cross-origin render-blocking + stylesheet. Inter is the body font, so preload it; the serif display + face is above-the-fold too, so preload it as well. */} + + diff --git a/src/styles/global.css b/src/styles/global.css index fb14f49..e2ae44a 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -35,8 +35,10 @@ --color-paper: var(--paper); --color-ink: var(--ink); --color-electric: var(--electric); - --font-serif: "Playfair Display", Georgia, serif; - --font-sans: "Inter", system-ui, sans-serif; + /* Resolve to the self-hosted families registered via Astro's fonts config + (astro.config.mjs). Each var already carries optimized fallback metrics. */ + --font-serif: var(--font-playfair, "Playfair Display", Georgia, serif); + --font-sans: var(--font-inter, "Inter", system-ui, sans-serif); } :root {