NavLink
A navigation link that auto-detects and styles the current route, with prefix matching, external links and a collapsible NavGroup.
Last updated
Show codeHide code
<NavLink href="/docs">Docs</NavLink>
<NavLink href="/pricing">Pricing</NavLink>
<NavLink href="/about" active>About</NavLink>Add
npx @ava-ui/apogee add nav-link
Uses @lucide/astro. NavGroup lives in the same folder and is copied with it.
Usage
---
import NavLink from '@/components/apogee/NavLink/NavLink.astro'
---
<NavLink href="/docs">Docs</NavLink>
The active state is automatic: it compares Astro.url.pathname to href
(trailing slashes normalized), so the current page’s link lights up with no
extra markup. match="prefix" also lights a section link on its child pages.
Pass active to override.
API
@composable — exposed to Content Editors in AVA. Any other native <a>
attribute passes through (...rest).
| Prop | Type | Default | Description |
|---|---|---|---|
href |
string |
— | Link target. |
active |
boolean |
auto-detected | Forces the active state. Default compares the current URL’s pathname to href. |
match |
'exact' | 'prefix' |
'exact' |
prefix also marks /docs active on /docs/button; / only ever matches itself. |
external |
boolean |
auto from href |
Opens in a new tab (target, rel) with a trailing icon and a screen-reader note. Auto-detected for http hrefs; pass false to opt out. |
externalLabel |
string |
'(opens in a new tab)' |
Screen-reader text after an external link. |
class |
string |
— | Extra classes, merged last. |
States
Show codeHide code
<NavLink href="/docs">Inactive</NavLink>
<NavLink href="/docs" active>Active</NavLink>- Inactive (default) — muted text, brightens on hover.
- Active —
aria-current="page"and full-contrast text; auto-detected from the URL, or forced viaactive. - Focus — a visible
focus-visiblering.
Matching
match="prefix" on a section link. This page is /docs/nav-link, so the
/docs link is active and the / link is not:
Show codeHide code
<NavLink href="/docs" match="prefix">Docs</NavLink>
<NavLink href="/" match="prefix">Home</NavLink>External links
An http href opens in a new tab with a trailing icon:
Show codeHide code
<NavLink href="https://astro.build">Astro</NavLink>NavGroup
A collapsible group on native <details>. It opens on load when a child is
the current page:
Projects3
Show codeHide code
<NavGroup label="Docs">
<BookOpen slot="start" />
<NavLink href="/docs/nav-link">NavLink</NavLink>
<NavLink href="/docs/navbar">Navbar</NavLink>
</NavGroup>
<NavGroup label="Projects">
<FolderKanban slot="start" />
<NavLink href="#">Spring launch</NavLink>
</NavGroup>| Prop | Type | Default | Description |
|---|---|---|---|
label |
string |
— | The summary row’s text. |
open |
boolean |
auto | Force open or closed; by default the group opens when it contains the current page. |
class |
string |
— | Extra classes on the <details>. |
Slots
start and end take an icon, badge or count. end is pushed to the far edge when the link fills its width (a sidebar) and sits inline in a horizontal navbar.
Show codeHide code
<NavLink href="#"><Inbox slot="start" /> Inbox <Badge slot="end" size="small">12</Badge></NavLink>Examples
A link row, built for use inside Navbar’s default slot:
<NavLink href="/docs">Docs</NavLink>
<NavLink href="/pricing">Pricing</NavLink>
<NavLink href="/blog">Blog</NavLink>
Accessibility
- Real
<a>— full keyboard + AT support for free. aria-current="page"is set on the active link, so assistive tech announces it as the current page (not just visually distinct).- Focus ring is always visible on keyboard focus.
Tokens
| Token | Used for |
|---|---|
--foreground-neutral |
Active link text |
--foreground-neutral-faded |
Inactive link text |
--outline-color-focus |
Focus ring |
Do / Don’t
- Do let the active state auto-detect — only pass
activewhen the route can’t be matched by pathname (e.g. a hash-based section link). - Do use NavLink for site navigation, inside
Navbaror aSidebar. - Don’t use NavLink for an action — use
Button. - Don’t hard-code the active state on every page; that defeats the point of auto-detection and drifts out of sync.
Content
- Labels are nouns, sentence case, one or two words (“Docs”, “Pricing”).
- No ending punctuation.