@svelte-put/preprocess-inline-svg GitHub

svelte preprocessor to inline static svg at build time

@svelte-put/preprocess-inline-svg @svelte-put/preprocess-inline-svg @svelte-put/preprocess-inline-svg changelog

Introduction

Current solutions (that I know of) for inlining SVGs in Svelte land require either runtime logics or a component-oriented strategy. These solutions are acceptable in most cases but have been proven to be problematic when additional styling / attributes are needed for the inlined svg element.

This package tries to achieve zero runtime footprint with no additional component. The idea is to enable this:

minimal usage api

<svg data-inline-src="google/info"></svg>

which will automatically read from the source svg and inline it at build time. Additional styling and attributes can now be added idiomatically as with any other html element.

Prior Art

Runtime Solution

This processor is best for static svgs like icons and pictograms. For dynamic svgs (i.e loaded from network), use @svelte-put/inline-svg - an action-based strategy with a similar api.

runtime alternative

<svg use:inlineSrc={'https://example.com/icon.svg'}></svg>

This preprocessor package is also re-exported from @svelte-put/inline-svg for convenience. If you find yourself needing both runtime & build time solutions, just install @svelte-put/inline-svg .

runtime alternative

import inlineSvg from '@svelte-put/inline-svg/preprocess'

Installation

terminal

npm install --save-dev @svelte-put/preprocess-inline-svg

Quick Start

Given the following (svelte.config.js)

quick start - config

import inlineSvg from '@svelte-put/preprocess-inline-svg';

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: [
    // input to `inlineSvg` can be either a single object or an array of such
    inlineSvg([
      {
        directories: 'src/assets/icons',
        attributes: {
          class: 'icon',
          width: '20',
          height: '20',
        },
      },
      {
        directories: 'src/assets/pictograms',
      },
    ]),
    // other preprocessors
  ],
};
export default config;

and the asset files as follow

quick start - assets

src/assets
    |
    |-- icons
         |-- svelte.svg
         |
         |-- google
               |-- arrow-right.svg
         |-- simpleicons
               |-- github.svg
    |
    |-- pictograms
         |-- diagram.svg

we can now do

quick start - usage

<!-- this will have width="20" height="20" as specified in the config -->
<svg data-inline-src="svelte" />

<!-- nested -->
<svg data-inline-src="google/arrow-right.svg" />
<!-- .svg can be omitted -->
<svg data-inline-src="simpleicons/github" />

<!-- with custom attributes -->
<svg data-inline-src="diagram" width="100" height="100" />

<!-- alternatively, you can provide a per-case path that is relative to the current source file -->
<svg data-inline-src="./local-icon.svg" />

<!-- if the source svg is not found for any of the above, an error will be thrown -->

The .svg extension may be omitted from the path provided to data-inline-src.

Attributes & Inner HTML

Attributes provided to the source svg element will be kept after build and override the existed ones in the inlined SVG.

merging attributes

<svg data-inline-src="path/icon" width="100" height="100" class="c-icon"></svg>

InnerHTML of the source svg element will be replaced with the that from the inlined SVG.

merging attributes

<svg data-inline-src="path/icon">anything in here will be replaced</svg>

If you have a use case where it is useful to append/prepend the innerHTML of inlined SVGs rather than replace it, please raise an issue over at github . For now, let's keep things simple.

Limitations

preprocess-inline-svg only works in svelte markup, i.e in the template part of svelte source files. The following will not work

only support svelte markup

<script>
  let html = `<svg data-inline-src="path/icon"></svg>`;
</script>

{@html html}

preprocess-inline-svg does not support data-inline-src as a variable. I.e, the following will not work

dynamic attribute is not support

<script lang="ts">
  export let icon: string;
</script>

<svg data-inline-src={icon} />

This is because it is difficult for the preprocessor to analyze the variable to determine is immutability at build time, i.e the variable is meant to be changed. In these case, some workarounds are

  • use if-else statements to switch between different data-inline-src as literal strings, or
  • use @svelte-put/inline-svg as a runtime action-based strategy instead.

If you have an idea for improvements, please raise an issue over at github . Thanks!

Customization

All options are optional. By default inline-svg can be used with no config at all, in which case svg source paths are resolved relative to the svelte source file it is specified in.

Note that path alias is not supported in data-inline-src! For example, "$lib/src/assets/..." will not work.

Alternatively, the directories option can be specified (as seen in the "Quick Start" section) to conveniently omit the need for verbose pathnames.


Input to inline-svg can be provided as a single object, or an array of such (as seen in the "Quick Start" section), helpful for organization purposes or when different configurations are needed for different directories.

When input is an array of configs, the following applies:

There can only one config object without the directories option (default config).
If multiple are found, an error will be thrown at build. If none is provided, the internal default config is used.

Each svg source will then be searched top down in the config until a match is found, or else an error will be thrown.

Local svg (local to svelte source file) always has the highest priority and will use default config as described above.


Option

Description

directories

directories relative to which the svg source paths will be resolved.
type: string[] | string
default: []

attributes

default attributes to add to the svg element, will override the attributes from the svg source, but be overridden by the attributes from the element itself (in svelte source)
type: Record<string, string>
default: {}

serializeOptions

options for hast-util-to-html during serialization
type: Object
default: { space: 'svg', allowDangerousCharacters: true }

inlineSrcAttributeName

the attribute to get the svg source from
type: string
default: 'data-inline-src'

keepInlineSrcAttribute

whether to keep the inline src attribute after build (for reference, for example)
type: boolean
default: false

Further Work

This package is kept minimal as it has served its purpose for all of my need. If you find this package to lack certain features / support essential to your use cases, please file an issue at github and let me know. Thank you!

Some possibilities:

  • Support for svgo?
  • Support for fetching remote svg in data-inline-src at build time?
  • Make this into a vite plugin and do these inline operation as part of the pre-rendering pipeline?

API Reference

The best documentation is no documentation!

It is recommended to utilize editor intellisense & explore in-code documentation while using the package .

See the extracted API Reference on github.

API extraction is powered by @microsoft/api-extractor and @microsoft/api-documenter ).

Edit this page on GitHub