コンテンツにスキップ

Sidebarのカスタマイズ

Starlightテーマのサイドバーに絵文字を追加できるようにカスタマイズしたい。

astro-iconifyの機能が使えるようにするのが目的。

  1. astro-iconifyをインストールする。

    Terminal window
    npm install astro-iconify
  2. オーバーライド用のSidebar.astroを作成する

    src/components/Sidebar.astro
    ---
    import { Icon } from 'astro-iconify';
    // Route Data からサイドバー配列と表示フラグを取得(公式推奨)
    const { sidebar = [], hasSidebar = true } = Astro.locals.starlightRoute;
    // "icon:pack:name テキスト" というラベルを分解するヘルパ
    function parseIconLabel(label: any) {
    const m = /^icon:([a-z0-9:-]+)\s+(.+)$/.exec(label);
    return m ? { icon: m[1], text: m[2] } : { text: label };
    }
    // オート生成グループ(type === 'group')だけを最小レンダリング対象にする
    // (リンク直列などは本例では扱わず、Starlight が生成する標準構造に寄せる)
    const groups = sidebar.filter((e) => e && e.type === 'group').map((g) => {
    const p = parseIconLabel(g.label);
    return {
    ...g,
    _icon: p.icon,
    _text: p.text,
    // 子はリンクのみを想定(入れ子グループは必要になったら拡張)
    _links: Array.isArray(g.entries) ? g.entries.filter((x) => x && x.type === 'link') : []
    };
    });
    ---
    {hasSidebar && (
    <nav class="sl-sidebar" aria-label="Main navigation">
    <div class="sl-sidebar-content">
    <ul class="sl-top-level">
    {groups.map((group) => (
    <li>
    <details open={group.collapsed ? false : true}>
    <summary class="sl-group-title">
    {group._icon && (
    <Icon name={group._icon} width="1.15em" height="1.15em" class="sl-group-icon" aria-hidden="true" />
    )}
    <span>{group._text}</span>
    {group.badge && <span class="sl-badge">{typeof group.badge === 'string' ? group.badge : (group.badge.text || '')}</span>}
    </summary>
    <ul class="sl-link-list">
    {group._links.map((link) => (
    <li>
    <a href={link.href} aria-current={link.isCurrent ? 'page' : undefined} class="sl-link">
    <span>{link.label}</span>
    {link.badge && <span class="sl-badge">{typeof link.badge === 'string' ? link.badge : (link.badge.text || '')}</span>}
    </a>
    </li>
    ))}
    </ul>
    </details>
    </li>
    ))}
    </ul>
    </div>
    <style>
    .sl-sidebar{ padding:.5rem .75rem; }
    .sl-top-level{ list-style:none; margin:0; padding:0; }
    .sl-top-level>li{ margin:.25rem 0; }
    .sl-group-title{ display:inline-flex; align-items:center; gap:.4em; font-weight:700; }
    .sl-group-icon{ vertical-align:-0.15em; margin-right:.1em; }
    .sl-badge{ margin-left:.5em; font-size:.85em; opacity:.75; }
    .sl-link-list{ list-style:none; margin:.25rem 0 0 .8rem; padding:0; }
    .sl-link{ display:inline-block; padding:.2rem 0; text-decoration:none; }
    .sl-link[aria-current="page"]{ text-decoration:underline; font-weight:600; }
    details>summary{ cursor:pointer; }
    </style>
    </nav>
    )}
  3. 設定ファイルでcomponentsのオーバーライドを追加する。

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import starlight from '@astrojs/starlight';
    export default defineConfig({
    integrations: [
    starlight({
    // ここを追加
    components: { Sidebar: './src/components/Sidebar.astro' },
    // ← 既存の設定はそのまま
    sidebar: [
    { label: 'icon:fluent-emoji-flat:house Home Page', autogenerate: { directory: 'home' } },
    { label: 'icon:fluent-emoji-flat:microscope ラボで作った技術', autogenerate: { directory: 'techlab' } },
    { label: 'icon:fluent-emoji-flat:orange-book 日記', autogenerate: { directory: 'diary' } },
    { label: 'icon:fluent-emoji-flat:rocket Astro', autogenerate: { directory: 'astro-tech' } },
    { label: 'icon:fluent-emoji-flat:books 研究', autogenerate: { directory: 'study' } },
    { label: 'icon:fluent-emoji-flat:fire Rust', autogenerate: { directory: 'rust' } },
    { label: 'icon:fluent-emoji-flat:warning Private', autogenerate: { directory: 'private' } }
    ],
    }),
    ],
    });

これでlabelicon:fluent-emoji-flat:house Home Pageのようにicon:アイコン名で設定すると、サイドバーに絵文字が表示されるようになる。