Vue Routing and SEO
- Paths and query parameters can identify public content. Choose stable, readable URLs that retain meaningful values
- SSR or generation can provide content in initial HTML. Client-generated content depends on JavaScript rendering
- If slash variants serve the same page, align links and canonicals with a chosen URL policy and verify HTTP redirects
Readable URLs help users recognize a page. Both /products/shoes and /products?category=shoes can identify content; neither pattern proves a ranking advantage. If slash variants serve duplicate or near-identical pages, use a deliberate canonical and redirect policy.
Rendering determines which content appears in the response and which depends on client JavaScript. Google can render JavaScript; check successful output rather than assuming a client-rendered page cannot be indexed.
Section Overview
| Topic | What You'll Learn |
|---|---|
| URL Structure | Slugs, hyphens vs underscores, URL length, keyword placement |
| Pagination | Self-referencing canonicals, infinite scroll vs pagination, crawlable links |
| Trailing Slashes | Consistent URL formats, redirect configuration |
| Query Parameters | Filters, tracking params, canonical handling |
| Hreflang & i18n | Multilingual sites, x-default, return links |
| 404 Pages | Soft 404s, proper status codes, crawl budget |
| Dynamic Routes | Route params, per-route meta tags, SSR patterns |
| Internal Linking | Hub and spoke architecture, link equity flow, orphan pages |
| Programmatic SEO | Feature pages, comparison pages, alternatives at scale |
| Rendering Modes | SSR, SSG, SPA, and edge rendering compared |
Rendering Mode Quick Reference
| Mode | Crawler Sees HTML | Best For |
|---|---|---|
| Hybrid | Depends on the chosen route policy | Framework-specific rendering and caching |
| SSR | Generated on the server, possibly cached | Request-specific or frequently changing output |
| SSG | Generated at build time | Public content with a suitable rebuild schedule |
| SPA | Static shell, then client-generated views | Views that can depend on browser JavaScript |
Google's JavaScript pipeline can render client pages. SSR or prerendering reduces dependence on that execution for content in the response. Neither guarantees indexing, timing, or a ranking result.
URL Structure Quick Reference
Choose a readable content identity:
✅ /products/electronics/laptop
✅ /products?category=electronics&item=laptopHyphens over underscores:
✅ /vue-router-guide
❌ /vue_router_guideLowercase, short URLs:
✅ /blog/vue-seo
❌ /Blog/The-Complete-Guide-To-Vue-SEO-Optimization-2025Read URL Structure for implementation details.
Crawl Budget
Google allocates limited time to crawl your site. Many duplicate or unneeded URL variants can use additional resources. A canonical or noindex directive does not itself prevent crawling.
Crawl, discovery, and canonical checks:
| Problem | Solution |
|---|---|
| Inconsistent trailing slashes | Configure redirects |
| Paginated pages need distinct URL identities | Review page canonicals and discovery links |
| Unneeded filter combinations | Choose a crawl or indexing policy deliberately |
| Soft 404s returning 200 | Proper status codes |
| Orphan pages with no links | Build internal linking structure |
Google's crawl-budget guide focuses on large or rapidly changing sites, and sites with many discovered but unindexed URLs. Its page counts are rough examples, not thresholds. Keep sitemaps current and monitor the Page indexing report in Google Search Console.
Dynamic Routes in Vue Router
These route excerpts assume app-owned BlogPost and Product components in an installed router:
const routes = [
{ path: '/blog/:slug', component: BlogPost },
{ path: '/products/:category/:id', component: Product }
]The patterns match /blog/vue-seo-guide and /products/electronics/123.
Provide metadata that describes the current page. Before using this component excerpt, install Unhead and supply the current post as a prop from your data layer:
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
const props = defineProps<{ post: { title: string, excerpt: string } }>()
useSeoMeta({
title: () => props.post.title,
description: () => props.post.excerpt
})
</script>
<template>
<article>
<h1>{{ props.post.title }}</h1>
<p>{{ props.post.excerpt }}</p>
</article>
</template>The loader and initial-state transfer belong to your app. Supply the current post when the page changes.
Read Dynamic Routes for SSR patterns, optional params, and common SEO issues.
Multilingual Sites
Hreflang signals language and regional alternatives; it does not guarantee which result appears. This Unhead component-setup excerpt is for corresponding English and French landing pages. Emit the same reciprocal set on both pages, including the current page:
import { useHead } from '@unhead/vue'
useHead({
link: [
{ rel: 'alternate', hreflang: 'en', href: 'https://example.com/en' },
{ rel: 'alternate', hreflang: 'fr', href: 'https://example.com/fr' },
{ rel: 'alternate', hreflang: 'x-default', href: 'https://example.com/en' }
]
})Read Hreflang & i18n for vue-i18n integration, bidirectional links, and common mistakes.
Nuxt supplies file-based routing and enables SSR by default. Canonical, sitemap, OG image, and structured-data behavior depends on the installed modules and configuration. Learn more in Nuxt →
Pre-launch setup, post-launch verification, and ongoing monitoring. Interactive checklist with links to every guide.