Files
svg-sprites/docs/en/guides/react-webpack.md
2026-07-14 16:11:39 +03:00

4.2 KiB

React Webpack SVG Sprite Quick Start

This guide targets the exact mode key react@webpack: a generated typed React component using Webpack 5 Asset Modules and CSS Modules.

1. Generate the sprite

No package installation and no package.json dependency are needed. npx downloads the CLI temporarily, and generated runtime does not import @gromlab/svg-sprites.

Keep the config adjacent to its source icons:

src/ui/icons/
├── icons/
│   ├── check.svg
│   └── folder.svg
└── svg-sprite.config.ts

Use a plain default object export with no package import:

// src/ui/icons/svg-sprite.config.ts
export default {
  mode: 'react@webpack',
  name: 'icons',
}

When input is omitted, SVG files are read from ./icons relative to the config. A .js config with a default export and a .json config are also supported. Generate directly with:

npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts

Use the exact Webpack 5 flags and generate once per invocation:

{
  "scripts": {
    "sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/ui/icons/svg-sprite.config.ts",
    "dev": "npm run sprites && webpack serve --mode development",
    "build": "npm run sprites && webpack --mode production"
  }
}

Do not add predev or prebuild hooks to these scripts; that would run generation twice. In CI, replace latest with an exact package version.

Generation creates a local .gitignore; commit that file once, but do not commit .svg-sprite/. Generated declarations are self-contained and do not require the package.

Production usage

Import the generated component and icon-name list directly:

// src/App.tsx
import {
  IconsIcon,
  iconsIconNames,
} from './ui/icons/.svg-sprite/index.js'

export function App() {
  return (
    <main>
      <IconsIcon icon="folder" width={24} height={24} aria-label="Files" />
      <small>{iconsIconNames.length} icons available</small>
    </main>
  )
}

The generated component uses new URL('../sprite.svg', import.meta.url), which Webpack 5 processes through Asset Modules and emits as a separate SVG asset. Exclude .svg-sprite/sprite.svg from SVG component or SVGR rules so they do not intercept that URL dependency.

The generated component also imports react-component.module.css. Configure .module.css through css-loader with modules enabled, plus style-loader or MiniCssExtractPlugin:

// webpack.config.js (relevant rule)
export default {
  module: {
    rules: [
      {
        test: /\.module\.css$/i,
        use: ['style-loader', { loader: 'css-loader', options: { modules: true } }],
      },
    ],
  },
}

2. Debug and preview

This section is optional. Only users who need the Viewer or icon previews should install:

npm install --save-dev @gromlab/svg-sprites

Use the React SpriteViewer bridge with a static loader array. Keep every import() path a string literal so Webpack can create the chunk:

// src/IconsDebugPage.tsx
import { SpriteViewer } from '@gromlab/svg-sprites/react'

const sources = [
  () => import('./ui/icons/.svg-sprite/svg-sprite.manifest.js'),
]

export function IconsDebugPage() {
  return <SpriteViewer sources={sources} title="Project icons" />
}

Keep this component on a debug route or in an internal tool. Viewer is not part of the production icon runtime.

3. Type the config

Choose one of these two paths.

With a local package installation

After installing the package locally, use the helper:

import { defineSpriteConfig } from '@gromlab/svg-sprites'

export default defineSpriteConfig({
  mode: 'react@webpack',
  name: 'icons',
})

You can alternatively import type SpriteConfig and apply satisfies SpriteConfig.

Without the package

Copy a mode-specific type directly into the config:

type LocalSpriteConfig = {
  mode: 'react@webpack'
  name?: string
  description?: string
  input?: string | string[]
  transform?: {
    removeSize?: boolean
    replaceColors?: boolean
    addTransition?: boolean
  }
  generatedNotice?: boolean
}

export default {
  mode: 'react@webpack',
  name: 'icons',
} satisfies LocalSpriteConfig