# How to Add New Beard or Facial Hair SVG Options to vue-color-avatar

> Easily add new beard SVG options to vue-color-avatar by creating SVG files, extending the BeardShape enum, and registering dynamic imports in data utils. Boost your avatar customization.

- Repository: [LeoKu/vue-color-avatar](https://github.com/codennnn/vue-color-avatar)
- Tags: how-to-guide
- Published: 2026-02-27

---

**To add a new beard option in vue-color-avatar, create the SVG asset files, extend the `BeardShape` enum in [`src/enums/index.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/src/enums/index.ts), and register the dynamic imports in [`src/utils/dynamic-data.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/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:

1. **Type Safety**: The `BeardShape` enum in [`src/enums/index.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/src/enums/index.ts) defines all valid beard identifiers.
2. **Configuration**: The `SETTINGS` constant in [`src/utils/constant.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/src/utils/constant.ts) uses `Object.values(BeardShape)` to populate available options for the random generator.
3. **Asset Mapping**: The `widgetData` and `previewData` objects in [`src/utils/dynamic-data.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/src/utils/dynamic-data.ts) map 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:

```text
src/assets/widgets/beard/goatee.svg
src/assets/preview/beard/goatee.svg

```

### 2. Extend the BeardShape Enum

Open [`src/enums/index.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/src/enums/index.ts) and add your new beard identifier to the `BeardShape` enum. This ensures type safety throughout the application.

```typescript
// 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`](https://github.com/codennnn/vue-color-avatar/blob/main/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`](https://github.com/codennnn/vue-color-avatar/blob/main/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.

```typescript
// 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:

```bash
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/` and `src/assets/preview/beard/` with matching lowercase names.
- **Extend `BeardShape`** in [`src/enums/index.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/src/enums/index.ts) to declare the new type.
- **Update [`dynamic-data.ts`](https://github.com/codennnn/vue-color-avatar/blob/main/dynamic-data.ts)** to map the enum value to `?raw` imports 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`](https://github.com/codennnn/vue-color-avatar/blob/main/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`](https://github.com/codennnn/vue-color-avatar/blob/main/src/utils/dynamic-data.ts).