npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nuxt-svg-icon-module

v1.5.1

Published

Nuxt module for lazy-loading inline SVG icons from your assets directory

Downloads

1,255

Readme

nuxt-svg-icon-module

npm version npm downloads License: MIT Nuxt

Nuxt module for lazily loading inline SVG icons straight from your assets/ directory. Icons inherit currentColor automatically so they fit naturally into any design system.

Features

  • Lazy-loaded — each SVG is loaded on demand via import.meta.glob, no upfront bundle cost
  • Inline SVG — full CSS control: color, stroke, fill, width, height
  • currentColor by default — icons follow the text color of their container
  • Subdirectory support — organise icons into folders: <Icon name="social/github" />
  • Reactive — changing the name prop swaps the icon without a page reload
  • SSR-safe — uses useAsyncData with a unique key per instance, no hydration mismatches
  • Configurable — custom icons directory, component name, and CSS prefix
  • Automatic optimization — SVGs are optimized via SVGO at build time (configurable or opt-out)

Compatibility

| nuxt-svg-icon-module | Nuxt | Node.js | |---------------|-------|---------| | ^1.0.0 | ^3.10 \|\| ^4.0 | >=18 |

Setup

# pnpm
pnpm add nuxt-svg-icon-module

# npm
npm install nuxt-svg-icon-module

# yarn
yarn add nuxt-svg-icon-module
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-svg-icon-module'],
})

That's it. The <Icon> component is now available everywhere in your app — no imports needed.

Usage

Place your SVG files in assets/icons/:

assets/
  icons/
    check.svg
    close.svg
    social/
      github.svg
      twitter.svg

Use the component anywhere:

<!-- Basic usage -->
<Icon name="check" />

<!-- Preserves original SVG colors -->
<Icon name="check" filled />

<!-- Subdirectory -->
<Icon name="social/github" />

<!-- Dynamic name -->
<Icon :name="currentIcon" />

Icons inherit color from their parent:

<p style="color: tomato;">
  <Icon name="check" /> Done
</p>

By default icons are 1em × 1em. To set a fixed size, apply width and height directly on the component or wrap it in a container:

<!-- square icon -->
<Icon name="check" style="width: 24px; height: 24px" />

<!-- non-square icon -->
<Icon name="logo" style="width: 124px; height: 40px" />

<!-- via a wrapper -->
<div style="width: 124px; height: 40px">
  <Icon name="logo" />
</div>

Configuration

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-svg-icon-module'],

  svgIcon: {
    // Directory containing SVG files, relative to project root
    iconsDir: 'assets/icons', // default

    // Name of the globally registered component
    componentName: 'Icon', // default

    // CSS class prefix applied to the wrapper <span>
    prefix: 'icon', // default

    // Automatically optimize SVGs via SVGO at build time
    optimize: true, // default

    // Custom SVGO configuration (see https://svgo.dev/docs/configuration/)
    svgoConfig: {}, // default
  },
})

Props

| Prop | Type | Default | Description | |----------|-----------|---------|----------------------------------------------------------------| | name | string | — | Icon path relative to iconsDir, without .svg extension | | filled | boolean | false | When true, preserves the SVG's original fill and stroke colors | | label | string | — | Accessible label announced by screen readers. When omitted, the icon is hidden from assistive technologies (aria-hidden="true") |

Accessibility

By default, icons are decorative and hidden from screen readers via aria-hidden="true". When an icon carries meaning, pass the label prop — the icon will be announced by assistive technologies:

<!-- decorative — screen readers skip this -->
<Icon name="check" />

<!-- meaningful — screen readers announce "Close dialog" -->
<Icon name="close" label="Close dialog" />

TypeScript: IconName type

The module generates an IconName type — a string union of every icon name derived from your iconsDir at build time. It is automatically available in vue component props via the global components augmentation, and can also be imported explicitly:

import type { IconName } from 'nuxt-svg-icon-module'

const icon = ref<IconName>('check')

This gives you autocomplete and type-safety wherever you pass an icon name — in scripts, composables, or typed component props.

If no SVG files are found in iconsDir, IconName falls back to string.

How it works

The component uses Vite's import.meta.glob with the ?raw query to import SVG files as plain strings at build time. At runtime:

  1. The component calls useAsyncData with a key unique per instance (via useId) and icon name — so multiple <Icon name="check" /> on the same page share one request but never conflict
  2. The raw SVG string is injected via v-html inside a <span> wrapper
  3. If the SVG contains a stroke attribute (and filled is not set), .icon_stroke is applied — making stroke inherit currentColor. Otherwise .icon_fill is applied for fill
  4. The filled prop skips both classes, leaving the SVG colors untouched

Only icons that are actually rendered get bundled — unused SVGs are tree-shaken automatically.

Security note: SVG content is injected via v-html. Never pass untrusted or user-supplied SVG strings through this component — only serve icons from your own iconsDir. Injecting arbitrary SVG can lead to XSS attacks.

Contributing

# clone and install
git clone https://github.com/markgareev/nuxt-svg-icon-module.git
cd nuxt-svg-icon-module
pnpm install

# prepare stubs and start playground
pnpm dev:prepare
pnpm dev

# run tests
pnpm test

# lint
pnpm lint

Pull requests are welcome. For major changes, please open an issue first.

License

MIT