zfb
GitHub repository

Type to search...

to open search from anywhere

getCollection

Load all entries from a content or data collection.

Signature

getCollection<T = Record<string, unknown>>(name: string): CollectionEntry<T>[]

Call getCollection from a page module to load every entry in a named collection. The collection must be declared in your zfb.config under collections. The function is synchronous — it returns a plain array, not a Promise. The TypeScript generic T is a type hint only; schemas are not checked inside getCollection or during zfb build.

Schema validation runs in zfb check, not in zfb build. The build snapshots collection entries and preserves their parsed frontmatter, but schema violations are enforced by the check command so CI should run zfb check when schemas matter.

getEntry

getEntry<T = Record<string, unknown>>(
  name: string,
  slug: string,
): CollectionEntry<T> | undefined

Use getEntry(name, slug) to load one entry from a collection. It shares the same snapshot/filesystem resolution path as getCollection, returning undefined when the collection has no matching slug.

import { getEntry } from "@takazudo/zfb/content";

export default function FeaturedPost() {
  const post = getEntry<{ title: string }>("blog", "hello-zfb");
  if (!post) return <p>Post not found</p>;
  return <post.Content />;
}

CollectionEntry shape

Each entry has the following fields:

  • slug: string — the collection-relative path with one trailing .md, .mdx, or .tsx extension stripped, normalized to forward-slash paths. Nested files produce path-based slugs (e.g. "2024/hello").

  • data: T — the parsed frontmatter, typed by the generic parameter.

  • body: string — the raw markdown body with frontmatter stripped.

  • module_specifier: string — stable bridge key used internally by the renderer to look up the compiled module. .md / .mdx entries get mdx://<collection>/<slug>#<hash> (with the entry's markdown body populated); .tsx entries get tsx://<collection>/<slug>#<hash> (with an empty body — there's no separate markdown body). The trailing hash is derived from the compiled JSX source. Pass the specifier to a custom Content lookup if building your own bridge.

  • Content: (props: ContentProps) => ContentElement — renderable component for this entry. Renders via the renderer bridge when available; falls back to a <pre data-zfb-content-fallback> block in test and dev contexts where the bridge is absent.

ContentProps

type ContentProps = {
  components?: Record<string, unknown>;
};

The components prop mirrors the Astro <Content components={...}> convention: a flat map of element name to override component. Use defaultComponents from "@takazudo/zfb" as a base:

import { defaultComponents } from "@takazudo/zfb";

<entry.Content components={{ ...defaultComponents, h2: MyHeading }} />

Example

A typical use case is rendering a list of blog posts on an index page.

import { getCollection } from "@takazudo/zfb/content";

export default function BlogIndex() {
  const posts = getCollection<{ title: string; date: string }>("blog");

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.slug}>
          <a href={`/blog/${post.slug}`}>{post.data.title}</a>
        </li>
      ))}
    </ul>
  );
}

Note that getCollection and getEntry return synchronously — no await needed. For dynamic per-entry pages, combine getCollection with a paths() export — see paginate for the related pattern.

Revision History

CreatedUpdated