Navigation link component for Yew with automatic active state detection.
yew-nav-link provides a NavLink component that wraps Yew Router's Link with automatic active state management. When the target route matches the current URL, an active CSS class is applied automatically.
[dependencies]
yew-nav-link = "0.4"| Dependency | Version |
|---|---|
| yew | 0.22+ |
| yew-router | 0.19+ |
Full working examples are available in the examples/ directory:
| Example | Description |
|---|---|
| basic | Simple navigation with Home, About, Contact pages |
| bootstrap | Integration with Bootstrap 5 navbar |
| tailwind | Sidebar navigation styled with Tailwind CSS |
| nested-routes | Multi-level navigation with partial matching |
# Install prerequisites (once)
rustup target add wasm32-unknown-unknown
cargo install trunk
# Run example
cd examples/basic
trunk serveOpen http://127.0.0.1:8080 in your browser.
use yew::prelude::*;
use yew_nav_link::NavLink;
use yew_router::prelude::*;
#[derive(Clone, PartialEq, Routable)]
enum Route {
#[at("/")]
Home,
#[at("/about")]
About,
}
#[component]
fn Navigation() -> Html {
html! {
<nav>
<NavLink<Route> to={Route::Home}>{ "Home" }</NavLink<Route>>
<NavLink<Route> to={Route::About}>{ "About" }</NavLink<Route>>
</nav>
}
}For text-only links, use nav_link with explicit Match mode:
use yew::prelude::*;
use yew_nav_link::{nav_link, Match};
use yew_router::prelude::*;
#[derive(Clone, PartialEq, Routable)]
enum Route {
#[at("/")]
Home,
#[at("/docs")]
Docs,
}
#[component]
fn Menu() -> Html {
html! {
<nav>
{ nav_link(Route::Home, "Home", Match::Exact) }
{ nav_link(Route::Docs, "Docs", Match::Partial) }
</nav>
}
}Use partial prop to keep parent links active on nested routes:
use yew::prelude::*;
use yew_nav_link::NavLink;
use yew_router::prelude::*;
#[derive(Clone, PartialEq, Routable)]
enum Route {
#[at("/docs")]
Docs,
#[at("/docs/api")]
DocsApi,
}
#[component]
fn Navigation() -> Html {
html! {
<nav>
// Active on /docs, /docs/api, /docs/*
<NavLink<Route> to={Route::Docs} partial=true>{ "Docs" }</NavLink<Route>>
</nav>
}
}The component applies these classes to the rendered <a> element:
| Class | When Applied |
|---|---|
nav-link |
Always |
active |
Route matches current URL |
<ul class="nav nav-pills">
<li class="nav-item">
<NavLink<Route> to={Route::Home}>{ "Home" }</NavLink<Route>>
<!-- Renders: <a class="nav-link active" href="/">Home</a> -->
</li>
</ul>.nav-link {
@apply px-4 py-2 text-gray-600 hover:text-gray-900;
}
.nav-link.active {
@apply text-blue-600 font-semibold;
}| Prop | Type | Default | Description |
|---|---|---|---|
to |
R: Routable |
required | Target route |
children |
Children |
required | Link content |
partial |
bool |
false |
Enable prefix matching |
| Variant | Description |
|---|---|
Match::Exact |
Active only on exact path match |
Match::Partial |
Active when current path starts with target |
fn nav_link<R: Routable>(to: R, children: &str, match_mode: Match) -> HtmlCreates a NavLink with text content and specified match mode.
Code coverage is tracked via Codecov. Target: 95%+ coverage.
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice represents the number of statements and the coverage, respectively.
Each block represents a single file in the project. The size and color of each block represents the number of statements and the coverage, respectively.
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice represents the number of statements and the coverage, respectively.
Licensed under the MIT License.