diff --git a/app/[leaflet_id]/Leaflet.tsx b/app/[leaflet_id]/Leaflet.tsx index a98ee708..8233c350 100644 --- a/app/[leaflet_id]/Leaflet.tsx +++ b/app/[leaflet_id]/Leaflet.tsx @@ -18,6 +18,7 @@ export function Leaflet(props: { token: PermissionToken; initialFacts: Fact[]; leaflet_id: string; + initialFontId?: string; }) { return ( - + diff --git a/app/[leaflet_id]/page.tsx b/app/[leaflet_id]/page.tsx index be3c7b31..ef90c290 100644 --- a/app/[leaflet_id]/page.tsx +++ b/app/[leaflet_id]/page.tsx @@ -14,6 +14,7 @@ import { supabaseServerClient } from "supabase/serverClient"; import { get_leaflet_data } from "app/api/rpc/[command]/get_leaflet_data"; import { NotFoundLayout } from "components/PageLayouts/NotFoundLayout"; import { getPublicationMetadataFromLeafletData } from "src/utils/getPublicationMetadataFromLeafletData"; +import { FontLoader, extractFontFromFacts } from "components/FontLoader"; export const preferredRegion = ["sfo1"]; export const dynamic = "force-dynamic"; @@ -48,19 +49,28 @@ export default async function LeafletPage(props: Props) { getPollData(res.data.permission_token_rights.map((ptr) => ptr.entity_set)), ]); let initialFacts = (data as unknown as Fact[]) || []; + + // Extract font setting from facts for server-side font loading + const fontId = extractFontFromFacts(initialFacts as any, rootEntity); + return ( - - - + <> + {/* Server-side font loading with preload and @font-face */} + + + + + ); } diff --git a/app/globals.css b/app/globals.css index 6a447a52..30d6bb13 100644 --- a/app/globals.css +++ b/app/globals.css @@ -62,7 +62,7 @@ --shadow-md: 1.2px 2.5px 2.7px -1.8px rgba(var(--primary), 0.1), 5.6px 11.6px 12.5px -3.5px rgba(var(--primary), 0.15); - --font-sans: var(--font-quattro); + --font-sans: var(--theme-font, var(--font-quattro)); --font-serif: Garamond; } @@ -194,7 +194,7 @@ } pre { - font-family: var(--font-quattro); + font-family: var(--theme-font, --font-quattro); } p { diff --git a/components/FontLoader.tsx b/components/FontLoader.tsx new file mode 100644 index 00000000..09edab66 --- /dev/null +++ b/components/FontLoader.tsx @@ -0,0 +1,55 @@ +// Server-side font loading component +// Replicates next/font behavior: preload links, @font-face, and CSS variable +// This is rendered on the server and the link/style tags are hoisted to + +import { getFontConfig, generateFontFaceCSS, getFontPreloadLinks, FontConfig } from "src/fonts"; + +type FontLoaderProps = { + fontId: string | undefined; +}; + +export function FontLoader({ fontId }: FontLoaderProps) { + const font = getFontConfig(fontId); + const preloadLinks = getFontPreloadLinks(font); + const fontFaceCSS = generateFontFaceCSS(font); + + // Generate CSS that sets the font family via CSS variable + const fontVariableCSS = ` +:root { + --theme-font: '${font.fontFamily}', ${font.fallback.join(", ")}; +} +`.trim(); + + return ( + <> + {/* Preload font files - these get hoisted to by React/Next.js */} + {preloadLinks.map((link) => ( + + ))} + {/* @font-face declarations and CSS variable */} +