From 13f78e4bf848e9a217df946d7caeb7d51a01091a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Tue, 2 Dec 2025 08:39:28 -0800 Subject: [PATCH] switch to dynamic font loading from env loads fonts from AWS S3 when PUBLIC_SIERO_IMG_URL is set, otherwise falls back to local /fonts directory --- src/app.html | 1 - src/hooks.server.ts | 12 ++++++- src/lib/utils/fonts.ts | 64 +++++++++++++++++++++++++++++++++++++ src/themes/_typography.scss | 10 ++---- 4 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 src/lib/utils/fonts.ts diff --git a/src/app.html b/src/app.html index 3b720b41..50bd0b52 100644 --- a/src/app.html +++ b/src/app.html @@ -3,7 +3,6 @@ - %sveltekit.head% diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 99d202b0..0a9ec17e 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -3,6 +3,7 @@ import { sequence } from '@sveltejs/kit/hooks' import { paraglideMiddleware } from '$lib/paraglide/server' import { getAccountFromCookies, getUserFromCookies } from '$lib/auth/cookies' import { PUBLIC_SIERO_API_URL } from '$env/static/public' +import { generateFontFaceCSS, getFontPreloadLinks } from '$lib/utils/fonts' export const handleSession: Handle = async ({ event, resolve }) => { const account = getAccountFromCookies(event.cookies) @@ -41,12 +42,21 @@ export const handleSession: Handle = async ({ event, resolve }) => { return resolve(event) } +// Generate font CSS and preload links once at startup +const fontCSS = generateFontFaceCSS() +const fontPreloads = getFontPreloadLinks() + const handleParaglide: Handle = ({ event, resolve }) => paraglideMiddleware(event.request, ({ request, locale }) => { event.request = request return resolve(event, { - transformPageChunk: ({ html }) => html.replace('%paraglide.lang%', locale) + transformPageChunk: ({ html }) => { + // Inject font preloads and @font-face CSS into the head + const fontStyle = `` + html = html.replace('', `${fontPreloads}\n${fontStyle}\n`) + return html.replace('%paraglide.lang%', locale) + } }) }) diff --git a/src/lib/utils/fonts.ts b/src/lib/utils/fonts.ts new file mode 100644 index 00000000..7484f832 --- /dev/null +++ b/src/lib/utils/fonts.ts @@ -0,0 +1,64 @@ +/** + * Font loading utilities + * + * Generates @font-face CSS based on environment: + * - Development: loads from /fonts (local static files) + * - Production: loads from AWS S3 CDN + */ + +import { getImageBaseUrl } from '$lib/api/adapters/config' + +const FONT_FILES = [ + { file: '437fb160c86d1771.woff2', weight: 400, style: 'normal' }, + { file: '90e2044c61d1d575.woff2', weight: 400, style: 'italic' }, + { file: 'db6054d73906f6d1.woff2', weight: 500, style: 'normal' }, + { file: '54cf3d47648cbde4.woff2', weight: 500, style: 'italic' }, + { file: 'a9a1343791e012e7.woff2', weight: 700, style: 'normal' }, + { file: '0137ea08b8d14fae.woff2', weight: 700, style: 'italic' }, + { file: '83b98eb4efef82d6.woff2', weight: 900, style: 'normal' }, + { file: '8fd873f2349d20e6.woff2', weight: 900, style: 'italic' } +] as const + +/** + * Get the base URL for font files + * Uses AWS S3 URL when PUBLIC_SIERO_IMG_URL is set, otherwise local /fonts + */ +export function getFontBaseUrl(): string { + const imageBaseUrl = getImageBaseUrl() + if (imageBaseUrl) { + return `${imageBaseUrl}/fonts` + } + return '/fonts' +} + +/** + * Generate @font-face CSS for all font weights/styles + */ +export function generateFontFaceCSS(): string { + const baseUrl = getFontBaseUrl() + + return FONT_FILES.map( + ({ file, weight, style }) => `@font-face { + font-family: 'AGrot'; + src: url('${baseUrl}/${file}') format('woff2'); + font-weight: ${weight}; + font-style: ${style}; + font-display: swap; +}` + ).join('\n\n') +} + +/** + * Get preload link tags for critical font weights (400 normal, 700 normal) + */ +export function getFontPreloadLinks(): string { + const baseUrl = getFontBaseUrl() + const criticalFonts = ['437fb160c86d1771.woff2', 'a9a1343791e012e7.woff2'] + + return criticalFonts + .map( + (file) => + `` + ) + .join('\n') +} diff --git a/src/themes/_typography.scss b/src/themes/_typography.scss index a25bdbd8..7a5064a5 100644 --- a/src/themes/_typography.scss +++ b/src/themes/_typography.scss @@ -1,11 +1,7 @@ // Fonts -@font-face { - font-family: 'Goalking'; - src: url('/fonts/gk-variable.woff2') format('woff2-variations'); - font-weight: 100 900; - font-style: normal; - font-display: swap; -} +// Font files are loaded from static/fonts locally or AWS S3 in production +// The @font-face declarations are in src/lib/styles/fonts.css which is +// generated/loaded based on environment (see app.html and hooks) // Font-weight (AGrot: 400, 500, 700, 900) $normal: 400;