Index of every page on this site: llms.txt

Vue Routing and SEO

Design stable Vue Router URLs, choose rendering for your content, and verify discovery links, canonical tags, and direct requests.
Harlan Wilton6 mins read Published Updated
What you'll learn
  • 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

TopicWhat You'll Learn
URL StructureSlugs, hyphens vs underscores, URL length, keyword placement
PaginationSelf-referencing canonicals, infinite scroll vs pagination, crawlable links
Trailing SlashesConsistent URL formats, redirect configuration
Query ParametersFilters, tracking params, canonical handling
Hreflang & i18nMultilingual sites, x-default, return links
404 PagesSoft 404s, proper status codes, crawl budget
Dynamic RoutesRoute params, per-route meta tags, SSR patterns
Internal LinkingHub and spoke architecture, link equity flow, orphan pages
Programmatic SEOFeature pages, comparison pages, alternatives at scale
Rendering ModesSSR, SSG, SPA, and edge rendering compared

Rendering Mode Quick Reference

ModeCrawler Sees HTMLBest For
HybridDepends on the chosen route policyFramework-specific rendering and caching
SSRGenerated on the server, possibly cachedRequest-specific or frequently changing output
SSGGenerated at build timePublic content with a suitable rebuild schedule
SPAStatic shell, then client-generated viewsViews 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=laptop

Hyphens over underscores:

✅ /vue-router-guide
❌ /vue_router_guide

Lowercase, short URLs:

✅ /blog/vue-seo
❌ /Blog/The-Complete-Guide-To-Vue-SEO-Optimization-2025

Read 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:

ProblemSolution
Inconsistent trailing slashesConfigure redirects
Paginated pages need distinct URL identitiesReview page canonicals and discovery links
Unneeded filter combinationsChoose a crawl or indexing policy deliberately
Soft 404s returning 200Proper status codes
Orphan pages with no linksBuild 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 →

Was this page helpful?