Dynamic Routes & Navigation
Linking between pages with NuxtLink and navigateTo, and reading route params and query strings.
2 menit membaca
Nuxt uses Vue Router under the hood, so most of what you already know about routes, params, and navigation guards still applies. What Nuxt adds are a couple of components and composables tuned for its SSR and file-based routing model.
Linking with NuxtLink
NuxtLink is Nuxt's auto-imported equivalent of Vue Router's <router-link> — use it instead of a plain <a> for internal navigation:
<template>
<nav>
<NuxtLink to="/">Home</NuxtLink>
<NuxtLink :to="`/blog/${post.slug}`">{{ post.title }}</NuxtLink>
</nav>
</template>A plain <a href="/blog/first-post"> would work too, but it forces a full page reload — the browser throws away the current JavaScript state and re-requests everything from the server. NuxtLink intercepts the click and does a client-side navigation instead, swapping only the page content while keeping the app running. It also automatically applies an active-link class when the link matches the current route, useful for styling nav items.
Reading params and query strings
useRoute() gives you the current route wherever you need it — not just in the page component itself, but in any component or composable rendered as part of that page:
<script setup>
const route = useRoute();
// /products/42?ref=email
const productId = route.params.id; // "42"
const ref = route.query.ref; // "email"
</script>Programmatic navigation
Sometimes navigation needs to happen from code rather than a click — after a form submits, or once a check passes. navigateTo is Nuxt's SSR-safe way to do that:
<script setup>
async function handleLogin() {
const success = await submitLogin();
if (success) {
await navigateTo("/dashboard");
}
}
</script>Use navigateTo instead of directly mutating window.location or reaching for router.push out of habit. navigateTo works identically whether the code runs on the server (during SSR, where it issues a proper redirect response) or in the browser (where it behaves like router.push) — window.location only makes sense client-side, and would silently do nothing useful during server rendering.
A quick contrast with plain Vue Router
If you've used vue-router directly, useRoute() and useRouter() will feel familiar — they're the same composables, re-exported by Nuxt. The difference is what's built on top: NuxtLink and navigateTo account for Nuxt's SSR and prefetching behavior, so reaching for them instead of the lower-level Vue Router APIs keeps navigation correct across both server and client rendering.