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

- обновлены русская и английская версии README
- добавлены технические справочники на двух языках
- актуализированы ссылки и инструкции для React-сборок
This commit is contained in:
2026-07-11 23:20:39 +03:00
parent c7e6a27236
commit 3f6b186a5b
8 changed files with 1366 additions and 672 deletions

525
README.md
View File

@@ -4,400 +4,261 @@
![npm](https://img.shields.io/npm/v/@gromlab/svg-sprites) ![license](https://img.shields.io/npm/l/@gromlab/svg-sprites)
A CLI for generating SVG sprites and typed icon components for React and Next.js.
`@gromlab/svg-sprites` is an SVG sprite generator for modern web applications. It combines selected SVG icons into one or more external, cacheable sprites and prepares them for use in the UI.
![Preview](https://raw.githubusercontent.com/gromov-sergei/svg-sprites/master/preview-image.png)
For React and Next.js, the package generates typed components and supports Vite, Webpack 5, and Turbopack. At its core is a standard SVG sprite that can be used without a framework, including in native HTML.
## AI Skills
## An SVG sprite as simple as a regular SVG icon
- [🇬🇧 Download the English skill (latest)](https://github.com/gromov-sergei/svg-sprites/releases/latest/download/svg-sprites.zip)
- [🇷🇺 Download the Russian skill (latest)](https://github.com/gromov-sergei/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
One typed React component is generated for the entire sprite. Choose an icon with the `icon` prop, and your editor will autocomplete every available name.
## Navigation
- [AI Skills](#ai-skills)
- [Features](#features)
- [Support matrix](#support-matrix)
- [Requirements](#requirements)
- [Quick start](#quick-start)
- [React + Vite](docs/en/react-vite.md)
- [React + Webpack 5](docs/en/react-webpack.md)
- [Next.js App Router](docs/en/next-app.md)
- [Next.js Pages Router](docs/en/next-pages.md)
- [Configuration](#configuration)
- [React](#react)
- [Next.js](#nextjs)
- [Multiple sprites](#multiple-sprites)
- [TypeScript](#typescript)
- [Sprite formats](#sprite-formats)
- [Rendering methods](#rendering-methods)
- [Transformations](#transformations)
- [Icon color management](#icon-color-management)
- [Caching](#caching)
- [SpriteViewer](#spriteviewer)
- [Migrating from 0.1.x](docs/en/migration-1.md)
- [Documentation](#documentation)
## Features
- **AI-agent friendly** - the repository includes a ready-to-use skill with up-to-date documentation for configuring, migrating, and troubleshooting `@gromlab/svg-sprites`.
- **TypeScript-friendly** - typed React components, union types, and runtime lists of available icons.
- **Clean generation** - generated files are automatically excluded from Git, the sprite does not need to be placed in `public` manually, and the generator updates only files it owns.
- **Shared icons without copying** - SVGs from the local folder and `inputFiles` are merged into a single sprite; one file can be used in multiple sprites.
- **Built-in interactive preview** - `<SpriteViewer>` is integrated as an application page and displays the provided React and Next.js sprites with search, color controls, and usage examples.
- **Configurable SVG transformations** - remove `width` and `height` while preserving `viewBox`, replace source colors with CSS variables, and add transitions for `fill` and `stroke`.
- **Separate cacheable SVG asset** - SVG path data does not end up in JavaScript chunks, and the bundler emits a file with a content hash.
- **Multiple sprites** - independent React and Next.js modules with their own components, types, and SVG assets.
- **Server-first Next.js** - generated components work in Server Components, SSR, and SSG without the `'use client'` directive.
- **Formats for different use cases** - React and Next.js use `stack`; legacy mode also supports `symbol` for existing integrations.
## Support matrix
| Environment | API mode key | Status |
|---|---|---|
| React + Vite | `react@vite` | Ready |
| React + Webpack 5 | `react@webpack` | Ready |
| Next.js + App Router + Turbopack | `next@app/turbopack` | Ready |
| Next.js + App Router + Webpack 5 | `next@app/webpack` | Ready |
| Next.js + Pages Router + Turbopack | `next@pages/turbopack` | Ready |
| Next.js + Pages Router + Webpack 5 | `next@pages/webpack` | Ready |
| Vue | - | Coming soon |
| Standalone | - | Coming soon |
## Requirements
- Node.js 18 or newer;
- the package is distributed as ESM only and is loaded via `import`;
- React 18 or 19 is required only for generated components and the `@gromlab/svg-sprites/react` entry point;
- for subpath export typings, use TypeScript 5+ with `moduleResolution: "bundler"`, `"node16"`, or `"nodenext"`.
## Quick start
For a quick start, follow the guide for your stack:
- [React + Vite](docs/en/react-vite.md)
- [React + Webpack 5](docs/en/react-webpack.md)
- [Next.js App Router](docs/en/next-app.md)
- [Next.js Pages Router](docs/en/next-pages.md)
## Configuration
### React
```ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
export default defineReactSpriteConfig({
name: 'file-manager',
description: 'File manager icons',
inputFolder: './icons',
inputFiles: [
'../../shared/icons/check.svg',
],
transform: {
removeSize: true,
replaceColors: true,
addTransition: true,
},
generatedNotice: true,
})
```tsx
<AppIcon icon="search" width={24} height={24} />
```
| Option | Type | Default | Purpose |
|---|---|---|---|
| `name` | `string` | Folder name | Name of the sprite, component, and public types |
| `description` | `string` | None | Description for types and the debug manifest |
| `inputFolder` | `string` | `./icons` | Folder containing source SVGs, relative to the config |
| `inputFiles` | `string[]` | `[]` | Additional SVG files, relative to the config |
| `transform` | `TransformOptions` | All enabled | [Transformation settings](#transformations) for source SVGs |
| `generatedNotice` | `boolean` | `true` | Full or short warning in generated files |
The component accepts familiar SVG attributes: dimensions, `color`, `className`, `style`, `aria-*`, and event handlers. If you need an outer container, add `wrapped`.
`inputFolder` and `inputFiles` are merged into a single sprite, so one SVG file can be used in multiple sprites without copying. If the implicit `./icons` folder does not exist but `inputFiles` is populated, generation continues using only the list. An explicitly specified missing folder is an error. Duplicate paths are deduplicated, while different files with the same icon name are treated as an error.
```tsx
<AppIcon icon="search" wrapped className="iconWrapper" />
```
`name` is stored in kebab-case and must start with a Latin letter. The React and Next.js presets produce the `stack` format.
You do not have to work with the sprite directly in your application. Use it like a regular SVG icon while benefiting from a single component, autocomplete, and TypeScript validation for every name.
### Next.js
## AI-friendly out of the box
Next.js uses the same `svg-sprite.config.ts` and set of options. For type checking, you can use a dedicated helper:
`@gromlab/svg-sprites` is designed to work with AI agents from the start. Add the ready-made skill and ask an agent to configure, migrate, or troubleshoot the package without lengthy instructions or manual documentation research.
[🇬🇧 Download AI skill (English)](https://github.com/gromov-sergei/svg-sprites/releases/latest/download/svg-sprites.zip)
[🇷🇺 Download AI skill (Russian)](https://github.com/gromov-sergei/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
## From SVG to component in four steps
The main example uses the Next.js App Router and Turbopack.
### 1. Install the package
```bash
npm install --save-dev @gromlab/svg-sprites
```
### 2. Specify the icons you need
SVG files can remain in your project's existing structure:
```text
src/
├── assets/icons/
│ ├── search.svg
│ └── settings.svg
├── features/profile/
│ └── user.svg
└── ui/app-icons/
└── svg-sprite.config.ts
```
Create the sprite configuration:
```ts
// src/ui/app-icons/svg-sprite.config.ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
name: 'file-manager',
description: 'File manager icons',
inputFolder: './icons',
name: 'app',
inputFiles: [
'../../assets/icons/search.svg',
'../../assets/icons/settings.svg',
'../../features/profile/user.svg',
],
})
```
The router and bundler are selected through the mode key, so switching between Turbopack and Webpack is always explicitly reflected in the generation command.
### 3. Add generation
## Multiple sprites
An application can contain several independent sprites for different scopes:
**Problem:** one global sprite loads icons that the current screen does not need.
**Solution:** keep shared icons globally, and place icon sets for pages and large components in separate sprites that load alongside them.
```text
global -> GlobalIcon -> shared application icons
analytics-page -> AnalyticsPageIcon -> icons for a specific page
file-manager -> FileManagerIcon -> icons for a large component
```
- **Global sprite** contains a small set of shared icons used in different parts of the application: navigation, states, and basic actions.
- **Page sprite** loads with a specific section and does not increase the shared sprite with icons that are not needed anywhere else.
- **Large component sprite** encapsulates the icon set of a complex UI module, such as a file manager or editor.
Each group gets:
- its own SVG asset;
- its own typed component;
- a separate list of icon names;
- a separate debug manifest;
- an independent cache lifecycle.
## TypeScript
The main feature of the TypeScript API is icon name autocomplete directly in the `icon` prop:
```tsx
<FileManagerIcon icon="folder" />
// ^ the editor suggests every icon in the sprite
```
SVG file names become valid `icon` values. A typo or unknown name immediately becomes a TypeScript error:
```tsx
<FileManagerIcon icon="unknown" /> // TypeScript error
```
For programmatic access, the generated module exports a readonly array of all icons available in a specific sprite:
```ts
import { fileManagerIconNames } from './svg-sprite'
// readonly ['check', 'folder', ...]
```
You can use this list in custom catalogs, select components, tests, and other runtime scenarios. The `FileManagerIconName` union type is also derived from it.
File names containing spaces and other characters unsafe for SVG IDs remain part of the public TypeScript API. For the internal `<symbol id>`, the generator creates a stable hash ID.
```text
folder open.svg -> icon="folder open" -> id="icon-<stable-hash>"
```
For such names, use the generated component or the `id` from the debug manifest. The manual examples below using `#<name>` are suitable only for names that are already safe SVG IDs.
## Sprite formats
`stack` is the more modern format, so it is used by default. Icons can be rendered through `<svg><use>`, `<img>`, and CSS `background-image`.
`symbol` is retained for compatibility with existing integrations and supports rendering only through `<svg><use>`.
## Rendering methods
### React component - recommended
The generated component provides type safety and icon name autocomplete, and constructs the SVG asset URL itself.
```tsx
<FileManagerIcon icon="check" width={24} height={24} />
```
Monochrome and multicolor icons are supported through `color` and `--icon-color-N`.
### Manually with `<svg><use>`
A good low-level method that provides full control over dimensions and colors. This is exactly what the React component uses under the hood.
How you obtain `spriteUrl` depends on the bundler.
**Vite:**
```tsx
import spriteUrl from './svg-sprite/generated/sprite.svg?no-inline'
```
**Webpack 5:**
```tsx
const spriteUrl = new URL(
'./svg-sprite/generated/sprite.svg',
import.meta.url,
).href
```
**Next.js with Webpack 5 or Turbopack:**
```tsx
const spriteUrl = new URL(
'./svg-sprite/generated/sprite.svg',
import.meta.url,
).href
```
After obtaining the URL, the icon is rendered the same way:
```tsx
<svg width={24} height={24}>
<use href={`${spriteUrl}#check`} />
</svg>
```
Vite, Webpack 5, and Next.js replace the source path with the final hashed asset URL automatically.
### With `<img>` - less efficient
```tsx
<img src={`${spriteUrl}#check`} width={24} height={24} alt="Done" />
```
The SVG loads as an isolated image: its colors cannot be changed through `color` or `--icon-color-N`.
### With CSS `background-image` - less efficient
```css
.icon {
background: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat;
```json
{
"scripts": {
"sprites": "svg-sprites --mode next@app/turbopack src/ui/app-icons",
"predev": "npm run sprites",
"prebuild": "npm run sprites"
}
}
```
Like `<img>`, this method does not allow you to control internal SVG colors. The path is specified relative to the CSS file, and Vite/Webpack replaces it with the final hashed URL during the build.
Run it for the first time:
### With CSS mask - less efficient
```bash
npm run sprites
```
```css
.icon {
background-color: currentColor;
mask: url('./svg-sprite/generated/sprite.svg#check') center / contain no-repeat;
The package will generate `AppIcon`, TypeScript types, and a separate SVG sprite.
### 4. Use it like a regular icon
```tsx
import { AppIcon } from '@/ui/app-icons'
export default function SearchButton() {
return (
<button type="button">
<AppIcon icon="search" width={20} height={20} />
Search
</button>
)
}
```
A mask retains only the silhouette and colors it with a single color. The original colors, gradients, and distinctions between `fill` and `stroke` are lost.
This is a Server Component. The icon does not require a provider, `'use client'`, or manual URL construction.
## Transformations
## Typed React component with autocomplete
All transformations are enabled by default and configured independently through `transform`.
Each sprite gets its own ready-to-use component. The `icon` prop is derived from the actual SVG names, so your editor shows the exact list of available icons and TypeScript catches typos immediately.
| Option | Default | What it does |
|---|---|---|
| `removeSize` | `true` | Removes `width` and `height` from the root `<svg>` while preserving the existing `viewBox`. The icon size is then set externally. |
| `replaceColors` | `true` | Replaces `fill` and `stroke` colors with `--icon-color-N`. For a monochrome icon, the fallback becomes `currentColor`; for a multicolor icon, the original colors are preserved. |
| `addTransition` | `true` | Adds `style="transition:fill 0.3s,stroke 0.3s;"` directly to colored SVG elements. An existing `transition` is not overwritten. |
To disable a transformation, pass `false` for the corresponding option. For more details about the result of `replaceColors`, see [Icon color management](#icon-color-management).
## Icon color management
When color replacement is enabled, the generator analyzes `fill` and `stroke` and converts them to CSS custom properties.
### Monochrome icons
If one color is found, the fallback is replaced with `currentColor`:
```svg
stroke="var(--icon-color-1, currentColor)"
```tsx
<AppIcon icon="search" /> // available icon
<AppIcon icon="serach" /> // TypeScript error
```
The color is controlled by the CSS `color` property of the outer `<svg>` or its parent.
After you add a new SVG icon and run generation again, its name automatically appears in the types and autocomplete. There is no need to maintain components, union types, or a name registry manually.
### Multicolor icons
## Next.js App Router and SSR out of the box
Each unique color gets a separate variable with the original fallback:
Generated components work in Server Components, SSR, and SSG without `'use client'`.
```svg
fill="var(--icon-color-1, #798198)"
fill="var(--icon-color-2, #ffffff)"
fill="var(--icon-color-3, #129d9d)"
Using an icon does not turn the page into a Client Component, require a provider, or create an additional hydration boundary.
The same component can be used in `page.tsx`, `layout.tsx`, and both server and client components.
## Multiple sprites instead of one global sprite
Your project is not limited to a single icon set. Create independent sprites for shared elements, individual pages, and large UI modules.
```tsx
<AppIcon icon="search" />
<AnalyticsIcon icon="chart" />
<EditorIcon icon="bold" />
```
The page can override only the required colors:
Each set gets its own typed component and SVG asset, so application sections do not load icons they do not need.
```css
.icon {
--icon-color-1: #4b5563;
--icon-color-3: #14b8a6;
}
```
## Store each icon only once
### Color limitations
- `none`, `transparent`, `inherit`, `unset`, and `initial` are not replaced;
- colors in `fill`, `stroke`, and inline `style` attributes are handled most reliably;
- CSS classes and external stylesheets inside the source SVG are not the primary transformation use case;
- gradients, patterns, filters, and `url(#...)` values require separate verification and may be incompatible with automatic color replacement;
- page CSS variables are available with `<svg><use>`, but are not available inside `<img>` and `background-image`.
## Caching
The Vite, Webpack, and Next.js targets emit the sprite as a separate asset with a content hash:
Each SVG icon is stored once in the source library and can be included in any number of sprites. Shared icons do not need to be copied between pages and modules: a single source updates every set.
```text
/assets/sprite-<hash>.svg
search.svg ─┬─→ AppIcon
├─→ AnalyticsIcon
└─→ EditorIcon
```
This provides the following properties:
Sprites are split for performance, while the source icon library remains unified.
- the SVG is cached independently of JavaScript;
- changes to React code do not alter the sprite contents;
- icon changes produce a new hashed asset;
- one file is used by every instance of the generated component;
- SVG path data is absent from JavaScript chunks.
## Browser caching
The Vite target prevents inlining through `?no-inline`. The Webpack 5 target uses Asset Modules through `new URL(..., import.meta.url)`.
With a standard Vite, Webpack, or Next.js configuration, each sprite is emitted as a separate versioned SVG file.
## SpriteViewer
As long as the icon set does not change, the browser can reuse its cached copy independently of JavaScript application updates.
`SpriteViewer` is a React component for viewing generated sprites inside an application's debug route.
Changes to React components do not require downloading the geometry of every icon again.
It uses separate manifests and displays:
## JavaScript without SVG bloat
- sprite groups;
- the icon list and count;
- search and the system light/dark theme;
- a preview modal with the `viewBox` and color variable controls;
- React, SVG, IMG, and CSS examples with code copying.
Icon paths remain in external SVG assets and do not add to application chunks.
Production components do not import debug manifests. How you integrate the Viewer depends on the bundler:
- [React + Vite: automatic `import.meta.glob`](docs/en/react-vite.md#6-add-a-debug-page);
- [React + Webpack 5: static `import()`](docs/en/react-webpack.md#6-add-a-debug-page);
- [Next.js App Router](docs/en/next-app.md#5-add-spriteviewer);
- [Next.js Pages Router](docs/en/next-pages.md#5-add-spriteviewer).
The Viewer is imported from the separate `@gromlab/svg-sprites/react` client entry point and is not included in production icon components.
### Viewer theme
By default, `colorTheme="auto"`: the Viewer follows `prefers-color-scheme` and responds to system theme changes. The application theme can be passed explicitly:
```tsx
<SpriteViewer sources={sources} colorTheme="dark" />
```text
React code → JavaScript chunks
SVG icons → separate SVG assets
```
Valid `colorTheme` values are `auto`, `light`, and `dark`. When the theme is controlled externally, the built-in switch is hidden. To keep it and update the application theme through the Viewer, pass a callback:
JavaScript handles the interface and behavior, while graphics are loaded and cached separately.
## Built-in SVG transformations
During generation, the package automatically prepares source SVG files for use in the UI:
- removes fixed `width` and `height` attributes;
- preserves the existing `viewBox`;
- converts `fill` and `stroke` values to CSS variables;
- adds smooth transitions directly to colored icon elements.
Each transformation can be configured or disabled independently.
## Control every color with CSS
During generation, `fill` and `stroke` colors are automatically converted to `--icon-color-N` CSS variables.
A monochrome icon inherits `currentColor`:
```tsx
<SpriteViewer
sources={sources}
colorTheme={appTheme}
onColorThemeChange={setAppTheme}
<AppIcon icon="search" color="rebeccapurple" />
```
For a multicolor icon, each color can be changed independently:
```tsx
<AppIcon
icon="user"
style={{
'--icon-color-1': '#2563eb',
'--icon-color-2': '#dbeafe',
}}
/>
```
Create themes, states, and hover effects without editing the SVG or making additional copies of the icon.
## SpriteViewer: every sprite on one debug page
`SpriteViewer` renders all project sprites in one place and shows which icons are included in each set and how they look.
For each icon, you can see the generated CSS variables and their fallback colors. Change the values directly in the Viewer and see the result immediately.
It also provides ready-to-use integration examples for:
- React;
- `<svg><use>`;
- `<img>`;
- CSS.
![SpriteViewer](https://raw.githubusercontent.com/gromov-sergei/svg-sprites/master/preview-image.png)
The Viewer is added only to an internal debug page and does not become part of the generated icon components.
## From native HTML to Next.js
At its core is a standard SVG sprite that can be used even without a framework or bundler.
For React and Next.js, the package generates typed components and supports Vite, Webpack 5, and Turbopack. The list of ready-made integrations will expand to include new frameworks.
## Clean Git history
The generator creates a local `.gitignore` that excludes generated files and keeps them from cluttering project history, pull requests, and the codebase.
The repository contains the source SVG files, configuration, and `.gitignore` rule, while sprites, components, and types are regenerated locally and in CI through `prebuild`.
## Only icons in production
`@gromlab/svg-sprites` does its main work during generation and remains in `devDependencies`.
Production components use only local generated code, styles, and the external SVG file. The compiler and CLI are not bundled into the client application, while `SpriteViewer` is imported separately only where a debug page is needed.
## Documentation
- [React + Vite](docs/en/react-vite.md)
- [React + Webpack 5](docs/en/react-webpack.md)
This README introduces the project's capabilities and demonstrates the primary use case. For setup, choose the guide for your stack.
### Quick start
- [Next.js App Router](docs/en/next-app.md)
- [Next.js Pages Router](docs/en/next-pages.md)
- [Legacy mode](docs/en/legacy.md)
- [Migrating from 0.1.x](docs/en/migration-1.md)
- [React + Vite](docs/en/react-vite.md)
- [React + Webpack 5](docs/en/react-webpack.md)
- [Native HTML and classic SVG sprites](docs/en/legacy.md)
### Technical resources
- [Technical reference](docs/en/reference.md)
- [Programmatic API](docs/en/programmatic-api.md)
- [Migrating from 0.1.x](docs/en/migration-1.md)
## License