Skip to content

NuxtLink and Navigation — Client-Side Navigation in Nuxt 3

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about NuxtLink and Navigation. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn NuxtLink component for client-side navigation, prefetching, active link styling, and programmatic routing in Nuxt 3.

In this lesson, you'll understand how <NuxtLink> enables client-side navigation, how prefetching works, and how to style active links.

What You'll Learn

How to use <NuxtLink> for navigation, how Nuxt prefetches pages, how to style active links, and how to navigate programmatically.

Why It Matters

Client-side navigation provides instant page transitions without full reloads. Nuxt's prefetching anticipates user navigation for even faster experiences.

flowchart LR
    A[User Hovers Link] --> B[Prefetch Triggered]
    B --> C[Page Component + Data Loaded]
    C --> D[User Clicks Link]
    D --> E[Instant Render]
    style B fill:#00dc82,color:#fff
<template>
  <nav>
    <NuxtLink to="/">Home</NuxtLink>
    <NuxtLink to="/about">About</NuxtLink>
    <NuxtLink to="/blog">Blog</NuxtLink>
    <NuxtLink to="https://external.com">External</NuxtLink>
  </nav>
</template>

Output: Internal links use client-side navigation. External links automatically render as <a> tags with target="_blank" and rel="noopener".

Style the currently active link:

<template>
  <nav>
    <NuxtLink to="/" :class="{ active: isActive }">Home</NuxtLink>
    <NuxtLink to="/about" exact-active-class="exact-active">About</NuxtLink>
    <NuxtLink to="/blog" active-class="nav-active">Blog</NuxtLink>
  </nav>
</template>

<style>
.nav-active { font-weight: bold; color: #00dc82; }
.exact-active { border-bottom: 2px solid #00dc82; }
</style>

Output: The blog link has nav-active class when any /blog/* page is active. The about link has exact-active only when exactly on /about.

Prefetching Behavior

Nuxt prefetches linked pages intelligently:

<template>
  <div>
    <!-- Prefetched when visible in viewport -->
    <NuxtLink to="/about">About</NuxtLink>

    <!-- Prefetched on hover -->
    <NuxtLink to="/contact" prefetch-on="hover">Contact</NuxtLink>

    <!-- Never prefetched -->
    <NuxtLink to="/admin" no-prefetch>Admin</NuxtLink>
  </div>
</template>

Output: Most links are prefetched when they enter the viewport. You can control prefetching behavior with prefetch-on and no-prefetch.

Programmatic Navigation

Navigate imperatively with useRouter:

<script setup>
const router = useRouter();

const navigate = {
  toHome: () => router.push('/'),
  toPost: (slug) => router.push(`/blog/${slug}`),
  goBack: () => router.back(),
  replace: (path) => router.replace(path),
  withQuery: () => router.push({ path: '/search', query: { q: 'nuxt' } })
};
</script>

<template>
  <div>
    <button @click="navigate.toHome">Home</button>
    <button @click="navigate.goBack">Back</button>
  </div>
</template>

Protect routes with middleware:

// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const user = useSupabaseUser();
  
  if (!user.value && to.path !== '/auth/login') {
    return navigateTo('/auth/login');
  }
});

Common Mistakes

  1. Using <a> instead of <NuxtLink>: Regular <a> tags cause full page reloads, losing application state.
  2. Forgetting exact-active-class for root links: The home link / matches all routes. Use exact-active-class for root navigation.
  3. Not using no-prefetch for auth-required links: Pages behind authentication shouldn't prefetch. Use no-prefetch.
  4. Using router.push without useRouter(): The router must be accessed via const router = useRouter().
  5. Navigating before data is ready: Wait for async operations to complete before navigating away.

Practice Questions

  1. What is the difference between active-class and exact-active-class? Answer: active-class applies when the route starts with the link's to path. exact-active-class applies only when routes match exactly.

  2. How does Nuxt decide which pages to prefetch? Answer: By default, links are prefetched when they enter the viewport (IntersectionObserver). prefetch-on="hover" changes this to hover-based prefetching.

  3. How do you prevent a link from being prefetched? Answer: Add the no-prefetch prop to <NuxtLink>.

  4. What function navigates programmatically? Answer: router.push(path) from useRouter(). Use router.replace() to navigate without adding history.

Challenge

Build a documentation sidebar with active link tracking. Each section header should highlight when any page in that section is active. Use active-class for section-level highlighting and exact-active-class for individual pages.

Mini Project

Create a multi-section documentation site with: sidebar navigation using <NuxtLink> with active classes, breadcrumb trail, prev/next page navigation at the bottom, and prefetching for the next page.

FAQ

Does NuxtLink work with external URLs?

: Yes. External URLs are automatically detected and rendered as regular <a> tags with security attributes.

Can I add custom attributes to NuxtLink?

: Yes. All extra attributes (like class, target, rel) are passed through to the underlying <a> tag.

How do I scroll to top on navigation?

: Nuxt scrolls to top by default. Configure scrollBehavior in app/router.options.ts for custom behavior.

Does NuxtLink support named routes?

: Yes. Use the to prop with a route object: { name: 'blog-slug', params: { slug: 'hello' } }.

What's Next

Learn about Nuxt Auto-imports for a deep dive into Nuxt 3's auto-import system for composables, components, and utilities.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro