Example Application Walkthrough
Relevant source files
The following files were used as context for generating this wiki page:
The wouter-vue example application serves as a comprehensive demonstration of a minimalist routing architecture for Vue 3. It showcases core routing capabilities including static and dynamic route matching, asynchronous component loading with Vue's Suspense, and hierarchical data passing between routing components.
The application is structured as a monorepo example that implements standard web patterns such as 404 handling, programmatic navigation, and active link styling, while maintaining a tiny footprint of approximately 2KB gzipped.
Sources: README.md:12-18, examples/example/README.md:1-12
Application Structure and Routing Logic
The example application organizes its logic into a clear directory structure where the main entry point sets up the routing tree using the <Router /> component. This component acts as the provider for routing context, although it is optional in wouter-vue's minimalist philosophy.
Core Routing Components
The application primarily utilizes three components from the wouter-vue library:
- Router: Provides the top-level routing context.
- Route: Matches the current URL path to a specific component.
- Link: Handles navigation while maintaining active state detection.
The following diagram illustrates the component hierarchy and the flow of navigation within the example app:
The routing tree handles both static paths (like /about) and dynamic segments (like /users/:id).
Sources: examples/example/README.md:27-38, README.md:118-132
Dynamic and Parameterized Routing
The example demonstrates advanced route matching using path-to-regexp. Specifically, the UserDetailPage.vue showcases how to extract parameters from the URL.
URL Parameter Extraction
When a user navigates to /users/1, the router identifies :id as a dynamic segment. The component accesses this data using the useParams composable, which returns a reactive object containing the matched parameters.
import { useParams } from 'wouter-vue';
const params = useParams();
// params.value.id will be '1'
Sources: examples/example/src/pages/UserDetailPage.vue:42-45, examples/example/README.md:63-69
Reactive Data Summary
| Parameter | Method | Description |
|---|---|---|
id | useParams() | Dynamic segment for identifying specific users. |
location | useLocation() | Returns the current path and a function to update it. |
searchParams | useSearchParams() | Provides reactive access to URL query strings. |
routeData | useRouteData() | Accesses hierarchical data passed from parent routes. |
Sources: examples/example/src/pages/AboutPage.vue:64-70, examples/example/src/pages/UserDetailPage.vue:45
Asynchronous Loading and Performance
A key feature demonstrated in the example is the integration with Vue's Suspense for code splitting. This is specifically used for the "Heavy Page" to ensure the initial bundle remains small.
The HeavyPage is defined using defineAsyncComponent, allowing the application to load the JavaScript for that specific page only when requested.
Sources: examples/example/README.md:46-59, examples/example/src/pages/HomePage.vue:24
Hierarchical Data Passing
The application demonstrates a unique feature of wouter-vue: the ability to pass reactive data down the routing tree. In AboutPage.vue, the component consumes data such as theme, layout, and version which are not part of the URL but are passed hierarchically through the routing components.
| Data Property | Type | Source |
|---|---|---|
theme | String | Passed via <Route> or <AnimatedSwitch> |
layout | String | Parent routing configuration |
pageName | String | Specific route metadata |
This data is merged automatically and can be accessed either via props or the useRouteData() composable.
Sources: examples/example/src/pages/AboutPage.vue:8-25, examples/example/src/pages/AboutPage.vue:72-74
Navigation and Active States
Navigation in the example is handled via the <Link /> component. It provides a scoped slot or a functional class binding to detect if the link is currently active.
<Link href="/" :class="isActive => isActive ? 'active' : ''">
Home
</Link>
For programmatic navigation, the app uses the useLocation hook, which follows the pattern: const [location, navigate] = useLocation(). Calling navigate('/path') updates the browser history and triggers the route matching logic.
Sources: examples/example/README.md:71-85, examples/example/src/pages/AboutPage.vue:69
Conclusion
The wouter-vue example application effectively illustrates how a minimalist router can handle complex application requirements like SSR, async loading, and dynamic routing without the overhead of larger libraries. By leveraging the Vue 3 Composition API and standard patterns like Suspense, it provides a performant foundation for high-traffic Vue applications.