diff --git a/.changeset/ninety-dragons-carry.md b/.changeset/ninety-dragons-carry.md new file mode 100644 index 000000000000..bf6bf5189b9b --- /dev/null +++ b/.changeset/ninety-dragons-carry.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: update inline css url generation for FOUC prevention in dev diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 23c0fae2eeb0..3935daf28565 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -21,6 +21,8 @@ import { check_feature } from '../../../utils/features.js'; import { escape_html } from '../../../utils/escape.js'; const cwd = process.cwd(); +// vite-specifc queries that we should skip handling for css urls +const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/; /** * @param {import('vite').ViteDevServer} vite @@ -188,6 +190,7 @@ export async function dev(vite, vite_config, svelte_config) { // in dev we inline all styles to avoid FOUC. this gets populated lazily so that // components/stylesheets loaded via import() during `load` are included result.inline_styles = async () => { + /** @type {Set} */ const deps = new Set(); for (const module_node of module_nodes) { @@ -198,19 +201,12 @@ export async function dev(vite, vite_config, svelte_config) { const styles = {}; for (const dep of deps) { - const url = new URL(dep.url, 'dummy:/'); - const query = url.searchParams; - - if ( - (isCSSRequest(dep.file) || - (query.has('svelte') && query.get('type') === 'style')) && - !(query.has('raw') || query.has('url') || query.has('inline')) - ) { + if (isCSSRequest(dep.url) && !vite_css_query_regex.test(dep.url)) { + const inlineCssUrl = dep.url.includes('?') + ? dep.url.replace('?', '?inline&') + : dep.url + '?inline'; try { - query.set('inline', ''); - const mod = await vite.ssrLoadModule( - `${decodeURI(url.pathname)}${url.search}${url.hash}` - ); + const mod = await vite.ssrLoadModule(inlineCssUrl); styles[dep.url] = mod.default; } catch { // this can happen with dynamically imported modules, I think