How to Add New Beard or Facial Hair SVG Options to vue-color-avatar
To add a new beard option in vue-color-avatar, create the SVG asset files, extend the BeardShape enum in src/enums/index.ts, and register the dynamic imports in src/utils/dynamic-data.ts for both widget and preview data.
vue-color-avatar is a Vue.js avatar generator that constructs faces by stitching together SVG "widgets." Adding custom facial hair requires updating the type system, asset pipeline, and dynamic import mappings. This guide walks through the exact file paths and code changes needed based on the source code of codennnn/vue-color-avatar.
Where Beard Options Are Defined
The library uses a three-layer architecture to manage beard styles:
- Type Safety: The
BeardShapeenum insrc/enums/index.tsdefines all valid beard identifiers. - Configuration: The
SETTINGSconstant insrc/utils/constant.tsusesObject.values(BeardShape)to populate available options for the random generator. - Asset Mapping: The
widgetDataandpreviewDataobjects insrc/utils/dynamic-data.tsmap each enum value to its corresponding SVG file import.
To introduce a new style, you must update all three layers so TypeScript recognizes the type, the random selector can pick it, and the component can load the correct graphics.
Step-by-Step Implementation
1. Create the SVG Assets
Add two SVG files for your new beard style: one for the full-size avatar widget and one for the UI preview thumbnail.
Place the files in the following directories:
src/assets/widgets/beard/{name}.svg— The full-resolution graphic rendered on the avatar.src/assets/preview/beard/{name}.svg— The smaller icon shown in the selector panel.
Use lowercase filenames that match your intended enum key. For example, if adding a "goatee" style:
src/assets/widgets/beard/goatee.svg
src/assets/preview/beard/goatee.svg
2. Extend the BeardShape Enum
Open src/enums/index.ts and add your new beard identifier to the BeardShape enum. This ensures type safety throughout the application.
// src/enums/index.ts
export enum BeardShape {
Scruff = 'scruff',
None = 'none',
/** New beard style */
Goatee = 'goatee',
}
The SETTINGS.beardShape array in src/utils/constant.ts automatically includes new values because it is derived from Object.values(BeardShape). No manual update to the settings file is required.
3. Register Dynamic Imports
Update src/utils/dynamic-data.ts to map the new enum value to its SVG files using dynamic imports with the ?raw suffix. You must add entries to both the widgetData and previewData objects.
// src/utils/dynamic-data.ts
import { BeardShape, WidgetType } from '../enums'
const widgetData: Data = {
// ... other widgets
[WidgetType.Beard]: {
[BeardShape.Scruff]: () => import('../assets/widgets/beard/scruff.svg?raw'),
[BeardShape.Goatee]: () => import('../assets/widgets/beard/goatee.svg?raw'), // Added
},
}
const previewData: Data = {
// ... other previews
[WidgetType.Beard]: {
[BeardShape.Scruff]: () => import('../assets/preview/beard/scruff.svg?raw'),
[BeardShape.Goatee]: () => import('../assets/preview/beard/goatee.svg?raw'), // Added
},
}
The getRandomAvatarOption function pulls beard shapes from SETTINGS.beardShape, so your new option will immediately become available for random generation once the enum is updated.
Verifying Your New Beard Option
Run the development server to test the integration:
npm run dev
Verify the following behaviors:
- The random avatar generator occasionally selects the new beard style.
- The beard selector panel displays the new preview icon.
- Clicking the preview applies the correct SVG to the avatar canvas.
If the SVG does not render, verify that the import paths match the filenames exactly and that the SVG files contain valid markup.
Summary
- Add SVG files to
src/assets/widgets/beard/andsrc/assets/preview/beard/with matching lowercase names. - Extend
BeardShapeinsrc/enums/index.tsto declare the new type. - Update
dynamic-data.tsto map the enum value to?rawimports for both widget and preview data. - The random generator and UI selector automatically recognize new values because they iterate over the enum and data maps.
Frequently Asked Questions
What file naming convention should I use for beard SVGs?
Use lowercase names that exactly match the enum value. If you define Goatee = 'goatee' in the BeardShape enum, name the files goatee.svg. The dynamic import template literals in src/utils/dynamic-data.ts rely on this consistency to resolve paths correctly.
Why are there separate widget and preview SVG files?
Widget SVGs are full-resolution graphics positioned absolutely on the avatar canvas, while preview SVGs are optimized thumbnails displayed in the configuration panel. The widgetData map loads the former, and previewData loads the latter, ensuring fast UI rendering without loading unnecessary detail for the selector icons.
Do I need to modify the random avatar generator?
No. The getRandomAvatarOption function selects beard shapes from SETTINGS.beardShape, which is automatically populated via Object.values(BeardShape). Once you add the enum value and restart the dev server, the new style becomes part of the randomization pool immediately.
Where should I place the SVG files?
Place full-size beard graphics in src/assets/widgets/beard/ and their corresponding preview icons in src/assets/preview/beard/. Both directories follow the same flat structure, and the build system processes them as raw strings via the ?raw import suffix used in src/utils/dynamic-data.ts.
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 →