Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/poppa/sveltekit-svg

SvelteKit plugin that makes it possible to import SVG files as Svelte components, inline SVG code or urls
https://github.com/poppa/sveltekit-svg

svelte svelte3 svelte4 sveltekit sveltekit-plugin vite vite-plugin vitejs

Last synced: 2 months ago
JSON representation

SvelteKit plugin that makes it possible to import SVG files as Svelte components, inline SVG code or urls

Lists

README

        

# SvelteKit SVG Plugin

This plugin makes it possible to import SVG files as Svelte
components, inline SVG code or urls.

_NOTE! This plugin isn't just for SvelteKit, but works for any Svelte
project using Vite_

## Install

- `yarn add --dev @poppanator/sveltekit-svg`
- `npm install -D @poppanator/sveltekit-svg`

## Usage

In your `vite.config.js`

```js
import { sveltekit } from '@sveltejs/kit/vite'
import svg from '@poppanator/sveltekit-svg'

/** @type {import('vite').UserConfig} */
const config = {
plugins: [
sveltekit(),
svg(options), // Options are optional
],
}

export default config
```

You can also pass multiple `svg` transformers based on paths if you want to
apply different SVGO options for different SVGs

```js
const config = {
plugins: [
sveltekit(),
svg({
includePaths: ['./src/lib/icons/', './src/assets/icons/'],
svgoOptions: {
multipass: true,
plugins: [
{
name: 'preset-default',
// by default svgo removes the viewBox which prevents svg icons from scaling
// not a good idea! https://github.com/svg/svgo/pull/1461
params: { overrides: { removeViewBox: false } },
},
{ name: 'removeAttrs', params: { attrs: '(fill|stroke)' } },
],
},
}),
svg({
includePaths: ['./src/lib/graphics/'],
svgoOptions: {
multipass: true,
plugins: ['preset-default'],
},
}),
],
}
```

## Svelte usage

**Import as a Svelte component:**

> **NOTE!** It's recommended that you use the `?component` query string if you
> use the suggested type definition below. The reason is that **Vite** ships a
> type definition for `*.svg` which states that `import Comp from './file.svg`
> returns a string.
>
> So providing a default type definition for `*.svg` is in most cases causing
> a conflict which will lead to TSC errors when treating such an import as a
> Svelte component.
>
> So the best way to avoid errors, current and future, is to always use
> `import Comp from './file.svg?component` with the suggested type definition
> at the end of this file.

```svelte

import Logo from "./logo.svg?component";

```

When used as a component you can also pass attributes to the SVG

```svelte

```

**Import as file path:**

```svelte

import logoUrl from "./logo.svg?url";


```

**Import as data URL:**

```svelte

import logoDataUrl from "./logo.svg?dataurl";


```

In contrast to `?url` this will apply SVGO optimization/transform before the
the SVG is turned into a data URL

You can also pass the SVGO config option `datauri` as value to `?dataurl`.
This will, for instance, generate an URI encoded string

```svelte

import logoDataUrl from "./logo.svg?dataurl=enc";


```

**Import as code:**

```svelte

import logo from "./logo.svg?src";

{@html logo}
```

## Options

````ts
interface Options {
/**
* Output type
*
* `dataurl` can also take the following options, which are verbatim SVGO
* `datauri` options:
*
* - `?dataurl=base64` (default, same as `?dataurl`)
* - `?dataurl=enc` URL encoded string
* - `?dataurl=unenc` Plain SVG
*
* @default "component"
*/
type?: 'src' | 'url' | 'component' | 'dataurl'
/**
* Verbatim [SVGO](https://github.com/svg/svgo) options
*
* If no options are given, the SVG will be optimized with the default SVGO
* options.
* If `false` SVGO will be bypassed altogether
*/
svgoOptions?: Config | false
/**
* Paths to apply the SVG plugin on. This can be useful if you want to apply
* different SVGO options/plugins on different SVGs.
*
* The paths are path prefixes and should be relative to your
* `svelte.config.js` file.
*
* @example
* ```
* {
* includePaths: ['src/assets/icons/', 'src/images/icons/']
* }
* ```
*/
includePaths?: string[]
/**
* Hook that lets you transform the svg to a raw Svelte component yourself,
* before being passed to the Svelte compiler.
*
* @param rawSvg The raw SVG data as read from disk
* @param splitSvg The SVG split into parts, e.g its attributes and
* its content
* @returns This should return a complete Svelte component that can be passed
* to the Svelte compiler
*/
preCompileHook?(rawSvg: string, splitSvg: SplitSvg): string
}
````

## Notes on using with _Jest_

According to a report [_Jest_](https://jestjs.io/) will have trouble
transforming `.svg` files when such is imported as a Svelte component.

The solution seems to be to add a module name mapper entry in the the
`jest.config.cjs` file, like so:

```js
module.exports = {
// ... other config
moduleNameMapper: {
// ... other mappers
'^.+\\.svg$': '/src/lib/EmptyIcon.svelte',
},
}
```

where `src/lib/EmptyIcon.svelte` can contain just ``.

> [See the reported issue and solution](https://github.com/poppa/sveltekit-svg/issues/22)

## Typescript

For Typescript not to complain about `file.svg?component` et.al, add the
following import statement to `src/app.d.ts` (or any `.d.ts` file somewhere in the path of your
project where `tsc` can find it).

```ts
import '@poppanator/sveltekit-svg/dist/svg'
```