How to Add Custom SVG Icons to the AppBar Using icons.yaml in Astro Big Doc

Add a YAML entry to content/icons.yaml pointing to an SVG in src/assets, optionally set align: right, and the create-menu integration automatically merges it into the AppBar navigation.

The Astro Big Doc theme generates its top navigation bar (the AppBar) from a build-time menu JSON. By editing content/icons.yaml, you can inject custom SVG icons into this bar without touching core layout code. The create-menu integration (src/integrations/create_menu.js) reads this file and appends entries to the generated menu, while src/layout/AppBar.astro renders them via the Icon component.

Step 1 – Store Your SVG Files in the Assets Directory

Place your custom SVG files inside src/assets/. The theme's asset pipeline and the SvgIcons component (src/components/svgicons.astro) both reference this directory for static files.

For example, save your logo as:


src/assets/mylogo.svg

Step 2 – Configure Icons in content/icons.yaml

Create or edit content/icons.yaml and add a map entry for each icon you want to display. The icon field should match the filename (without extension) of the SVG stored in src/assets.

- icon: mylogo
  align: right
  link: https://example.com
  • icon: Required. The base name of the SVG file in src/assets.
  • align: Optional. Set to right to push the icon to the right side of the AppBar. Omit or set to left for left alignment.
  • link: Optional. The URL navigated to when the icon is clicked.

Step 3 – Understanding the Build Integration

The create-menu integration (src/integrations/create_menu.js) automatically merges icons.yaml into the site menu at build time. Lines 63-68 load the file and push its contents into the sorted_items array that becomes the AppBar menu:

const icons_file = join(content_path,"icons.yaml")
if (await exists(icons_file)) {
    const icons_list = await load_yaml_abs(icons_file)
    sorted_items.push(...icons_list)   // Icons become menu items
}

This happens during the astro:build:setup hook, ensuring your icons are present in the static JSON menu consumed by the layout components.

Step 4 – How the AppBar Renders Icons

The AppBar component (src/layout/AppBar.astro) receives the menu from layout_utils.js and filters items into left and right arrays based on the align property:

// From src/layout/layout_utils.js
let base_menu = get_base_menu()
const menu = get_active_appbar_menu(base_menu, Astro.url.pathname)
const left_side  = menu.filter(item => !item.align || item.align !== "right")
const right_side = menu.filter(item => item.align === "right")

When iterating over menu items, AppBar.astro checks for the icon field and renders the Icon component:

{item.icon && <Icon filename={item.icon} />}

Step 5 – Extending the Icon Component for Custom SVGs

By default, src/components/icon.astro hard-codes support for specific PNG icons (github and search). To render arbitrary SVGs from src/assets, modify icon.astro to dynamically load SVG files using the same pattern as svgicons.astro:

---
import { readFile } from 'fs/promises';
import { exists } from '@/libs/assets';
import { config } from '@/config';
import { join } from 'node:path';

export interface Props {
  filename: string;
}
const { filename } = Astro.props as Props;
const filepath = join(config.rootdir, `src/assets/${filename}.svg`);
const innerHTML = await exists(filepath) ? await readFile(filepath) : "<svg/>";
---
<Fragment set:html={innerHTML} />

After this modification, the Icon component will render any SVG placed in src/assets whose name matches the icon field in icons.yaml.

Complete Working Example

  1. Save your SVG:

    # src/assets/company-logo.svg
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
      <path d="M12 2L2 22h20L12 2z"/>
    </svg>
  2. Configure icons.yaml:

    - icon: company-logo
      align: right
      link: https://my-company.com
  3. Update icon.astro (if not already generic) with the dynamic SVG loader code shown in Step 5.

  4. Run the dev server:

    pnpm run dev

The company logo now appears on the right side of the AppBar and links to the specified URL.

Summary

  • Place SVG files in src/assets/ to make them available to the theme.
  • Define icons in content/icons.yaml using the icon, align, and link fields.
  • The create_menu.js integration automatically merges YAML entries into the AppBar menu at build time.
  • AppBar.astro filters items by alignment and renders them via the Icon component.
  • Extend src/components/icon.astro to support arbitrary SVGs beyond the default hard-coded icons.

Frequently Asked Questions

Can I add multiple custom icons to the AppBar?

Yes. content/icons.yaml accepts a list of entries. Each item with an icon field becomes a separate icon in the AppBar. You can mix left-aligned and right-aligned icons by setting or omitting the align: right property on each entry.

What happens if the SVG file is missing from src/assets?

If src/components/icon.astro is updated with the dynamic loader pattern shown in Step 5, the component renders an empty <svg/> element when the file is not found. This prevents build errors while allowing the menu structure to remain intact. Always verify that the icon value in icons.yaml matches the filename (without extension) in src/assets.

Do I need to restart the dev server after editing icons.yaml?

Yes. The create_menu.js integration runs during the Astro build process to generate the static menu JSON. While Astro's dev server handles many hot updates, changes to YAML data files consumed by integrations typically require a restart to regenerate the menu structure. Run pnpm run dev again to see new icons appear.

Can I use PNG or other image formats instead of SVG?

The default Icon component in src/components/icon.astro is designed for SVG files when using the dynamic loader pattern. If you need to support PNGs or other formats, you would need to modify the component to handle different file extensions or use an <img> tag instead of inline SVG. However, SVG is recommended for AppBar icons because it scales cleanly and supports currentColor for theme consistency.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →