Purpose

One entry in a frontend nav contribution. A flat list of these (possibly with nested children) is what a builder returns from FrontendNavRegistry. The theme walks the list and emits HTML.

The class is deliberately minimal: a URL, a label, a sort key, a children list. No isActive, no isCurrent, no icon, no badge. Active state is render-time and depends on the request URL; the renderer compares against $site->urlSegments. Extra visual metadata belongs in the theme, not in a cross-plugin DTO.

FQCN + file path

When to use

You construct NavItem instances inside a nav builder registered with PluginContext::contributeFrontendNav(). You never receive a NavItem from any other API surface; the registry hands the list back to themes for rendering, where you consume it as data, not as something to mutate.

Surface

public function __construct(
    public string $url,
    public string $label,
    public int $position = 0,
    public array $children = [],   // list<NavItem>
)

All four fields are public readonly (the class is final readonly):

Field Type Purpose
url string Either absolute (https://...) or rooted (/docs/). The theme prepends $site->siteUrl when it sees a leading slash
label string The text the link displays. Plain text; the renderer escapes it
position int Sort key inside FrontendNavRegistry::collect(). Lower wins. Default 0
children list<NavItem> Nested entries. Empty by default; supply when the section has sub-nav

There are no methods. The DTO is just data.

Lifecycle

Constructed by a nav builder, returned through FrontendNavRegistry::collect(), consumed by the theme. Lives for one render pass. final readonly, so an instance is safe to share between collaborators in the same request without copying.

Common patterns

Top-level entry pointing at a section

new NavItem(
    url:      '/developer-guide/',
    label:    'Developer Guide',
    position: 20,
);

Nested entries

new NavItem(
    url:      '/developer-guide/',
    label:    'Developer Guide',
    position: 20,
    children: [
        new NavItem('/developer-guide/concepts/',       'Concepts',       10),
        new NavItem('/developer-guide/build-a-theme/',  'Build a Theme',  20),
        new NavItem('/developer-guide/build-a-module/', 'Build a Module', 30),
        new NavItem('/developer-guide/api/',            'API',            40),
    ],
);
new NavItem(
    url:      'https://github.com/bigin/Scriptor',
    label:    'GitHub',
    position: 90,
);

See also