---
title: "Custom Collections"
description: "Serve your own SVG files as an icon collection."
canonical_url: "https://nuxt-git-feat-module-docs-nuxt-js.vercel.app/modules/icon/guide/custom-collections"
---
# Custom Collections

> Serve your own SVG files as an icon collection.

You can use local SVG files to create a custom Iconify collection.

For example, place your icons' SVG files under a folder of your choice, for example, `./assets/my-icons`:

```bash
assets/my-icons
├── foo.svg
├── bar-outline.svg
```

In your `nuxt.config.ts`, add an item in `icon.customCollections`:

```ts
export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons',
        // if you want to include all the icons in nested directories:
        // recursive: true,
      },
    ],
  },
})
```

> [!NOTE]
> A relative `dir` is resolved from the directory of the project that declares it. When your project is used as an [extendable layer](https://nuxt.com/docs/4.x/getting-started/layers), the icons are loaded from the layer's own directory, not from the consuming project. Absolute paths, such as `createResolver(import.meta.url).resolve('./assets/my-icons')`, keep working as before.

> [!NOTE]
> If you are running on Nuxt 4 with the new `app` directory, the assets directory is `'./app/assets/*'` instead of `'./assets/*'`.

Then you can use the icons like this:

```vue
<template>
  <Icon name="my-icon:foo" />
  <Icon name="my-icon:bar-outline" />
</template>
```

You can also pass a full custom `IconifyJSON` object:

```ts
export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'paid-icons',
        icons: {
          'nuxt': { body: '<path d="M281.44 ... />' },
        },
        width: 512,
        height: 512,
      }
    ],
  },
})
```

Note that custom local collections require you to have a server to serve the API. When setting `ssr: false`, or when generating a static app using `nuxt generate` (which is equivalent to ssr: false), the provider will default to the Iconify API (which does not have your custom icons). If you want to build a SPA with server endpoints, you can explicitly set `provider: 'server'`:

```ts
export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  ssr: false,
  icon: {
    provider: 'server', // <-- this
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons'
      },
    ],
  },
})
```

## Disabling Runtime Fetching

Or if you want to disable the dynamic icon fetching completely and only use icons from the [client bundle](#client-bundle), you can set `provider: 'none'`:

```ts
export default defineNuxtConfig({
  icon: {
    provider: 'none',
    clientBundle: {
      scan: true,
      // ...or other bundle options
    },
  }
})
```

## Case Sensitive Custom Collections

Before `v1.10`, due to the limitation of Iconify's previous convention, all custom icons were normalized to `kebab-case` with a warning. Thanks to the updates on Iconify side, starting from `v1.10`, you can opt-in to use case-sensitive custom collections and by pass the normalization.

```ts
export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons',
        normalizeIconName: false, // <-- this
      },
    ],
  },
})
```

Which enable to use `assets/my-icons/FooBar.svg` as `my-icon:FooBar`, for example.

`normalizeIconName` is default to `true` for backward compatibility, and will be flipped in the future major version. See [#265](https://github.com/nuxt/icon/issues/265) for more context.


## Sitemap

See the full [sitemap](https://nuxt-git-feat-module-docs-nuxt-js.vercel.app/sitemap.md) for all pages.
