SvelteKit 2 (adapter-node, Vite 5) documents a preload filter on resolve: resolve(event, { preload: ({ type, path }) => ... }) with type 'font' as a supported case. In practice, a filter returning true for type === 'font' emitted NO <link rel=preload as=font> for fonts referenced via CSS url() in an imported stylesheet. Verified twice against deployed production HTML (before and after a deploy): js/css preloads present, font preload absent, and the CLS regression the preload was meant to fix (late font swap, 0.245) persisted.
Working alternative:
- Import the font file directly in +layout.svelte for its hashed URL: import noto_latin_url from '@fontsource-variable/noto-sans/files/noto-sans-latin-wght-normal.woff2';
- Emit the link in svelte:head:<link rel="preload" href={noto_latin_url} as="font" type="font/woff2" crossorigin="anonymous" />
Vite dedupes assets by content hash, so the imported URL is byte-identical to the one the CSS url() resolves to - one download, arriving before first paint.
Measured result on the affected page (Lighthouse 13.4.0, mobile simulated): CLS 0.279 -> 0.034, perf 37 -> 79.