sveltekit-svg
sveltekit-svg copied to clipboard
SvelteKit plugin that makes it possible to import SVG files as Svelte components, inline SVG code or urls
SvelteKit SVG Plugin
This plugin makes it possible to import SVG files as Svelte components, inline SVG code or urls.
Install
yarn add --dev @poppanator/sveltekit-svgnpm install -D @poppanator/sveltekit-svg
Usage
In your vite.config.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
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:
<script>
import Logo from "./logo.svg";
</script>
<Logo />
When used as a component you can also pass attributes to the SVG
<Logo width="200" />
Import as file path:
<script>
import logoUrl from "./logo.svg?url";
</script>
<img src={logoUrl} />
Import as code:
<script>
import logo from "./logo.svg?src";
</script>
{@html logo}
Options
interface Options {
/**
* Output type
* @default "component"
*/
type?: 'src' | 'url' | 'component'
/**
* Verbatim [SVGO](https://github.com/svg/svgo) options
*/
svgoOptions?: svgo.OptimizeOptions
/**
* 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[]
}
Notes on using with Jest
According to a report Jest 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:
module.exports = {
// ... other config
moduleNameMapper: {
// ... other mappers
'^.+\\.svg$': '<rootDir>/src/lib/EmptyIcon.svelte',
},
}
where src/lib/EmptyIcon.svelte can contain just <svg />.
Typescript
For Typescript not to complain about file.svg?component et.al, add the
following to your application's global.d.ts. (global.d.ts is just an
arbitrary file. It can be named whatever and reside wherever as long as
your Typescript config recognize it)
declare module '*.svg' {
const content: any
export default content
}
declare module '*.svg?component' {
const content: any
export default content
}
declare module '*.svg?src' {
const content: string
export default content
}
declare module '*.svg?url' {
const content: string
export default content
}