The frontmatter preview block renders custom frontmatter fields as a compact key/value table below the page title — useful for surfacing document metadata such as authorship, status, or version without embedding it inline in the prose. It is not automatic in a fresh scaffold: `frontmatterPreview` defaults to `false`, and the unbound `buildFrontmatterPreviewEntries` slot defaults to `() => []`.

This showcase page demonstrates the feature: the `author` and `status` fields rendered above were declared in its own frontmatter and its showcase bindings supply the entry builder.

[Dynamic content unavailable in text export]

`buildFrontmatterPreviewEntries` defaults to a no-op. Point
`chromeBindingsModule` at a module that binds it. Fresh route stubs already
consume the module; do not edit them. See [Custom Components](https://zudo-doc.takazudomodular.com/docs/guides/custom-components)
and [Host Chrome Bindings](https://zudo-doc.takazudomodular.com/docs/reference/host-chrome-bindings).



Enable the setting and create the builder in your bindings module. Keep the value passed to
`frontmatterPreview` in the builder aligned with the `zudoDoc()` setting.

```ts title="src/chrome-bindings.ts"
import { defineChromeBindings } from "@takazudo/zudo-doc/chrome-bindings";
import { createBuildFrontmatterPreviewEntries } from "@takazudo/zudo-doc/frontmatter-preview-data";
import { defaultFrontmatterPreviewIgnoreKeys } from "@takazudo/zudo-doc/frontmatter-preview-defaults";
import { frontmatterRenderers } from "./frontmatter-preview-renderers";

export const chromeBindings = defineChromeBindings({
  buildFrontmatterPreviewEntries: createBuildFrontmatterPreviewEntries({
    frontmatterPreview: {},
    defaultIgnoreKeys: defaultFrontmatterPreviewIgnoreKeys,
  }),
  frontmatterRenderers,
});
```

```ts title="zfb.config.ts"
export default defineConfig(
  zudoDoc({
    frontmatterPreview: {},
    chromeBindingsModule: "./src/chrome-bindings.ts",
  }),
);
```

## When the Block Appears

Once enabled and bound, the block appears only when at least one frontmatter key survives filtering. Framework-managed keys (`title`, `description`, `sidebar_position`, `tags`, etc.) are stripped by default. If every key is on the ignore list, nothing is rendered.

Set `frontmatterPreview: false` in `zfb.config.ts` (the `zudoDoc({...})` call) to disable the feature entirely for all pages.

## Default Ignore List

The following keys are ignored by default. They correspond to every field defined in the content schema and would be redundant to show again:

| Key | Reason |
|-----|--------|
| `title` | Rendered as the page `h1` |
| `description` | Shown as a subtitle below the title |
| `sidebar_position` | Internal navigation metadata |
| `sidebar_label` | Internal navigation metadata |
| `category` | Internal navigation metadata |
| `tags` | Rendered separately as tag badges |
| `search_exclude` | Build-time flag |
| `pagination_next` | Build-time flag |
| `pagination_prev` | Build-time flag |
| `draft` | Build-time flag |
| `unlisted` | Build-time flag |
| `hide_sidebar` | Layout flag |
| `hide_toc` | Layout flag |
| `standalone` | Layout flag |
| `slug` | URL override |
| `generated` | Build-time flag |

Once the builder is bound, any key not in this list is shown automatically.

## Customizing the Ignore List

The `frontmatterPreview` field in `zudoDoc({...})` (set in `zfb.config.ts`) accepts two mutually exclusive knobs.

### `extraIgnoreKeys` — extend the defaults

Add keys to the ignore list without discarding the defaults. Use this when you have a project-wide custom frontmatter field that should remain hidden everywhere:

```ts
frontmatterPreview: {
  extraIgnoreKeys: ["reviewed_by", "internal_id"],
},
```

### `ignoreKeys` — replace the defaults

Completely replaces the built-in ignore list. Use this when you want full control over which keys are hidden. When `ignoreKeys` is present, `extraIgnoreKeys` is ignored.

```ts
frontmatterPreview: {
  ignoreKeys: ["title", "description", "sidebar_position"],
},
```

[Dynamic content unavailable in text export]

Using `ignoreKeys` without including the standard schema keys can expose framework-internal fields like `draft` or `unlisted` in the rendered table. In most cases, `extraIgnoreKeys` is the safer choice.



## Disable the Feature

Set `frontmatterPreview: false` to remove the block from all pages at once:

```ts
frontmatterPreview: false,
```

## Example

The following frontmatter produces a preview table with `author` and `status` visible, while `title`, `description`, and `sidebar_position` are filtered out:

```mdx
---
title: My Release Notes
description: What changed in v2.
sidebar_position: 5
author: Jane Doe
status: released
---
```

The rendered table shows:

| Key | Value |
|-----|-------|
| `author` | Jane Doe |
| `status` | released |

For the full configuration reference, see [Configuration — frontmatterPreview](https://zudo-doc.takazudomodular.com/docs/guides/configuration#site-settings-frontmatterpreview).

## Custom Renderers

By default, frontmatter values render as plain text. To replace a value with a styled component — a colored pill, a link, an icon — create a renderer map and bind it through the `frontmatterRenderers` slot shown above. This repository's `src/config/frontmatter-preview-renderers.tsx`, threaded through `src/chrome-bindings.tsx`, is a showcase wiring example; a fresh scaffold has neither file.

### Component contract

Each renderer is a zudo-react component that receives `FrontmatterCellRendererProps` from `@takazudo/zudo-doc/metainfo`:

| Prop | Type | Description |
|------|------|-------------|
| `value` | `NonNullable<unknown>` | The frontmatter value (null/undefined values are never passed) |
| `entryKey` | `string` | The frontmatter key name |
| `data` | `Record<string, unknown>` | Full frontmatter of the current page |
| `locale` | `string \| undefined` | Active locale |

### Registering a renderer

Add a key to your renderer map. Each value is a component function that receives `FrontmatterCellRendererProps` and returns JSX or `null`:

```tsx
discount: ({ value }) => {
  if (value !== true) return null;
  return (
    <span class="inline-block px-hsp-sm py-vsp-2xs text-caption rounded-full bg-danger text-fg">
      ON SALE
    </span>
  );
},
```

This page's own frontmatter includes `discount: true`, `status: "stable"`, and `difficulty: "beginner"` — the metadata table at the top of this page shows them rendered as colored pills.

### Ignore-list precedence

A renderer registered for an ignored key has no effect. The ignore list is applied _before_ renderer lookup — if a key is suppressed, the row is never rendered and the renderer is never called.

To surface a framework-managed key (such as `draft`) with a custom renderer, first remove it from the ignore list in your `frontmatterPreview` config (set in `zfb.config.ts`):

```ts
frontmatterPreview: {
  // Must explicitly list all keys to keep hidden — ignoreKeys replaces the defaults
  ignoreKeys: ["title", "description", "sidebar_position", "tags"],
},
```

[Dynamic content unavailable in text export]

`ignoreKeys` replaces the entire default ignore list. Omitting standard schema keys like `tags`, `slug`, or `unlisted` will expose them in the preview table. In most cases, use `extraIgnoreKeys` to extend the defaults instead.



The showcase's renderer map is not scaffolded or auto-consumed. Bind your own map through `frontmatterRenderers`; omitting that slot leaves all values on the plain-text fallback.