docs: обновить документацию generated-контракта

- описаны единая конфигурация и exact modes
- обновлена структура .svg-sprite
- удалены материалы legacy pipeline
- синхронизированы русская и английская версии skill
This commit is contained in:
2026-07-13 20:07:42 +03:00
parent f4f464a568
commit 7992adc9d3
55 changed files with 618 additions and 2168 deletions

View File

@@ -1,102 +0,0 @@
# Legacy mode
[← Back to home](../../README.md)
A quick guide to generating centralized SVG sprites in `symbol` and `stack` formats, with an optional HTML preview.
## 1. Install the package
```bash
npm install --save-dev @gromlab/svg-sprites
```
## 2. Prepare the icons and config
```text
project/
├── src/assets/icons/
│ ├── check.svg
│ └── folder.svg
└── svg-sprites.config.ts
```
```ts
// svg-sprites.config.ts
import { defineLegacyConfig } from '@gromlab/svg-sprites'
export default defineLegacyConfig({
output: 'public/sprites',
preview: true,
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'symbol',
},
],
})
```
## 3. Add generation
```json
{
"scripts": {
"sprites": "svg-sprites --mode legacy .",
"prebuild": "npm run sprites"
}
}
```
Run the local package through the script:
```bash
npm run sprites
```
Result:
```text
public/sprites/
├── icons.sprite.svg
└── preview.html
```
With `preview: false`, the HTML file is not created. For the `stack` format, specify `format: 'stack'`.
## 4. Use the symbol sprite
```html
<svg width="24" height="24" aria-label="Done">
<use href="/sprites/icons.sprite.svg#check"></use>
</svg>
```
## Multiple sprites
Add multiple entries to `sprites`:
```ts
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'symbol',
},
{
name: 'logos',
input: 'src/assets/logos',
format: 'stack',
},
]
```
All output files and the shared `preview.html` will be written to `output`.
## Troubleshooting
- Config not found: make sure `svg-sprites.config.ts` is located in the specified root directory.
- No icons: check `sprites[].input` and the `.svg` extension.
- Preview not needed: set `preview: false`.
For programmatic use, see [`generateLegacy`](programmatic-api.md#generatelegacy).

View File

@@ -1,122 +0,0 @@
# Migrating from 0.1.x to 1.0
[← Back to home](../../README.md)
Version 1.0 separates local generation for React and Next.js from the centralized legacy mode. The old config cannot be mixed with the new API in a single CLI invocation.
## Installation
Install the package as a development dependency so the migration uses the version recorded in the project lockfile:
```bash
npm install --save-dev @gromlab/svg-sprites
```
## CLI
The CLI now always requires an explicit `--mode` and a path to the configuration directory:
```text
"sprites": "svg-sprites"
→ "sprites": "svg-sprites --mode <mode> <path>"
```
Choose a mode based on your environment:
| Environment | Mode |
|---|---|
| React + Vite | `react@vite` |
| React + Webpack 5 | `react@webpack` |
| Next.js App Router + Turbopack | `next@app/turbopack` |
| Next.js App Router + Webpack 5 | `next@app/webpack` |
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
| Centralized legacy setup | `legacy` |
## React and Next.js
Instead of a root-level `svg-sprites.config.ts`, create a local `svg-sprite.config.ts` next to the icon set:
```ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
name: 'global',
inputFolder: './icons',
})
```
For regular React, use `defineReactSpriteConfig`. A folder and an explicit list of shared SVG files can be combined using `inputFolder` and `inputFiles`.
Add the local CLI with the selected mode to `package.json`, for example:
```json
{
"scripts": {
"sprite:global": "svg-sprites --mode next@app/turbopack src/ui/global/svg-sprite"
}
}
```
Run it with `npm run sprite:global` before importing the generated component.
The old `publicPath` and `react` options are no longer needed. The generated module is created next to the config and adds its own `.gitignore`, while Vite, Webpack, or Next.js emits the SVG as a separate asset with a content hash.
The `<SvgSprite icon="..." />` component is replaced by a component whose name is derived from `name`:
```tsx
<GlobalIcon icon="check" />
```
To browse the icons, add `<SpriteViewer>` as a debug page in the application. A separate `preview.html` is available only in legacy mode.
## Legacy mode
If you need to preserve the centralized structure, rename the helper and the format fields:
```ts
import { defineLegacyConfig } from '@gromlab/svg-sprites'
export default defineLegacyConfig({
output: 'public/sprites',
preview: true,
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'stack',
},
],
})
```
- `defineConfig` has been replaced with `defineLegacyConfig`;
- `sprites[].mode` has been renamed to `sprites[].format`;
- `generate` has been replaced with `generateLegacy`;
- `loadConfig` has been replaced with `loadLegacyConfig`;
- `publicPath` and generation of the old shared React component have been removed.
Add the local CLI to `package.json`:
```json
{
"scripts": {
"sprites": "svg-sprites --mode legacy ."
}
}
```
Run it with `npm run sprites`.
## Programmatic API
The package is distributed as ESM only. Replace `require()` with `import`.
`compileSpriteContent` now returns `Promise<Uint8Array>` so that the public declarations do not require `@types/node` to be installed. In Node.js, the actual result is compatible with APIs that accept `Uint8Array`.
## After migration
1. Add an explicit generation command before `dev`, `build`, and `typecheck`.
2. Generate the new output and run type checking while the old artifacts are still available.
3. Replace imports and verify the icons and color variables using `SpriteViewer` or the legacy `preview.html`.
4. Only then remove confirmed old generated files and obsolete ignore rules without deleting source SVGs.

View File

@@ -22,19 +22,28 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@app/turbopack',
name: 'file-manager',
description: 'File manager icons',
})
```
The root barrel is application-owned:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
## 3. Add generation
For Turbopack:
@@ -42,7 +51,7 @@ For Turbopack:
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager"
}
@@ -85,7 +94,7 @@ The viewer is interactive, so it requires a separate Client Component boundary:
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('@/ui/file-manager/svg-sprite/manifest'),
() => import('@/ui/file-manager/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
]
export default function SpritesPage() {

View File

@@ -22,25 +22,34 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@pages/webpack',
name: 'file-manager',
description: 'File manager icons',
})
```
The root barrel is application-owned:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
## 3. Add generation
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager"
}
@@ -77,7 +86,7 @@ The component works the same way with SSR, SSG, and client-side navigation. Next
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('@/ui/file-manager/svg-sprite/manifest'),
() => import('@/ui/file-manager/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
]
export default function SpritesPage() {

View File

@@ -2,100 +2,65 @@
[← Back to home](../../README.md)
The package provides a main Node.js entry point and a separate React runtime entry point. Both are distributed as ESM only and must be loaded with `import`.
The package is ESM-only and provides one Node.js generation API. The React runtime with `SpriteViewer` is available from the separate `@gromlab/svg-sprites/react` entry point.
To resolve `@gromlab/svg-sprites/react` in TypeScript, use `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`.
## Main entry point
## `generateSprite`
```ts
import {
defineNextSpriteConfig,
defineReactSpriteConfig,
generateNextSprite,
generateReactSprite,
} from '@gromlab/svg-sprites'
```
import { generateSprite } from '@gromlab/svg-sprites'
The main entry point does not import React and can be used in CLIs, build scripts, and Node.js tools.
## `generateReactSprite`
```ts
import { generateReactSprite } from '@gromlab/svg-sprites'
const result = await generateReactSprite(
'src/ui/file-manager/svg-sprite',
'vite',
const result = await generateSprite(
'src/ui/file-manager/svg-sprite/svg-sprite.config.ts',
)
```
The second argument is required:
The first argument accepts the full path to an explicitly selected `.ts`, `.js`, or `.json` config file with any name. Passing a directory enables config-less mode and uses that directory as the sprite module root.
The second argument contains optional overrides and always takes precedence over the config:
```ts
type ReactAssetTarget = 'vite' | 'webpack'
```
Result:
```ts
type ReactSpriteGenerationResult = {
name: string
rootDir: string
generatedDir: string
spritePath: string
manifestPath: string
iconCount: number
target: 'vite' | 'webpack'
}
```
```ts
console.log(result.name)
console.log(result.iconCount)
console.log(result.spritePath)
console.log(result.manifestPath)
```
The function loads `svg-sprite.config.ts` from the specified root, compiles the SVG files, and safely updates managed files.
## `generateNextSprite`
```ts
import { generateNextSprite } from '@gromlab/svg-sprites'
const result = await generateNextSprite(
'src/ui/file-manager/svg-sprite',
{
router: 'app',
bundler: 'turbopack',
await generateSprite('src/ui/file-manager/svg-sprite/custom-config.json', {
mode: 'react@webpack',
name: 'documents',
inputFolder: './assets',
inputFiles: ['../../shared/search.svg'],
transform: {
addTransition: false,
},
)
generatedNotice: false,
})
```
Available values:
Configuration is resolved in this order:
```ts
type NextSpriteGenerationOptions = {
router: 'app' | 'pages'
bundler: 'turbopack' | 'webpack'
}
```text
defaults → config → API overrides
```
The result also contains the selected `router`, `bundler`, and the full target in the form `next@app/turbopack`.
## `defineReactSpriteConfig`
For fully programmatic generation, pass a directory and provide the required settings as overrides:
```ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
await generateSprite('src/ui/file-manager/svg-sprite', {
mode: 'react@vite',
name: 'file-manager',
inputFiles: [
'../../shared/search.svg',
'../../shared/settings.svg',
],
})
```
export default defineReactSpriteConfig({
## Configuration
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'react@vite',
name: 'file-manager',
description: 'File manager icons',
inputFolder: './icons',
inputFiles: [
'../../shared/icons/check.svg',
],
inputFiles: ['../../shared/check.svg'],
transform: {
removeSize: true,
replaceColors: true,
@@ -105,99 +70,54 @@ export default defineReactSpriteConfig({
})
```
`inputFolder` and `inputFiles` are combined. The helper returns the configuration without runtime transformations and provides TypeScript autocomplete.
`defineSpriteConfig` is an identity helper for TypeScript autocomplete. JavaScript can export the same object with `export default`, while JSON contains the object directly.
## `defineNextSpriteConfig`
## Specialized wrappers
The specialized functions are available as wrappers around `generateSprite`:
```ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { generateNextSprite, generateReactSprite } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
name: 'file-manager',
description: 'File manager icons',
inputFolder: './icons',
await generateReactSprite('path/to/config.ts', 'vite')
await generateNextSprite('path/to/config.ts', {
router: 'app',
bundler: 'turbopack',
})
```
Next.js uses the same configuration contract as the React presets.
An explicitly supplied target overrides `mode` from the file. Prefer `generateSprite` in new code.
## `generateLegacy`
## Config API
```ts
import { generateLegacy } from '@gromlab/svg-sprites'
const results = await generateLegacy({
output: 'public/sprites',
preview: false,
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'symbol',
},
],
})
import {
loadSpriteConfig,
resolveSpriteConfig,
validateSpriteConfig,
} from '@gromlab/svg-sprites'
```
Returns an array:
- `loadSpriteConfig(file)` loads an explicitly selected `.ts`, `.js`, or `.json` file.
- `validateSpriteConfig(value)` performs runtime validation.
- `resolveSpriteConfig(root, config, overrides)` merges values, applies defaults, and resolves paths relative to `root`.
```ts
type SpriteResult = {
name: string
format: 'symbol' | 'stack'
spritePath: string
iconCount: number
}
```
For details, see [Legacy mode](legacy.md).
## Low-level functions
The main entry point also exports:
## Low-level compiler
```ts
import {
compileSprite,
compileSpriteContent,
createShapeTransform,
generatePreview,
loadLegacyConfig,
loadReactSpriteConfig,
resolveSpriteEntry,
resolveSprites,
} from '@gromlab/svg-sprites'
```
These functions are intended for custom orchestration built on top of the existing compiler and writer. For standard usage, prefer `generateReactSprite` and `generateLegacy`.
These functions are intended for custom orchestration. Standard generation should use `generateSprite`.
## React runtime entry point
## React runtime
```tsx
import { SpriteViewer } from '@gromlab/svg-sprites/react'
```
Types:
```ts
import type {
SpriteManifest,
SpriteManifestColor,
SpriteManifestIcon,
SpriteManifestLoader,
SpriteManifestModule,
SpriteViewerColorTheme,
SpriteViewerProps,
SpriteViewerSource,
SpriteViewerSources,
} from '@gromlab/svg-sprites/react'
```
The React entry point contains `'use client'` and is intended for debug tools. Generated production components are imported from the application's local sprite modules, not from the package's React entry point.
`SpriteViewerProps.colorTheme` accepts `auto | light | dark`. The default is `auto`, which follows `prefers-color-scheme`; to synchronize it with the application theme, pass the computed `light` or `dark` value.
## Related guides
- [React + Vite](react-vite.md)
- [React + Webpack 5](react-webpack.md)
`SpriteViewer` accepts generated manifests, lazy loaders, or an `import.meta.glob` result. This entry point contains `'use client'` and is intended for debug tools; production components are imported from local sprite modules.

View File

@@ -19,6 +19,7 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
@@ -28,24 +29,32 @@ Place the source SVG files in `icons/`.
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineReactSpriteConfig({
export default defineSpriteConfig({
mode: 'react@vite',
name: 'file-manager',
description: 'File manager icons',
})
```
The root barrel is application-owned and explicitly re-exports the generated API:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite.
The complete list of options is available under [React and Next.js configuration](reference.md#react-and-nextjs-configuration).
The complete list of options is available under [Unified configuration](reference.md#unified-configuration).
## 4. Add generation to package.json
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager",
"pretypecheck": "npm run sprite:file-manager"
@@ -96,7 +105,7 @@ import { SpriteViewer } from '@gromlab/svg-sprites/react'
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
const sources = import.meta.glob<SpriteManifestModule>(
'/src/**/svg-sprite/manifest.ts',
'/src/**/svg-sprite/.svg-sprite/svg-sprite.manifest.js',
)
export const IconsDebugPage = () => (
@@ -104,13 +113,13 @@ export const IconsDebugPage = () => (
)
```
Vite automatically finds the generated `manifest.ts` for each React sprite. The `import.meta.glob` pattern must be a string literal, and generation must run before Vite starts.
Vite automatically finds the generated manifest for each React sprite. The `import.meta.glob` pattern must be a string literal, and generation must run before Vite starts.
Only include the Viewer on a debug route or in an internal tool.
## Troubleshooting
- Missing `index.ts`: run `npm run sprite:file-manager`.
- The Viewer cannot find the sprite: check the glob path and make sure `manifest.ts` exists.
- Missing `.svg-sprite/index.js`: run `npm run sprite:file-manager`.
- The Viewer cannot find the sprite: check the glob path to `.svg-sprite/svg-sprite.manifest.js`.
- `Refusing to overwrite a user file` error: there is a user file at a generated path.
- The icon does not change color: use `color` or `--icon-color-N`.

View File

@@ -19,6 +19,7 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
@@ -28,24 +29,32 @@ Place the source SVG files in `icons/`.
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineReactSpriteConfig({
export default defineSpriteConfig({
mode: 'react@webpack',
name: 'file-manager',
description: 'File manager icons',
})
```
The root barrel is application-owned and explicitly re-exports the generated API:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
By default, SVG files are loaded from `./icons`. You can add shared icons from other directories through `inputFiles`: the directory and file list are combined into a single sprite.
The complete list of options is available under [React and Next.js configuration](reference.md#react-and-nextjs-configuration).
The complete list of options is available under [Unified configuration](reference.md#unified-configuration).
## 4. Add generation to package.json
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager",
"pretypecheck": "npm run sprite:file-manager"
@@ -87,7 +96,7 @@ Webpack processes the generated `new URL('./sprite.svg', import.meta.url)` throu
If the project already uses a custom SVG loader, make sure it does not intercept the generated `sprite.svg` instead of Asset Modules.
The generated component imports `styles.module.css`, so Webpack must process CSS Modules through `css-loader` and `style-loader` or `MiniCssExtractPlugin`. If the TypeScript project does not include a declaration for CSS Modules, add one separately.
The generated component imports `react/react-component.module.css`, so Webpack must process CSS Modules through `css-loader` and `style-loader` or `MiniCssExtractPlugin`. If the TypeScript project does not include a declaration for CSS Modules, add one separately.
## 6. Add a debug page
@@ -97,8 +106,8 @@ Webpack does not support Vite's `import.meta.glob` API, so provide static loader
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('./ui/file-manager/svg-sprite/manifest'),
() => import('./ui/navigation/svg-sprite/manifest'),
() => import('./ui/file-manager/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('./ui/navigation/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
]
export const IconsDebugPage = () => (
@@ -112,8 +121,8 @@ Only include the Viewer on a debug route or in an internal tool.
## Troubleshooting
- Missing `index.ts`: run `npm run sprite:file-manager`.
- The Viewer does not load the sprite: check the path in `import()` and make sure `manifest.ts` exists.
- Missing `.svg-sprite/index.js`: run `npm run sprite:file-manager`.
- The Viewer does not load the sprite: check the `import()` path to `.svg-sprite/svg-sprite.manifest.js`.
- Incorrect asset URL: check `output.publicPath`.
- Another loader intercepts the SVG: exclude the generated sprite from the incompatible rule.

View File

@@ -8,7 +8,6 @@ Reference for the configuration, generated API, and behavior of `@gromlab/svg-sp
- [Next.js Pages Router](next-pages.md)
- [React + Vite](react-vite.md)
- [React + Webpack 5](react-webpack.md)
- [Native HTML and classic SVG sprites](legacy.md)
## Requirements
@@ -25,10 +24,10 @@ npm install --save-dev @gromlab/svg-sprites
## CLI and generation modes
The CLI accepts one mode and a path to the configuration directory:
The CLI accepts exactly one path: an explicitly selected config file or a directory for config-less generation:
```text
svg-sprites --mode <mode> <path>
svg-sprites [options] <config-file-or-directory>
```
| Environment | Mode |
@@ -39,20 +38,24 @@ svg-sprites --mode <mode> <path>
| Next.js App Router + Webpack 5 | `next@app/webpack` |
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
| Classic `stack` and `symbol` sprites | `legacy` |
Modern React and Next.js modes use a local `svg-sprite.config.ts`. Legacy mode uses a separate `svg-sprites.config.ts` and is covered in [its own guide](legacy.md).
The config file may have any name and use the `.ts`, `.js`, or `.json` extension. The CLI does not discover it by convention: pass the file explicitly. The guides use `svg-sprite.config.ts` as the recommended name.
When a directory is passed, all settings come from CLI options. When a config file is passed, CLI options override the file. The full order is `defaults → config → CLI`.
Available options are `--mode`, `--name`, `--description`, `--input-folder`, repeatable `--input-file`, plus the `--remove-size`/`--no-remove-size`, `--replace-colors`/`--no-replace-colors`, `--add-transition`/`--no-add-transition`, and `--generated-notice`/`--no-generated-notice` pairs. Transform flags override individual fields, while supplying at least one `--input-file` replaces the complete config `inputFiles` array.
The mode must match the application's bundler. The generator creates different SVG asset integration code for Vite and for bundlers compatible with Webpack Asset Modules.
## React and Next.js configuration
## Unified configuration
Each directory containing `svg-sprite.config.ts` defines one independent sprite.
Each config file defines one independent sprite.
```ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@app/turbopack',
name: 'app',
description: 'Shared application icons',
inputFolder: './local-icons',
@@ -69,18 +72,13 @@ export default defineNextSpriteConfig({
})
```
For React, use `defineReactSpriteConfig`. The configuration contract is the same:
```ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
```
| Option | Type | Default | Purpose |
|---|---|---|---|
| `mode` | `SpriteMode` | None | Generation mode; may be supplied by CLI/API |
| `name` | `string` | Derived from the directory | Name of the sprite, component, and public types |
| `description` | `string` | None | Description for types and the debug manifest |
| `inputFolder` | `string` | `./icons` | SVG directory relative to the configuration file |
| `inputFiles` | `string[]` | `[]` | Paths to individual SVG files relative to the configuration file |
| `inputFolder` | `string` | `./icons` | SVG directory relative to the module root |
| `inputFiles` | `string[]` | `[]` | Paths to individual SVG files relative to the module root |
| `transform` | `TransformOptions` | All enabled | SVG preparation settings |
| `generatedNotice` | `boolean` | `true` | Full or abbreviated warning in generated files |
@@ -112,28 +110,41 @@ After generation, the sprite directory looks like this:
```text
app-icons/
├── .gitignore
├── index.ts
├── manifest.ts
├── svg-sprite.config.ts
── generated/
── .svg-sprites.manifest.json
├── react-component.tsx
── index.ts # optional user-owned barrel
── .svg-sprite/
├── state.json
├── index.js
├── index.d.ts
├── icon-data.js
├── icon-data.d.ts
├── sprite.svg
├── styles.module.css
── types.ts
├── svg-sprite.manifest.js
── svg-sprite.manifest.d.ts
└── react/
├── react-component.js
├── react-component.d.ts
└── react-component.module.css
```
| File | Purpose |
|---|---|
| `index.ts` | Production exports for the component, props, styles, and icon names |
| `manifest.ts` | Debug metadata and the asset URL for `SpriteViewer` |
| `generated/sprite.svg` | Compiled SVG sprite |
| `generated/react-component.tsx` | Typed React component |
| `generated/styles.module.css` | Base styles and transitions |
| `generated/types.ts` | Runtime list and union type of icon names |
| `generated/.svg-sprites.manifest.json` | List of files managed by the generator |
| `.svg-sprite/index.js` | Production exports for the component and runtime icon-name list |
| `.svg-sprite/index.d.ts` | Public declarations for the component, props, styles, and icon-name union |
| `.svg-sprite/svg-sprite.manifest.js` | Debug metadata and the asset URL for `SpriteViewer` |
| `.svg-sprite/sprite.svg` | Compiled SVG sprite |
| `.svg-sprite/react/react-component.js` | React component runtime without TypeScript or JSX |
| `.svg-sprite/react/react-component.d.ts` | React component props, style, and declaration |
| `.svg-sprite/react/react-component.module.css` | Styles for the React implementation |
| `.svg-sprite/icon-data.js` | Runtime icon-name list and internal IDs |
| `.svg-sprite/*.d.ts` | TypeScript declarations for the corresponding JavaScript modules |
| `.svg-sprite/state.json` | Mode, contract version, and managed file list |
The generator overwrites and deletes only files that contain its marker. If a user file occupies a managed path, generation fails.
The generator overwrites and deletes only files that contain its marker. If a user file occupies a managed path, generation fails. The root `index.ts` is user-owned; create a barrel when needed:
```ts
export * from './.svg-sprite'
```
## React component and TypeScript
@@ -224,12 +235,11 @@ For multiple sprites, add a separate CLI command for each directory or combine t
## Formats and rendering methods
Modern React and Next.js modes generate the `stack` format. Legacy mode supports both `stack` and `symbol`.
React and Next.js modes generate the `stack` format.
| Format | `<svg><use>` | `<img>` | CSS background |
|---|---:|---:|---:|
| `stack` | Yes | Yes | Yes |
| `symbol` | Yes | No | No |
### Generated component
@@ -246,13 +256,13 @@ How you obtain `spriteUrl` depends on the bundler.
Vite:
```ts
import spriteUrl from './generated/sprite.svg?no-inline'
import spriteUrl from './.svg-sprite/sprite.svg?no-inline'
```
Webpack 5, Turbopack, and Next.js:
```ts
const spriteUrl = new URL('./generated/sprite.svg', import.meta.url).href
const spriteUrl = new URL('./.svg-sprite/sprite.svg', import.meta.url).href
```
After obtaining the URL, use it in JSX:
@@ -277,7 +287,7 @@ An SVG inside `<img>` is isolated from the page's CSS. Setting `color` or `--ico
```css
.icon {
background: url('./generated/sprite.svg#search') center / contain no-repeat;
background: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
}
```
@@ -286,7 +296,7 @@ For a single-color silhouette, you can use a mask:
```css
.icon {
background-color: currentColor;
mask: url('./generated/sprite.svg#search') center / contain no-repeat;
mask: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
}
```
@@ -300,7 +310,7 @@ The generated component passes the SVG to the bundler as a separate asset:
- Vite uses a static import with `?no-inline`;
- Webpack 5, Turbopack, and Next.js use `new URL(..., import.meta.url)`;
- SVG path data is not serialized into the generated TSX.
- SVG path data is not serialized into generated JavaScript.
With standard asset naming, the bundler adds a content hash:
@@ -325,7 +335,8 @@ All transformations are enabled by default and can be configured independently:
To disable an individual operation:
```ts
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@app/turbopack',
transform: {
removeSize: false,
replaceColors: false,
@@ -399,7 +410,7 @@ import { SpriteViewer } from '@gromlab/svg-sprites/react'
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
const sources = import.meta.glob<SpriteManifestModule>(
'/src/**/svg-sprite/manifest.ts',
'/src/**/svg-sprite/.svg-sprite/svg-sprite.manifest.js',
)
export const IconsDebugPage = () => (
@@ -411,8 +422,8 @@ Webpack and Next.js:
```tsx
const sources = [
() => import('@/ui/app-icons/manifest'),
() => import('@/features/analytics/icons/manifest'),
() => import('@/ui/app-icons/.svg-sprite/svg-sprite.manifest.js'),
() => import('@/features/analytics/icons/.svg-sprite/svg-sprite.manifest.js'),
]
export const IconsDebugPage = () => (
@@ -447,9 +458,7 @@ To synchronize it with the application theme:
A modern sprite module creates a local `.gitignore` for:
```text
/generated/
/index.ts
/manifest.ts
/.svg-sprite/
```
Commit the local `.gitignore` to the repository once. It excludes the other generated files, so generation must run before commands that import the sprite module:
@@ -457,7 +466,7 @@ Commit the local `.gitignore` to the repository once. It excludes the other gene
```json
{
"scripts": {
"sprites": "svg-sprites --mode next@app/turbopack src/ui/app-icons",
"sprites": "svg-sprites src/ui/app-icons/svg-sprite.config.ts",
"predev": "npm run sprites",
"prebuild": "npm run sprites",
"pretypecheck": "npm run sprites"
@@ -467,18 +476,19 @@ Commit the local `.gitignore` to the repository once. It excludes the other gene
CI must install development dependencies and run the generation script before building or type-checking.
If the sprite directory already contains a user-created `.gitignore`, `index.ts`, or `manifest.ts`, the generator will not overwrite it. Move the user file or choose a separate sprite directory.
If the sprite directory already contains a user-created `.gitignore` or a user-owned file inside `.svg-sprite`, the generator will not overwrite it. The root `index.ts` remains user-owned and may re-export the generated API.
## Troubleshooting
- Missing `index.ts`: run the generation script before importing the module.
- Configuration not found: check the CLI path and the `svg-sprite.config.ts` file name.
- Missing `.svg-sprite/index.js`: run the generation script before importing the generated module.
- Source not found: pass an existing config file or sprite module directory.
- Mode missing: add `mode` to the config or pass `--mode`.
- Icon missing from the type: check `inputFiles`, the `.svg` extension, and the nesting level under `inputFolder`.
- Name conflict: two different SVG files have the same basename; rename one of them.
- `Refusing to overwrite a user file`: a file without the generated marker occupies a managed path.
- The icon does not change color: use `<svg><use>` or the generated component and check `replaceColors`.
- Webpack emits an incorrect URL: check Asset Modules, `output.publicPath`, and SVG loaders.
- The Viewer cannot find the sprite: check the path to `manifest.ts` and run generation before starting the application.
- The Viewer cannot find the sprite: check the path to `.svg-sprite/svg-sprite.manifest.js` and run generation before starting the application.
- Build and mode do not match: use the target that corresponds to the actual bundler.
For custom orchestration and low-level compilation, see the [Programmatic API](programmatic-api.md).