canvas-navigation-components
About canvas-navigation-components
A skill for building navigation components in Drupal Canvas and React projects. It guides component decomposition, data-source selection, and accessible markup for menus, breadcrumbs, and static navigation.
Key features
- 01Decompose navigation into regions
- 02Choose menu, breadcrumb, or static data
- 03Fetch Drupal menus with SWR
- 04Configure menu props and component slots
- 05Follow navigation accessibility guidance
Use cases
- 01Build reusable main or footer navigation
- 02Load links from Drupal menus
- 03Show breadcrumbs from the current page
- 04Compose mega-menus with multiple columns
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ drupal-canvas/ skills --skill canvas-navigation-componentsAfter installing, type/canvas-navigation-componentsin Claude Code to confirm it loaded.
Bundled filesreferences/data-sources.md
Details
From the project READMECanvas navigation components
Project type
Before applying this skill, check package.json for a dependency named
@drupal-canvas/headless or starting with @drupal-canvas/headless-. If one is
present, this is a Canvas Headless codebase — read
canvas-headless first. The decomposition,
naming, and accessibility guidance below applies unchanged. React components use
the portable hooks and SWR patterns below in Drupal, Workbench, and React
headless projects. Headless server code uses the SDK's getClient(); native
non-React components use framework-native data loading and page context. If no
such dependency is present, this is a Canvas-rendered React codebase: components
are React (index.jsx/.tsx) and everything in this skill applies as written.
These are the only two project types.
Build navigation that fits Canvas: reusable names, clear props
(variant, menuName) and slots (logo, utilities, mega-menu regions),
correct data source (Drupal menu vs breadcrumb context vs static), and
accessible markup.
This skill stacks on:
canvas-design-decomposition— regions, tree, prop/slot sketch, reuse-first naming before code.canvas-data-fetching— SWR,useJsonApiClient, menu resource pattern, Workbench rules.
Then apply canvas-component-metadata,
canvas-component-definition
(including
references/naming.md),
canvas-styling-conventions, and
canvas-component-composability
for slots and repeatable groups.
Workflow (order matters)
1. Decompose (mandatory)
Follow canvas-design-decomposition
through at least Phase E (props/slots) before writing React or
component.yml.
Navigation-specific prompts:
- Separate chrome (bar, drawer shell) from link lists and optional columns (footer, mega-menu). Prefer composition over one god-component.
- Repeating link groups or cards → parent + child pattern per
canvas-component-composability/references/repeatable-content.md. - Use generic
machineNames (main-navigation,footer-navigation), not page-specific names. Express placement in the page, not the component name. - Sketch
variantfor layout modes (horizontal, drawer, compact footer). - Add
menuNamein the sketch when the nav reads from a Drupal menu (see step 2). Use slots for logo, utility links, or CTAs when authors compose those blocks.
2. Choose a data source
See references/data-sources.md for a decision table. Summary:
| Source | When |
|---|---|
| Drupal menu | Editors manage links in Structure → Menus; use menu_items + getResource |
| Breadcrumb | Trail from current page context via usePageContext() |
| Static | Rare; document why; still provide sensible defaults or slots |
3. Implement the fetch (Drupal menu)
Use the Navigation / Menu Components section in
canvas-data-fetching:
- Read
clientwithuseJsonApiClient()fromdrupal-canvas/react. useSWR(client && menuName ? ['menu_items', menuName] : null, ([type, id]) => client.getResource(type, id))Array.from(sortMenu(data))when data is valid; otherwiseFALLBACK_LINKS. Do not hide available data behindisLoadingor disguise draft-session failures as successful fallback content.- Always define
FALLBACK_LINKSso Workbench and sites without the menu still render. - Expose
menuNameincomponent.ymlwhen editors should pick the Drupal menu (machine name, e.g.main,footer). Hard-coding only the default in JSX without a prop is fine for examples; production nav that must switch menus should registermenuNameper data-fetching rules. - Set
menuNameexplicitly to null to disable fetching for static-only previews; omission may select the component's default menu.
Do not fabricate JSON:API menu payloads in Workbench mocks. Prefer real loading/error/empty behavior; fallback links cover the empty-menu case.
Menus in Drupal (preferred): Production navigation should live in Drupal
menus (CMS), not only as hardcoded arrays in code. FALLBACK_LINKS are
for Workbench / empty-menu cases — not a long-term substitute for CMS menus on a
real site.
On Acquia Source, prefer creating or updating menus via Source MCP using
acquia-source-navigation-menus
when automating that environment; otherwise use Structure → Menus in Drupal.
Align menu_name with this component’s menuName prop.
For non–Acquia Source targets, use the Drupal admin (or your deployment
process) — do not apply the Source MCP menu skill. If there is no admin/MCP
access, tell the user exactly which menus to create (match menuName /
machine names such as main, footer) and link to Structure → Menus as in
canvas-data-fetching.
4. Breadcrumbs
Breadcrumbs come from page context, not menu_items. Read
usePageContext() from drupal-canvas/react unconditionally, then handle a
null page or an empty breadcrumbs collection. Read existing patterns before
inventing fields. Workbench supplies empty breadcrumbs by default; verify real
page trails in the routed application. Preserve Drupal-generated URLs unless the
application explicitly adapts routing.
5. Accessibility (minimum)
- Wrap primary link lists in
<nav>with distinctaria-label(oraria-labelledbypointing at visible heading text). - Mobile toggles:
aria-expanded,aria-controlswhen you wire IDs; buttontype="button". - Do not mark every link
aria-current="page"—only the true current item when the design requires it. - Nested lists (mega-menu, footer columns): preserve list semantics where appropriate; keep tab order predictable.
6. Metadata and styling
- Props/slots YAML:
canvas-component-metadata. - Folder and mocks:
canvas-component-definition. - Tailwind tokens:
canvas-styling-conventions.
Reference example
The canonical menu + SWR + sortMenu example lives in
canvas-data-fetching,
including the menuName metadata for editor configuration.
Mega-menu and nested menus
- Model composition: parent nav shell + slots for columns or featured blocks; child components for link groups.
- Nested menu shape: do not assume raw JSON:API nesting. Probe deserialized
output with the same
JsonApiClientcall the component will use (seecanvas-data-fetching) before mapping children.
Further reading
Anti-duplication
- Full menu code samples and
menuNameYAML live under Navigation / Menu Components incanvas-data-fetching. - Decomposition phases A–G are not repeated here—use
canvas-design-decomposition.