sensei icon indicating copy to clipboard operation
sensei copied to clipboard

SVG icon sprite not working when using a CDN

Open yscik opened this issue 3 years ago • 0 comments
trafficstars

Steps to Reproduce

  1. Configure WordPress to load assets from an external CDN
  2. Open a course page frontend
  3. See that Sensei icons are missing, and there is a CORS error in the console Security Error: Content at example.com may not load data from cdn.example.com/wp-content/plugins/sensei-lms/assets/dist/icons/sensei-sprite.svg?v=4.6.0.

Background

We package SVG icons at build time into one sprite file and use the SVG <use> element to pick icons from it: <svg><use xlink:href=".../sensei-sprite.svg#sensei-sprite-name"></use></svg>'

It is currently not possible to set up cross-origin rules for this element: Understanding CORS and SVG

Solutions

Add CDN exception for the file

Ask users to configure their CDN or plugin to serve this file directly, so it's not loaded from an external server with a different URL and not blocked by the same-origin policy.

Load the file with JS

Since AJAX requests can contain the needed crossorigin attributes, we can

  • Fetch the sprite file with a request in JS
  • Append it to the document in a new <svg> element
  • Icons can now be referenced only by id, since they are on the same page: <svg><use xlink:href="#sensei-sprite-name"></use></svg>

Pros/cons:

⊕ SVG can still be cached ⊖ Might take a flash of time for the JS to run and load the sprite

Render the sprite with PHP

We can also output the sprite in the HTML when rendering the page.

Pros/cons:

⊕ Simpler ⊖ No caching, the svg icons are adding bytes to every page request ⊕ Can be optimized to only serve the icons used on the page ⊖ Might require change to the assets build process too to not merge the icons into one file

yscik avatar Aug 02 '22 16:08 yscik