When to Use the Vue Router Link Component Instead of Anchor Tags in Vue.js
Use <router-link> for all internal navigation within your Vue.js single-page application to enable client-side routing, preserve application state, and trigger navigation guards, while reserving standard <a> tags strictly for external links or resource downloads.
In the vuejs/core repository, the framework is architected to support seamless SPA navigation through tight integration with Vue Router. The vue router link component provides router-aware capabilities that standard anchor tags cannot replicate, making it the idiomatic choice for internal route transitions.
History API Navigation Without Page Reloads
The <router-link> component calls router.push() (or replace) under the hood, updating the browser URL using the History API without triggering a full page refresh. According to the Vue Router source code, this preserves your application's JavaScript state and provides instantaneous view transitions. A standard <a href> tag, by contrast, initiates a standard HTTP request that reloads the entire page, destroying your current component state and re-running all initialization logic.
Navigation Guards and Route Protection
When you use the vue router link component, navigation guards execute automatically before the route change completes. This includes global guards like beforeEach and beforeResolve, as well as in-component hooks like beforeRouteEnter, beforeRouteUpdate, and beforeRouteLeave. These guards are essential for authentication checks, data prefetching, and preventing users from losing unsaved form data. Standard anchor tags bypass these guards entirely, allowing navigation to occur regardless of your route protection logic.
Automatic Active Link Styling
<router-link> automatically applies CSS classes to indicate active navigation state. The component adds router-link-active when the current route matches the link's target, and router-link-exact-active for exact matches. This eliminates the need for custom JavaScript to track the current URL and manually toggle classes. As implemented in vuejs/router/src/components/RouterLink.vue, this behavior respects the router's matching logic, including parameters and nested routes.
Named Routes and Parameter Resolution
The component accepts a :to prop that can resolve named routes and parameters dynamically:
<router-link :to="{ name: 'user', params: { id: 42 } }">
User Profile
</router-link>
This allows Vue Router to generate the final URL string based on your route definitions, preventing broken links if paths change later. Standard anchor tags require hardcoded strings that can drift out of sync with your route configuration.
SSR and Hydration Compatibility
During server-side rendering, <router-link> renders as a valid <a> tag with the correct href attribute, ensuring SEO-friendly markup while preserving SPA navigation behavior once the page hydrates on the client. The Vue Core test suite in packages/compiler-sfc/__tests__/compileTemplate.spec.ts (lines 411-416) specifically verifies SSR handling of router-link components, confirming they render correctly when containing child elements like images.
Vue Core Integration Points
The vue router link component relies on deep integration with Vue's runtime core. In packages/runtime-core/src/componentPublicInstance.ts, the framework injects the $router instance into every component, allowing <router-link> to access routing methods regardless of where it appears in the component tree. Additionally, packages/runtime-core/src/component.ts imports RouterView, demonstrating the core's expectation of a router-aware rendering outlet that works in tandem with router-link navigation.
Practical Implementation Examples
Internal Navigation with router-link
Use <router-link> for all application-internal navigation to leverage SPA optimizations:
<template>
<!-- Basic route navigation -->
<router-link to="/about">About Us</router-link>
<!-- Named route with parameters -->
<router-link :to="{ name: 'user', params: { id: 42 } }">
View User
</router-link>
<!-- Custom active classes -->
<nav>
<router-link to="/" exact-active-class="active-home">Home</router-link>
<router-link to="/about" active-class="active-page">About</router-link>
</nav>
</template>
External Links with Standard Anchors
Reserve standard <a> tags for external resources where you want default browser behavior:
<a href="https://developer.mozilla.org" target="_blank" rel="noopener">
MDN Documentation
</a>
Programmatic Navigation Patterns
When combining user interaction with navigation, <router-link> maintains proper routing context:
<router-link :to="{ name: 'search' }" @click.prevent="logInteraction">
Search
</router-link>
<script setup>
import { useRouter } from 'vue-router'
function logInteraction() {
console.log('Search navigation initiated')
// Navigation continues via router-link; no manual router.push() needed
}
</script>
When to Use Standard Anchor Tags Instead
Despite the advantages of <router-link>, standard anchor tags remain appropriate for specific scenarios:
- External navigation: Linking to different domains or websites where you want a full page load
- File downloads: Triggering browser download dialogs for PDFs, images, or documents
- Static HTML sites: Projects without Vue Router installed where SPA behavior isn't required
- Email and telephone links:
mailto:andtel:protocols that don't require routing
Summary
<router-link>is the vue router link component designed specifically for internal SPA navigation, providing History API updates, navigation guards, and automatic active-state styling- The component integrates deeply with Vue Core through
$routerinjection incomponentPublicInstance.tsand coordination withRouterView - Standard
<a>tags trigger full page reloads and should only be used for external links, downloads, or non-SPA contexts - For SSR applications,
<router-link>ensures correct hydration while maintaining SEO-friendly markup as verified in the Vue Core test suite
Frequently Asked Questions
Does <router-link> work with server-side rendering?
Yes, <router-link> renders as a standard <a> tag with the correct href attribute during SSR, ensuring search engines can crawl your links. During client hydration, Vue attaches the SPA navigation behavior. The Vue Core repository includes specific tests in packages/compiler-sfc/__tests__/compileTemplate.spec.ts to verify this SSR compatibility.
Can I use <router-link> for external URLs?
No, <router-link> is designed exclusively for internal routes managed by Vue Router. For external websites, use a standard <a> tag. Attempting to use <router-link> with external URLs will cause routing errors or unexpected behavior since the router cannot resolve those paths.
How do I style active links with <router-link>?
The component automatically applies router-link-active and router-link-exact-active classes based on the current route. You can customize these class names using the active-class and exact-active-class props, or configure global defaults in your router configuration. This allows for straightforward CSS styling of navigation states without manual JavaScript tracking.
What happens if I use a standard anchor tag for internal navigation?
Using <a> for internal routes triggers a full browser page refresh, reloading your JavaScript bundle and reinitializing your Vue application. This destroys any client-side state, bypasses navigation guards (including authentication checks), and eliminates the performance benefits of SPA architecture. Always use <router-link> for internal navigation to maintain application continuity.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →