obsidian/wiki/payloadcms/plugin-nested-docs.md
2026-05-15 16:21:03 +01:00

4 KiB

title aliases tags sources created updated
Nested Docs Plugin
nested-docs
plugin-nested-docs
parent-child-pages
payloadcms
plugin
hierarchy
breadcrumbs
pages
raw/plugins__nested-docs.md
2026-05-15 2026-05-15

Overview

@payloadcms/plugin-nested-docs adds parent/child hierarchy to any collection. It injects two fields — parent (relationship) and breadcrumbs (array) — and recursively updates all descendants whenever a parent changes.

Common use case: hierarchical page tree (/about/company/our-team).

Install

pnpm add @payloadcms/plugin-nested-docs

Basic Setup

import { nestedDocsPlugin } from '@payloadcms/plugin-nested-docs'

buildConfig({
  plugins: [
    nestedDocsPlugin({
      collections: ['pages'],
      generateLabel: (_, doc) => String(doc.title),
      generateURL: (docs) =>
        docs.reduce((url, doc) => `${url}/${String(doc.slug)}`, ''),
    }),
  ],
})

Auto-Injected Fields

parent

  • Relationship field pointing to another doc in the same collection
  • Editor picks the direct parent; plugin builds the full ancestry chain

breadcrumbs

Array of ancestor objects, each with:

Field Default Override via
label admin.useAsTitle or doc ID generateLabel option
url undefined generateURL option

Breadcrumbs cascade automatically — if a grandparent slug changes, every descendant's breadcrumbs update.

Plugin Options

Option Type Description
collections string[] Collection slugs to enable
generateLabel (docs, doc, collection, req) => string Dynamic breadcrumb label
generateURL (docs, doc, collection, req) => string Dynamic breadcrumb URL
parentFieldSlug string Use your own parent field (must be top-level)
breadcrumbsFieldSlug string Use your own breadcrumbs field (must be top-level)

Gotcha: custom parent/breadcrumbs fields must be at the top level — not inside a group, array, or blocks.

Field Overrides

Use createParentField / createBreadcrumbsField to extend the built-in fields:

import { createParentField, createBreadcrumbsField } from '@payloadcms/plugin-nested-docs'

fields: [
  createParentField('pages', {
    admin: { position: 'sidebar' },
    // keep self-reference guard: filterOptions: ({ id }) => ({ id: { not_equals: id } })
  }),
  createBreadcrumbsField('pages', { label: 'Page Breadcrumbs' }),
]

If you override the name of either field, set parentFieldSlug / breadcrumbsFieldSlug in plugin options.

Localization

When localization is enabled in Payload Config, the breadcrumbs field is automatically localized. See wiki/payloadcms/localization.

TypeScript

import type {
  NestedDocsPluginConfig,
  GenerateURL,
  GenerateLabel,
} from '@payloadcms/plugin-nested-docs/types'

Key Takeaways

  • Plugin injects parent + breadcrumbs fields; updates cascade recursively down the tree
  • generateURL builds full paths like /about/company/our-team from breadcrumb docs array
  • Custom fields are supported — set parentFieldSlug/breadcrumbsFieldSlug and place them at top-level only
  • Use createParentField/createBreadcrumbsField when you need sidebar placement or label overrides
  • Localization is automatic when Payload's localization config is set
  • Official Website Template in the Payload repo uses this plugin as a reference

Sources