zudo-doc
GitHub repository

Type to search...

to open search from anywhere

Header Right Items

Created Apr 23, 2026Updated Jul 24, 2026Takeshi Takatsudo

Configure the right-side cluster of the site header with a data-driven array of actions.

The right side of the header — search, theme toggle, language switcher, version switcher, GitHub link, and the Design Token / AI Chat triggers — is rendered from a single array: the headerRightItems field. Each entry is a discriminated-union item rendered in order.

Note

This complements Header Navigation, which configures the left-side tabs. Both are configured in zfb.config.ts and are independent of each other.

Default configuration

zfb.config.ts
export default defineConfig(
  zudoDoc({
    // ...
    githubUrl: "https://github.com/zudolab/zudo-doc",
    headerRightItems: [
      { type: "trigger", trigger: "design-token-panel" },
      { type: "trigger", trigger: "ai-chat" },
      { type: "component", component: "version-switcher" },
      { type: "component", component: "github-link" },
      { type: "component", component: "theme-toggle" },
      { type: "component", component: "search" },
      { type: "component", component: "language-switcher" },
    ],
  }),
);

Item types

component

References a built-in UI piece. Most are gated by their own feature flag; search is ungated.

ComponentFeature flag
theme-togglecolorMode
language-switcherlocales (needs at least one non-default locale)
version-switcherversions
github-linkgithubUrl
searchnone — always available
{ type: "component", component: "github-link" }

When the associated feature is disabled the entry is skipped — you can leave it in the array unconditionally. search has no dedicated feature flag: the renderer is always available, and its presence and position are controlled purely by where (or whether) it appears in the array.

trigger

Opens a built-in modal or panel.

TriggerFeature flag
design-token-paneldesignTokenPanel
ai-chataiAssistant
{ type: "trigger", trigger: "ai-chat" }

The design-token-panel trigger button dispatches the toggle-design-token-panel custom event on window. The zdtp panel (@takazudo/zdtp) listens for this event natively — no additional wiring is needed.

A custom external or internal link, rendered with an optional icon.

{
  type: "link",
  href: "https://discord.example",
  ariaLabel: "Discord",
  icon: "github", // only "github" is bundled today
}

External URLs open in a new tab automatically.

html

Escape hatch for injecting arbitrary markup.

{ type: "html", html: '<span class="text-caption">beta</span>' }

Use sparingly — the html string is rendered verbatim.

Customisation recipes

Point the GitHub icon at your repo

Set githubUrl at the top level of zudoDoc({...}) in zfb.config.ts. The github-link component reads that value, so you don't duplicate the URL inside headerRightItems.

zfb.config.ts
export default defineConfig(
  zudoDoc({
    githubUrl: "https://github.com/your-org/your-repo",
  }),
);

Setting githubUrl: false removes the icon without having to edit the array.

Drop an item

Remove it from the array — don't rely on the feature flag to hide it. For example, to hide the AI chat trigger:

headerRightItems: [
  { type: "trigger", trigger: "design-token-panel" },
  // { type: "trigger", trigger: "ai-chat" },  // removed
  { type: "component", component: "version-switcher" },
  { type: "component", component: "github-link" },
  { type: "component", component: "theme-toggle" },
  { type: "component", component: "language-switcher" },
],
headerRightItems: [
  // ...existing items
  {
    type: "link",
    href: "https://discord.gg/your-server",
    ariaLabel: "Discord",
    icon: "github", // until more icons are bundled
  },
],

Customizing the theme toggle

The built-in theme-toggle component is enough for most sites. Some consumers still keep their own ThemeToggle in their project — to place it in a custom spot, compose it into their own island wrapper, or because they were avoiding the @takazudo/zudo-doc/theme barrel (which has a React-resolution hazard — see below). In all of these cases, import ThemeToggle from the dedicated @takazudo/zudo-doc/theme-toggle subpath instead of hand-copying a local component.

import { ThemeToggle } from "@takazudo/zudo-doc/theme-toggle";

The exported ThemeToggle renders its own <button> with built-in sun/moon icons and accepts a single prop, defaultMode ("light" or "dark"). You can place it anywhere and compose UI around it, but its button markup and icons are fixed — importing it is about reusing the package's toggle (and avoiding the collision below), not restyling it. If you need genuinely different toggle markup or icons, build your own component and give it a name other than ThemeToggle, so it doesn't claim the package's island marker.

Why import the package island

zfb (since 0.1.0-next.39) scans the "use client" modules shipped in npm dist/, and @takazudo/zudo-doc ships a scanner-visible ThemeToggle island. If you hand-copy a local ThemeToggle of the same name, zfb sees two components claiming the ThemeToggle island marker and emits a collision warning on every build:

⚠ island marker name collision: "ThemeToggle" is produced by two different source files —
keeping <consumer>/src/components/theme-toggle.tsx and dropping
<pkg>/@takazudo/zudo-doc/dist/theme-toggle/index.js. ...

The warning is benign — your local component wins and hydrates correctly — but it is noisy and the "keep one, drop one" resolution is scan-order-dependent. Importing ThemeToggle from the package registers under the same marker, so there is nothing to collide with, and you drop the maintenance burden of a hand-rolled copy.

Import from /theme-toggle, not /theme

Pull the toggle from the dedicated @takazudo/zudo-doc/theme-toggle subpath specifically. Do not import it from the broader @takazudo/zudo-doc/theme barrel: that barrel drags the react-importing design-token-panel modules into the esbuild graph, and react is not aliased to preact/compat there. The /theme-toggle subpath is a clean, preact-only module with no react-barrel hazard.

Tweak-state is not cleared on scheme change

The package's applyColorScheme (in theme-toggle/color-scheme-sync.ts) deliberately does not clear design-token panel state when the color scheme changes — @takazudo/zdtp owns its storage lifecycle. Palette, Spacing, Font, and Size tweaks survive a light/dark toggle untouched, and the Color tab's ref/literal defaults re-seed to the new mode while a saved override carries over mode-agnostically until reset. See Mode-scoped editing model for the full semantics.

Ordering

Items render in the order they appear in the array. The cluster is right-aligned, so the first entry sits closest to the nav and the last entry sits closest to the viewport edge.

Revision History

Takeshi TakatsudoCreated: 2026-04-24T02:08:55+09:00Updated: 2026-07-25T02:43:17+09:00

AI Assistant

Ask a question about the documentation.

Preview theme

Loading theme previews…