How to Add New SVG Assets for Avatar Components in Vue Color Avatar
To add new SVG assets for avatar components in vue-color-avatar, place the SVG file in the appropriate widgets directory, extend the corresponding shape enum in src/enums/index.ts, and register the lazy import function in src/utils/dynamic-data.ts.
The codennnn/vue-color-avatar library renders avatars by dynamically loading SVG assets at runtime. This architecture allows you to extend the avatar library with custom graphics without modifying the core rendering logic. Understanding how to add new SVG assets for avatar components ensures you can seamlessly integrate custom widgets while maintaining the existing dynamic loading mechanism.
Understanding the SVG Asset Pipeline
The avatar rendering pipeline relies on three interconnected systems to load and display SVG assets dynamically.
Enum Definitions in src/enums/index.ts
Each widget category (e.g., Tops, Mouth, Eyes) has a corresponding shape enum that defines valid options. The enum values must match the SVG file names exactly.
// src/enums/index.ts
export enum TopsShape {
// ... existing members ...
Crown = 'crown',
}
Dynamic Import Mapping in src/utils/dynamic-data.ts
The widgetData object maps each widget type and shape to a lazy import function. The VueColorAvatar.vue component calls these functions at runtime to fetch the raw SVG strings.
// src/utils/dynamic-data.ts
[WidgetType.Tops]: {
// ... existing shapes ...
[TopsShape.Crown]: () => import(`../assets/widgets/tops/crown.svg?raw`),
},
Runtime Rendering in VueColorAvatar.vue
The core component iterates over the selected widgets, resolves the async imports, substitutes $fillColor variables with the chosen colors, and injects the final SVG markup via v-html.
Step-by-Step Guide to Adding New SVG Assets
Follow these steps to integrate custom SVG graphics into the avatar system.
Step 1: Create the SVG File
Place your SVG file in src/assets/widgets/<widget-type>/<shape>.svg. The file name must exactly match the enum value you will define (case-sensitive).
src/assets/widgets/tops/crown.svg
Step 2: Extend the Shape Enum
Add a new member to the appropriate enum in src/enums/index.ts. Use PascalCase for the member name and ensure the value matches the SVG file name.
// src/enums/index.ts
export enum TopsShape {
Beanie = 'beanie',
Crown = 'crown', // New entry
// ... other shapes
}
Step 3: Register the Dynamic Import
In src/utils/dynamic-data.ts, add a lazy import entry to the widgetData map for your widget type.
// src/utils/dynamic-data.ts
[WidgetType.Tops]: {
[TopsShape.Beanie]: () => import('../assets/widgets/tops/beanie.svg?raw'),
[TopsShape.Crown]: () => import('../assets/widgets/tops/crown.svg?raw'), // New entry
},
Step 4: (Optional) Add Preview Thumbnails
If your UI displays preview thumbnails, add a simplified SVG to src/assets/preview/<widget-type>/<shape>.svg and register it in the previewData object in src/utils/dynamic-data.ts.
Working Example: Adding a Crown Top
Here is the complete implementation for adding a new "crown" top to the avatar system.
First, create the SVG asset:
# File location
src/assets/widgets/tops/crown.svg
Extend the enum definition:
// src/enums/index.ts
export enum TopsShape {
// existing members...
Crown = 'crown',
}
Register the dynamic import:
// src/utils/dynamic-data.ts
[WidgetType.Tops]: {
// existing shapes...
[TopsShape.Crown]: () => import(`../assets/widgets/tops/crown.svg?raw`),
},
Use the new asset in your application:
import { AvatarOption, TopsShape } from '@/types';
const myAvatar: AvatarOption = {
background: { color: '#fff', borderColor: '#000' },
widgets: {
tops: { shape: TopsShape.Crown, fillColor: '#FFD700' },
// other widgets...
},
};
The VueColorAvatar component will automatically resolve the lazy import, substitute the fill color, and render the crown SVG.
Key Files and Their Roles
| File | Purpose |
|---|---|
[src/enums/index.ts](https://github.com/codennnn/vue-color-avatar/blob/main/src/enums/index.ts) |
Defines widget‑type enums; each shape value must match an SVG filename. |
[src/utils/dynamic-data.ts](https://github.com/codennnn/vue-color-avatar/blob/main/src/utils/dynamic-data.ts) |
Holds the lazy‑import maps (widgetData & previewData) that the avatar component uses to fetch SVGs. |
[src/components/VueColorAvatar.vue](https://github.com/codennnn/vue-color-avatar/blob/main/src/components/VueColorAvatar.vue) |
Core avatar renderer; pulls SVG strings from widgetData, substitutes colors, and builds the final SVG markup. |
[src/types/index.ts](https://github.com/codennnn/vue-color-avatar/blob/main/src/types/index.ts) |
Type definitions for AvatarOption and widget shapes; ensures compile‑time safety when selecting new assets. |
src/assets/widgets/<type>/<shape>.svg |
Location for the raw SVG files that get imported at runtime. |
src/assets/preview/<type>/<shape>.svg (optional) |
Thumbnail preview assets used by the configurator UI. |
Summary
- Place SVG files in
src/assets/widgets/<widget-type>/<shape>.svgusing filenames that match your enum values exactly. - Extend the appropriate enum in
src/enums/index.tsto register the new shape option. - Register the lazy import in
src/utils/dynamic-data.tsusing the?rawquery parameter to load the SVG as a string. - Optionally add preview thumbnails in
src/assets/preview/for UI selectors. - The
VueColorAvatar.vuecomponent automatically handles runtime loading, color substitution, and rendering once the asset is registered.
Frequently Asked Questions
What is the purpose of the ?raw suffix in the import statement?
The ?raw query parameter instructs Vite to import the SVG file as a plain text string rather than as a processed component or URL. The avatar component concatenates these raw SVG strings, substitutes $fillColor variables with user-selected colors, and injects the final markup via v-html. This approach keeps the SVG assets lightweight and enables dynamic color replacement without complex component hierarchies.
Do I need to modify the VueColorAvatar.vue component to add new assets?
No, you do not need to modify VueColorAvatar.vue. The component is designed to dynamically load assets based on the widgetData map in src/utils/dynamic-data.ts. As long as you register your new SVG in the dynamic-data file and extend the corresponding enum, the component will automatically resolve and render the new asset at runtime.
Can I use different file names than the enum values?
No, the file names must match the enum values exactly (case-sensitive). The dynamic import path in src/utils/dynamic-data.ts uses the enum value to construct the file path: import(\../assets/widgets/tops/${shape}.svg?raw`). If the enum value is Crown = 'crown', the file must be named crown.svg` (lowercase) to match the string value.
Where should I place preview images for the UI configurator?
Place preview thumbnail SVGs in src/assets/preview/<widget-type>/<shape>.svg, using the same naming convention as the main assets. Then register the import in the previewData object within src/utils/dynamic-data.ts using the same lazy import pattern (?raw). The configurator UI uses these preview assets to display selectable options to users before they apply them to the main avatar.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →