Skip to content

Crossorigin attribue for stylesheets #528

@zangab

Description

@zangab

Description 📖

Similar issue as #189

Our problem is related to this github issue.
Everything worked fine until we recently updated vite & vite-ruby. We host our assets on S3, however we do have CORS issues on Chrome/Chromium. The reason is a change in Vite.

The result is a stylesheet beeing loaded twice, one time with the crossorigin attribute (due to async component, f.e.) and one time without (component is bundled, not in a separate chunk).

Example:

  • component B is a sub-component of A that is directly bundled
  • component B is also a sub-component of C that is defined as an async component (we use Vue)

The stylesheet of component B is then inserted by vite-ruby in the <head> via:

<!-- Vite rails stylesheet via vite_javascript_tag (not preloaded), by component A -->
<link rel="stylesheet" src="cdn.blabla.test/component-b-css-123123.css">

<!-- Vite preload, by component C -->
<link rel="stylesheet" crossorigin src="cdn.blabla.test/component-b-css-123123.css">

The CORS policy of chrome then blocks the second request because the origin header is now there which wasn't the case before. Imho an easy fix would be that we could add the crossorigin attribute to the stylesheets as well within the tag helpers. Unfortunately, this is currently not possible within vite-ruby.

Vite however adds the crossorigin attribtue to stylesheets by default therefore the implementations diverge. Responsible source code in Vite

Part within the tag helpers that would need a change:

  def vite_javascript_tag(*names,
    type: "module",
    asset_type: :javascript,
    skip_preload_tags: false,
    skip_style_tags: false,
    crossorigin: "anonymous",
    media: "screen",
    **options)
    entries = vite_manifest.resolve_entries(*names, type: asset_type)
    tags = javascript_include_tag(*entries.fetch(:scripts), crossorigin: crossorigin, type: type, extname: false, **options)
    tags << vite_preload_tag(*entries.fetch(:imports), crossorigin: crossorigin, **options) unless skip_preload_tags

    options[:extname] = false if Rails::VERSION::MAJOR >= 7

    # here we would need to also pass the crossorigin param
    # see https://github.com/ElMassimo/vite_ruby/blob/main/vite_rails/lib/vite_rails/tag_helpers.rb#L52
    tags << stylesheet_link_tag(*entries.fetch(:stylesheets), media: media, **options) unless skip_style_tags

    tags
  end

Best would be to use a flag if the crossorigin attribute should be applied to the stylesheet tags or not. This would prevent a change to the current behavior.

Reproduction 🐞

Vite Ruby Info

Run bin/rake vite:info and provide the output:

Running via Spring preloader in process 125
bin/vite present?: true
vite_ruby: 3.9.1
vite_rails: 3.0.19
rails: 7.1.5.1
ruby: ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [x86_64-linux]
node: v20.17.0
yarn: 1.22.22

installed packages:
atalanda@1.0.0 /usr/src/app
├─┬ @vitejs/plugin-vue@5.2.1
│ └── vite@5.4.14 deduped
├─┬ vite-plugin-ruby@5.1.1
│ └── vite@5.4.14 deduped
├─┬ vite-plugin-sass-glob-import@5.0.0
│ └── vite@5.4.14 deduped
├── vite@5.4.14
└─┬ vitest@0.34.6
  ├─┬ vite-node@0.34.6
  │ └── vite@4.5.0
  └── vite@4.5.0

Screenshots 📷

Image
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug: pending triageSomething doesn't seem to be working, but hasn't been verified

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions