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
This commit is contained in:
Justin Edmund 2025-12-02 08:39:28 -08:00
parent 7471901fee
commit 13f78e4bf8
4 changed files with 78 additions and 9 deletions

View file

@ -3,7 +3,6 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/fonts/fonts.css" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">

View file

@ -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 = `<style id="font-faces">${fontCSS}</style>`
html = html.replace('</head>', `${fontPreloads}\n${fontStyle}\n</head>`)
return html.replace('%paraglide.lang%', locale)
}
})
})

64
src/lib/utils/fonts.ts Normal file
View file

@ -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) =>
`<link rel="preload" href="${baseUrl}/${file}" as="font" type="font/woff2" crossorigin />`
)
.join('\n')
}

View file

@ -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;