vnphanquang / svelte-put

Useful svelte stuff to put in your projects
https://svelte-put.vnphanquang.com
MIT License
836 stars 25 forks source link

preprocess-inline-svg does not decode `&` when inlining SVGs #322

Closed SizableShrimp closed 1 month ago

SizableShrimp commented 3 months ago

When inlining SVGs, preprocess-inline-svg does not decode the HTML entity & into &, which .svelte files support. Svelte files do not decode & into &, so it must be done by this inlining process. This is especially apparent when using a URL in an SVG that needs an ampersand as a query parameter. When inlining, the ampersand is not decoded, so the query is ruined because the URL is resolved including &. Here is a demo SVG:

<?xml version="1.0"?>
<svg width="1" height="1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style type="text/css">
      @import url('https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic&amp;display=swap');
    </style>
  </defs>
</svg>

When used in combination with preprocess-inline-svg, you can look in the Network tab of your browser's dev tools to see that the queried URL does not properly have &display=swap, meaning the queried URL & returned data is incorrect.

Here is a simple workaround I found in the time being to circumvent this issue (placed in svelte.config.js):

import * as preprocess_svg from '@svelte-put/preprocess-inline-svg'

function customInlineSvg(sources, inlineConfig) {
  const rSources = preprocess_svg.resolveSources(sources)
  const rConfig = preprocess_svg.resolveInlineSvgConfig(inlineConfig)

  return {
    markup({ content, filename }) {
      const transformed = preprocess_svg.transform(
        content,
        filename,
        rSources,
        rConfig
      )
      // Replace &amp; with & because .svelte files will not decode it for us
      transformed.code = transformed.code.replace(/&amp;/g, '&')
      return transformed
    }
  }
}

Then, use customInlineSvg in place of inlineSvg in the config, like so:

/** @type {import('@sveltejs/kit').Config} */
const config = {
  // Consult https://kit.svelte.dev/docs/integrations#preprocessors
  // for more information about preprocessors
  preprocess: [
    customInlineSvg([
      { directories: 'static' }
    ]),
    // ...
  ],
  // ...
vnphanquang commented 3 months ago

Thank you @SizableShrimp . Will look into this.

vnphanquang commented 1 month ago

Should be fixed in @svelte-put/preprocess-inline-svg@2.1.4. Thanks again for reporting!