Skip to content

fix: add crossorigin to SSR stylesheet links - #17404

Open
55Kamiryo wants to merge 2 commits into
sveltejs:mainfrom
55Kamiryo:fix/ssr-stylesheet-crossorigin
Open

55Kamiryo wants to merge 2 commits into
sveltejs:mainfrom
55Kamiryo:fix/ssr-stylesheet-crossorigin

Conversation

@55Kamiryo

Copy link
Copy Markdown

closes #17403

SvelteKit renders <link rel="stylesheet"> and the rel="preload"; as="style" Link header without crossorigin. Vite's preload helper and SvelteKit's own load_css request the same stylesheets with crossorigin. If paths.assets is on another origin and its server sends CORS headers only for requests with an Origin header, the browser can reuse the cached no-cors response for the CORS request and block the stylesheet. The issue has a reproduction.

This PR adds crossorigin to both. Without it on the Link header, the browser fetches the preload in no-cors mode and reuses that response for the <link crossorigin>, so the CSS fails on a full page load.

Tests: test/apps/options checks the SSR stylesheet links with a cross-origin paths.assets, and test/apps/options-2 checks the Link header with linkHeaderPreload. Both fail without the change.

After an upgrade, browsers reuse stylesheets cached by the previous version (without Access-Control-Allow-Origin) for the new <link crossorigin> until the file names change. Vite changed all CSS hashes once to handle this (vitejs/vite#18367). Should this PR do the same?

AI disclosure: Claude helped with the investigation, drafted this change and the tests, and helped with the English. I reviewed and tested everything myself.


Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

@pkg-svelte-dev

pkg-svelte-dev Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 6b93b41:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/6b93b41f79c346bc0f3f779ab897bb1ad82f20b1

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/17404

Note

This PR is from a fork. A maintainer must approve approve each commit before it can be built and installed.

@changeset-bot

changeset-bot Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6b93b41

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@kdelay kdelay left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side effect worth noting: with crossorigin on the SSR stylesheet link, a cross-origin paths.assets must send Access-Control-Allow-Origin for CSS on initial load too.

CSR pages already need that, since the JS chunks are module scripts from the same origin. A csr = false page has none, so its CSS loads today from a bucket with no CORS config and would be blocked after this.

Probably fine, but worth a line in the changeset and the paths.assets docs (which don't mention CORS) so people know to add the header.

@teemingc teemingc added the needs-platform-tests This PR needs to run platform tests in order to merge. label Oct 12, 2026
@svelte-docs-bot

Copy link
Copy Markdown

@55Kamiryo

Copy link
Copy Markdown
Author

@kdelay Thanks for your review. Right now a csr = false page can load its CSS from a bucket without CORS headers, and this change breaks that. I added a note to the changeset and to the paths.assets docs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-platform-tests This PR needs to run platform tests in order to merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Browsers can block stylesheets from a cross-origin paths.assets after client-side navigation

3 participants