# How to Add Interactive Links and Highlights to SVG Diagrams Using YAML Metadata Files in Astro-Big-Doc

> Add interactive links and highlights to SVG diagrams with Astro-Big-Doc and YAML. Transform static SVGs into dynamic visualizations easily without code edits.

- Repository: [Micro Web Stacks/astro-big-doc](https://github.com/microwebstacks/astro-big-doc)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Astro-Big-Doc automatically transforms static SVG diagrams into interactive visualizations by pairing them with YAML metadata files that define clickable links and hover highlights, requiring no code changes to the SVG itself.**

The `astro-big-doc` repository provides a built-in mechanism for enhancing SVG diagrams with interactivity through external metadata. By placing a YAML file alongside your SVG asset, you can define clickable regions and hover-triggered highlights without modifying the original vector graphic. This approach keeps content separate from presentation while delivering rich, interactive documentation experiences.

## How the YAML-to-SVG Pipeline Works

Astro-Big-Doc processes SVG interactivity through a five-stage pipeline that bridges server-side asset resolution with client-side DOM manipulation:

1. **Asset Resolution** – When an SVG is referenced in Markdown, the `MarkdownImage.astro` component invokes `getMetaData()` from [`src/libs/assets.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/libs/assets.js) (lines 184-198). This function constructs a parallel file path by replacing the `.svg` extension with `.yaml` and checks for existence using `exists()`.

2. **Metadata Injection** – The parsed YAML object is passed as the `meta` prop to the `Panzoom` component (`src/components/panzoom/panzoom.astro`, lines 13-36). The component serializes the metadata into a `data-meta` attribute on the container element using `JSON.stringify(meta)` (line 35).

3. **Client-Side Processing** – On page load, [`panzoom_common.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/panzoom_common.js) (lines 21-30) reads the `data-meta` attribute, parses the JSON, and conditionally invokes `svg_add_links()` and `svg_highlight()` from [`src/components/panzoom/lib_svg_utils.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/components/panzoom/lib_svg_utils.js) (lines 29-146).

4. **Link Insertion** – The `svg_add_links()` function (lines 30-55) traverses all `<text>` nodes in the SVG DOM, compares their `textContent` against the `label` fields in the metadata's `links` array, and wraps matches in SVG.js `linkTo` elements pointing to the specified URLs.

5. **Hover Highlights** – The `svg_highlight()` function (lines 57-96) attaches `mouseover` and `mouseout` event listeners to trigger labels. When activated, it recolors (`fill({color:'#292'})`) and bolds every SVG text node whose content matches entries in the corresponding `highlights` array.

## YAML Schema for SVG Interactivity

The metadata file uses a strict schema with two top-level arrays: `links` for clickable navigation and `highlights` for visual emphasis on hover.

### Links Configuration

The `links` array contains objects that map SVG text labels to URLs:

```yaml
links:
  - label: "Home"
    link: "/"                     # Absolute URL opens in new tab

  - label: "API Reference"
    link: "/api/docs"             # Relative URL navigates in-page

  - label: "GitHub Repository"
    link: "https://github.com/microwebstacks/astro-big-doc"

```

**Key constraints:**
- The `label` value must exactly match the text content of an SVG `<text>` node (case-sensitive)
- Absolute URLs (starting with `http` or `https`) automatically open in new tabs
- Relative URLs and anchors (`#section`) navigate within the current page context

### Highlights Configuration

The `highlights` array defines hover-triggered visual connections between diagram elements:

```yaml
highlights:
  - label: "Critical Path"
    highlights:
      - "Step 1"
      - "Step 3"
      - "Database"
  - label: "Optional Path"
    highlights:
      - "Step 2"
      - "Step 4"

```

**Behavior details:**
- When the user hovers over the SVG text matching `label`, all nodes listed in the nested `highlights` array receive a green fill (`#292`) and bold font weight
- Moving the mouse out restores the original styling
- Multiple highlight groups can reference the same target nodes

## Step-by-Step Implementation Guide

Follow these steps to add interactivity to any SVG diagram in your Astro-Big-Doc project:

1. **Prepare your assets**
   - Export your diagram as `diagram.svg` and place it in your content directory (e.g., `src/content/docs/architecture/`)

2. **Create the metadata file**
   - In the same directory, create [`diagram.yaml`](https://github.com/microwebstacks/astro-big-doc/blob/main/diagram.yaml) with your links and highlights configuration:
   
   ```yaml
   links:
     - label: "Frontend"
       link: "/frontend-guide"
     - label: "Backend"
       link: "https://api.example.com"
   
   highlights:
     - label: "Frontend"
       highlights:
         - "React Component"
         - "CSS Module"
   ```

3. **Reference in Markdown**
   - Use standard Markdown image syntax. The `MarkdownImage.astro` component (located at `src/components/markdown/image/MarkdownImage.astro`) automatically detects the companion YAML file:
   
   ```markdown
   ![Architecture Diagram](diagram.svg)
   ```

4. **Verify the build**
   - Run `pnpm run dev` and navigate to your page
   - Inspect the SVG container to confirm the `data-meta` attribute contains your YAML data
   - Test that clicking labeled elements navigates to the specified URLs
   - Hover over trigger labels to verify target nodes highlight in green

## Technical Deep Dive: Source Code Architecture

Understanding the underlying implementation helps troubleshoot edge cases and extend functionality.

### Asset Resolution Layer

The `getMetaData()` function in [`src/libs/assets.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/libs/assets.js) (lines 184-198) handles the filesystem lookup:

```javascript
// Simplified logic from src/libs/assets.js
export async function getMetaData(url, dirpath) {
  const basePath = resolvePath(url, dirpath);
  const yamlPath = basePath.replace(/\.[^/.]+$/, '.yaml');
  
  if (await exists(yamlPath)) {
    return await load_yaml_abs(yamlPath);
  }
  return null;
}

```

This convention-based approach means any asset type can potentially support metadata by following the `{filename}.{ext}` → `{filename}.yaml` pattern.

### Component Integration

The `Panzoom.astro` component (`src/components/panzoom/panzoom.astro`, lines 13-36) serves as the bridge between server-side data and client-side execution:

```astro
---
// Props interface includes meta object
const { src, alt, meta } = Astro.props;
---

<div class="panzoom-container" data-meta={JSON.stringify(meta)}>
  <object data={src} type="image/svg+xml" aria-label={alt}></object>
</div>

```

The `data-meta` attribute stores the serialized YAML content, making it accessible to the client-side JavaScript without requiring additional fetch requests.

### Client-Side Processing Engine

The [`panzoom_common.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/panzoom_common.js) file ([`src/components/panzoom/panzoom_common.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/components/panzoom/panzoom_common.js), lines 21-30) orchestrates the interactivity:

```javascript
// Executed after DOMContentLoaded
const containers = document.querySelectorAll('.panzoom-container');
containers.forEach(container => {
  const metaAttr = container.getAttribute('data-meta');
  if (metaAttr) {
    const meta = JSON.parse(metaAttr);
    if (meta.links) svg_add_links(svgElement, meta.links);
    if (meta.highlights) svg_highlight(svgElement, meta.highlights);
  }
});

```

This initialization pattern ensures that SVG manipulation only occurs after the `<object>` element has fully loaded the SVG document.

### SVG Manipulation Utilities

The [`lib_svg_utils.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/lib_svg_utils.js) file ([`src/components/panzoom/lib_svg_utils.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/components/panzoom/lib_svg_utils.js), lines 29-146) contains the core DOM manipulation logic using SVG.js:

**Link Creation (lines 30-55):**

```javascript
export function svg_add_links(svgElement, links) {
  const texts = svgElement.querySelectorAll('text');
  texts.forEach(textNode => {
    const content = textNode.textContent.trim();
    const match = links.find(l => l.label === content);
    if (match) {
      // SVG.js wrapper for link creation
      const svgText = SVG(textNode);
      svgText.linkTo(match.link);
    }
  });
}

```

**Highlight System (lines 57-96):**

```javascript
export function svg_highlight(svgElement, highlights) {
  highlights.forEach(entry => {
    const triggerNode = findTextNode(svgElement, entry.label);
    if (!triggerNode) return;
    
    triggerNode.addEventListener('mouseover', () => {
      entry.highlights.forEach(targetLabel => {
        const target = findTextNode(svgElement, targetLabel);
        if (target) {
          SVG(target).fill({ color: '#292' }).font({ weight: 'bold' });
        }
      });
    });
    
    triggerNode.addEventListener('mouseout', () => {
      // Reset logic omitted for brevity
    });
  });
}

```

## Code Examples

### Minimal Configuration with Links Only

Create [`network-diagram.yaml`](https://github.com/microwebstacks/astro-big-doc/blob/main/network-diagram.yaml) alongside your SVG:

```yaml
links:
  - label: "Load Balancer"
    link: "/infrastructure/load-balancer"
  - label: "Database Cluster"
    link: "https://db.internal.company.com"

```

### Configuration with Hover Highlights Only

Create [`workflow.yaml`](https://github.com/microwebstacks/astro-big-doc/blob/main/workflow.yaml):

```yaml
highlights:
  - label: "Initialization"
    highlights:
      - "Config Load"
      - "Cache Warmup"
  - label: "Processing"
    highlights:
      - "Worker Pool"
      - "Queue Manager"

```

### Complete Markdown Integration

File: [`src/content/docs/architecture.md`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/content/docs/architecture.md)

```markdown

# System Architecture

The following diagram illustrates component relationships. Hover over any service to see its dependencies, or click labels to navigate to detailed documentation.

![Architecture Overview](architecture.svg)

```

Required companion file: [`src/content/docs/architecture.yaml`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/content/docs/architecture.yaml)

```yaml
links:
  - label: "API Gateway"
    link: "/api/gateway"
  - label: "Auth Service"
    link: "https://auth.example.com"

highlights:
  - label: "API Gateway"
    highlights:
      - "Rate Limiter"
      - "Router"
  - label: "Auth Service"
    highlights:
      - "JWT Validator"
      - "User Store"

```

## Summary

- **Convention-based pairing**: Astro-Big-Doc automatically associates `diagram.svg` with [`diagram.yaml`](https://github.com/microwebstacks/astro-big-doc/blob/main/diagram.yaml) when placed in the same directory, triggered by the `getMetaData()` function in [`src/libs/assets.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/libs/assets.js).
- **Zero-code configuration**: The YAML schema supports two interaction modes—`links` for navigation and `highlights` for visual emphasis—without requiring modifications to the SVG source.
- **Client-side activation**: The [`panzoom_common.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/panzoom_common.js) bootstrapper reads JSON-encoded metadata from the `data-meta` attribute (injected by `Panzoom.astro`) and delegates DOM manipulation to `svg_add_links()` and `svg_highlight()` in [`lib_svg_utils.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/lib_svg_utils.js).
- **SVG.js integration**: Link creation uses the `linkTo()` API, while highlights manipulate fill colors (`#292`) and font weights through SVG.js wrappers for robust cross-browser SVG manipulation.

## Frequently Asked Questions

### What happens if the YAML file is missing or malformed?

If [`diagram.yaml`](https://github.com/microwebstacks/astro-big-doc/blob/main/diagram.yaml) is absent, `getMetaData()` in [`src/libs/assets.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/libs/assets.js) returns `null`, and the SVG renders as a static image without interactivity. If the YAML contains syntax errors, `load_yaml_abs()` will throw a parsing error during the build process, halting compilation until the file is fixed.

### Can I use this feature with SVGs embedded directly in Markdown rather than referenced as files?

No. The current implementation in `MarkdownImage.astro` specifically processes external file references to enable the filesystem-based metadata lookup. Inline SVGs in Markdown bypass the asset resolution pipeline and will not trigger the `getMetaData()` call or the subsequent `Panzoom` wrapping.

### How do I style the highlight colors or link appearances?

The highlight color is hardcoded to `#292` (green) in `svg_highlight()` within [`src/components/panzoom/lib_svg_utils.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/src/components/panzoom/lib_svg_utils.js) (line 78). To customize colors, modify the `fill({color:'#292'})` call or extend the YAML schema to accept a `color` property and update the utility function to read it. Link styling inherits from the SVG.js `linkTo()` implementation, which creates standard SVG `<a>` elements.

### Does this work with server-side rendering (SSR) or only static builds?

The feature works in both modes. During SSR or static generation, the `Panzoom.astro` component embeds the metadata as a JSON string in the `data-meta` attribute. The interactivity is then hydrated client-side by [`panzoom_common.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/panzoom_common.js), ensuring the SVG DOM is fully loaded before `svg_add_links()` and `svg_highlight()` execute, regardless of the build output mode.