---
title: "Vue Routing and SEO"
description: "Structure Vue Router routes and choose SSR, SSG, or SPA rendering so search engines can crawl, index, and rank every page."
canonical_url: "https://nuxtseo.com/learn-seo/vue/routes-and-rendering"
last_updated: "2026-07-16"
---

::key-takeaways
- Use path segments over query parameters: `/products/shoes` beats `/products?item=shoes`
- SSR/SSG delivers HTML immediately; SPA requires JavaScript execution first
- Inconsistent trailing slashes create duplicate content; pick one and redirect the other
::

Search engines read URLs before content. `/products/shoes` ranks better than `/products?category=shoes`. `/about` and `/about/` are different pages unless you configure otherwise.

Rendering mode determines whether crawlers see your content immediately (SSR/SSG) or must execute JavaScript first (SPA). Google can render JavaScript, but it's slower and less reliable than serving HTML directly.

## Section Overview

| Topic                                                                    | What You'll Learn                                                           |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| [URL Structure](/learn-seo/vue/routes-and-rendering/url-structure)       | Slugs, hyphens vs underscores, URL length, keyword placement                |
| [Pagination](/learn-seo/vue/routes-and-rendering/pagination)             | Self-referencing canonicals, infinite scroll vs pagination, crawlable links |
| [Trailing Slashes](/learn-seo/vue/routes-and-rendering/trailing-slashes) | Consistent URL formats, redirect configuration                              |
| [Query Parameters](/learn-seo/vue/routes-and-rendering/query-parameters) | Filters, tracking params, canonical handling                                |
| [Hreflang & i18n](/learn-seo/vue/routes-and-rendering/i18n)              | Multilingual sites, x-default, return links                                 |
| [404 Pages](/learn-seo/vue/routes-and-rendering/404-pages)               | Soft 404s, proper status codes, crawl budget                                |
| [Dynamic Routes](/learn-seo/vue/routes-and-rendering/dynamic-routes)     | Route params, per-route meta tags, SSR patterns                             |
| [Internal Linking](/learn-seo/vue/routes-and-rendering/internal-linking) | Hub and spoke architecture, link equity flow, orphan pages                  |
| [Programmatic SEO](/learn-seo/vue/routes-and-rendering/programmatic-seo) | Feature pages, comparison pages, alternatives at scale                      |
| [Rendering Modes](/learn-seo/vue/routes-and-rendering/rendering)         | SSR, SSG, SPA, and edge rendering compared                                  |

## Rendering Mode Quick Reference

| Mode   | Crawler Sees HTML   | Best For                            |
| ------ | ------------------- | ----------------------------------- |
| Hybrid | Immediately (mixed) | Optimize per route with route rules |
| SSR    | Immediately         | Dynamic content, personalization    |
| SSG    | Immediately         | Blogs, docs, marketing pages        |
| SPA    | After JavaScript    | Admin panels, authenticated apps    |

SPAs still require [prerendering](/learn-seo/vue/spa/prerendering) or SSR for SEO. Google processes pages in [three phases: crawling, rendering, and indexing](https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics); a client-rendered page waits in a render queue until Googlebot can execute its JavaScript, which delays content discovery.

## URL Structure Quick Reference

**Path segments over query parameters:**

```
✅ /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](/learn-seo/vue/routes-and-rendering/url-structure) for implementation details.

## Crawl Budget

Google allocates limited time to crawl your site. Poor URL structure wastes budget on duplicate or low-value pages.

**Common crawl budget problems:**

| Problem                       | Solution                                                                                 |
| ----------------------------- | ---------------------------------------------------------------------------------------- |
| Inconsistent trailing slashes | [Configure redirects](/learn-seo/vue/routes-and-rendering/trailing-slashes)              |
| Pagination without canonicals | [Self-referencing canonicals](/learn-seo/vue/routes-and-rendering/pagination)            |
| Infinite filter combinations  | [Noindex or block in robots.txt](/learn-seo/vue/routes-and-rendering/query-parameters)   |
| Soft 404s returning 200       | [Proper status codes](/learn-seo/vue/routes-and-rendering/404-pages)                     |
| Orphan pages with no links    | [Build internal linking structure](/learn-seo/vue/routes-and-rendering/internal-linking) |

Google's own guidance treats crawl budget as a concern mainly for sites with 10,000+ pages that update daily, or a million-plus pages that update weekly: see [managing crawl budget for large sites](https://developers.google.com/search/docs/crawling-indexing/large-site-managing-crawl-budget). Smaller sites should keep sitemaps current and monitor index coverage in [Google Search Console](https://search.google.com/search-console).

## Dynamic Routes in Vue Router

Vue Router's dynamic segments create clean URLs:

```ts
const routes = [
  { path: '/blog/:slug', component: BlogPost },
  { path: '/products/:category/:id', component: Product }
]
```

Generates `/blog/vue-seo-guide` and `/products/electronics/123`.

Each dynamic route needs unique meta tags. Set them with [Unhead](https://unhead.unjs.io/):

```vue
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
import { useRoute } from 'vue-router'

const route = useRoute()
const post = await fetchPost(route.params.slug)

useSeoMeta({
  title: post.title,
  description: post.excerpt
})
</script>
```

Read [Dynamic Routes](/learn-seo/vue/routes-and-rendering/dynamic-routes) for SSR patterns, optional params, and common SEO issues.

## Multilingual Sites

Use hreflang tags to tell search engines which language version to show users:

```ts
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](/learn-seo/vue/routes-and-rendering/i18n) for vue-i18n integration, bidirectional links, and common mistakes.

Using Nuxt? It handles most of this automatically: file-based routing, SSR by default, automatic canonical URLs, sitemaps, OG images, and structured data. [Learn more in Nuxt →](/learn-seo/nuxt/routes-and-rendering)