sveltejs / kit

web development, streamlined
https://svelte.dev/docs/kit
MIT License
18.78k stars 1.96k forks source link

inlineStyleThreshold causes relative link to fonts/resources to be broken #6720

Open audacioustux opened 2 years ago

audacioustux commented 2 years ago

Describe the bug

it works fine in dev mode, but with inlineStyleThreshold: 32 1024 and vite.build.assetsInlineLimit: 2 1024, the relative links to font files (e.g. .woff2) gets broken, as the css is now resides in html, and the font file in .svelte-kit/output/.. and i can't change the url to absolute url either, as I faced the issue with @fontsource/* fonts.

Reproduction

use any relative url in css, and make sure inlineStyleThreshold causes the css to be inlined

Logs

Error: Not found: /playfair-display-latin-variable-wghtOnly-normal-22b6cdc4.woff2

System Info

System:
    OS: macOS 11.6.5
    CPU: (4) x64 Intel(R) Core(TM) i5-4690 CPU @ 3.50GHz
    Memory: 89.70 MB / 24.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.17.0 - ~/.asdf/installs/nodejs/16.17.0/bin/node
    Yarn: 1.22.11 - /usr/local/bin/yarn
    npm: 8.15.0 - ~/.asdf/plugins/nodejs/shims/npm
  Browsers:
    Chrome: 105.0.5195.102
    Chrome Canary: 107.0.5292.0
    Firefox Nightly: 106.0a1
    Safari: 15.4

Severity

serious, but I can work around it

Additional Information

i had to disable inlineStyleThreshold, and call it a workaround

EmeraldSnorlax commented 9 months ago

hi, just want to add that i'm still experiencing this in my own website.

if it helps at all, i've created a minimal reproduction here https://github.com/EmeraldSnorlax/inline-style-minimal-reproduction

this is not exclusive to fontsource packages. i'm using a private font package, and the url()s in css do not get properly transformed if the css is inlined. it otherwise works perfectly in dev mode, or if the @font-face rule doesn't get inlined in production.

a copy paste of the thread i opened in the discord, if you want additional context or another example (from https://discord.com/channels/457912077277855764/1208579327575457802/1208579327575457802) hi, i'm trying to inline some styles, and i'm wondering if i'm making a mistake, or i should open a bug on github i've set inlineStyleThreshold here: https://github.com/EmeraldSnorlax/website/blob/71c2f0dc1539ee8afdbacd5930bf011bcc788238/svelte.config.js#L19 i'm importing the font + stylesheet from an external package by doing this: https://github.com/EmeraldSnorlax/website/blob/71c2f0dc1539ee8afdbacd5930bf011bcc788238/src/routes/p/mdsvex/MdsvexLayout.svelte#L2 the font gets loaded correctly when inlining is not done. however, when sveltekit tries to inline styles, it looks like the build output does not properly transform the paths for the inlined `@font-face` rules. this is output in `.svelte-kit/output/server/_app/immutable/assets/MdsvexLayout.BGZiVAWv.css`, where the italic *is not inlined* because it isn't deemed critical, and the path is *correct*. the browser happily finds the font ```css @font-face{font-family:Editorial New;src:url(/_app/immutable/assets/PPEditorialNew-Italic.Cp3W8-2Y.woff2) format("woff2"); /*snip...*/ ``` this gets output in `.svelte-kit/output/server/stylesheets/2.js`, where the regular *tries* to be inlined, but the path is *wrong*, and so when the page loads in browsers in production (no problem in dev mode, because no inlining is happening), the font is not found `downloadable font: download failed (font-family: "Editorial New" style:normal weight:400 stretch:100 src index:0): status=2147746065 source: http://localhost:4173/p/PPEditorialNew-Regular.Dr0yIrkc.woff2` ```css @font-face{font-family:Editorial New;src:url(./PPEditorialNew-Regular.Dr0yIrkc.woff2) format(\"woff2\"); ``` disabling inlining once again allows the browser to correctly request the font, but there's a noticeable fcp hit
eltigerchino commented 9 months ago

Another workaround is to set kit.config.paths.relative to false. https://kit.svelte.dev/docs/configuration

The issue is that the style inlining process is using the client bundle stylesheets (which have relative paths) instead of the server ones (non-relative paths). We can either use the server bundle stylesheets to inline or try to repair the relative URLs when inlining the client bundle ones (I think the former is safer?). https://github.com/sveltejs/kit/blob/4ae1cd152a60a22044ab3b8aa5572a2b79864583/packages/kit/src/exports/vite/index.js#L854