Creating Custom Location Hooks
Relevant source files
The following files were used as context for generating this wiki page:
Custom location hooks in wouter-vue are the core mechanism for defining how the router interacts with the environment's address bar or navigation state. While the library provides default hooks for browser history and hash-based routing, developers can implement custom hooks to support specialized environments like testing, non-browser platforms, or custom state management systems.
These hooks leverage Vue 3's Composition API to provide a reactive state representing the current path and a function to trigger navigation. This architecture allows the router to remain agnostic of the actual underlying navigation mechanism.
Sources: README.md, package.json:11-13, src/index.ts
Architecture of a Location Hook
A location hook is a function that returns a tuple containing a reactive reference to the current location (string) and a navigation function. This navigation function typically accepts a path and an optional options object (e.g., for replacing history entries).
Data Flow and Interaction
The following diagram illustrates how a custom location hook sits between the Router component and the environment's state:
The Router component consumes the hook to determine which Route should be active based on the reactive state provided.
Sources: src/index.ts, test/link.test.ts:46-55
Implementing the Hook Interface
A custom hook must adhere to the specific signature expected by the Router's hook prop.
Key Components
| Component | Type | Description |
|---|---|---|
| Location State | Ref<string> | A reactive Vue reference containing the current path. |
| Navigate Function | (to: string, options?: { replace?: boolean }) => void | A function that updates the location state and handles history logic. |
Memory Location Example
The memory-location utility is a primary example of a custom hook used for testing. It stores the navigation state in a local variable rather than the browser's window.history.
// Conceptual structure based on usage in tests
export const memoryLocation = ({ path = "/" } = {}) => {
const location = ref(path);
const hook = () => [location, (to) => { location.value = to; }];
return { hook, navigate: (to) => { location.value = to; } };
};
Sources: src/memory-location.ts, test/nested-route.test.ts:18-20, test/link.test.ts:46-50
Integration with Router and Components
Once created, the custom hook is passed to the <Router /> component. All child components like <Route /> and <Link /> will automatically use this hook to sync their state.
Sequence of Navigation
When a user clicks a <Link />, the following sequence occurs within the custom hook context:
Programmatic Usage
Inside components, developers can access the hook's functionality using useLocation(), which retrieves the current router's hook context.
<script setup>
import { useLocation } from 'wouter-vue';
const [location, navigate] = useLocation();
const goToUser = (id) => navigate(`/users/${id}`);
</script>
Sources: examples/example/README.md:104-109, src/index.ts
Advanced Hook Features
Support for Options
Custom hooks should handle the replace option to mimic native history behavior. In the library's tests, the replace property is explicitly checked to ensure history stack integrity.
Sources: test/link.test.ts:71-78
Basepath Integration
While hooks manage the raw path, the Router component handles the concatenation of base props. A custom hook simply provides the path relative to the environment, and the library ensures that <Link href="/path"> correctly resolves if a base is provided.
Sources: test/link.test.ts:135-144
Summary
Creating custom location hooks in wouter-vue allows for high flexibility, enabling routing in environments where a standard browser URL is unavailable or undesired. By returning a simple [Ref<string>, Function] tuple, developers can plug any state management or persistence layer into the routing system.