---
title: "Vue Routing and SEO"
description: "URL structure and rendering mode determine whether search engines can crawl, index, and rank your Vue application."
canonical_url: "https://nuxtseo.com/learn-seo/vue/routes-and-rendering"
last_updated: "2026-01-29"
---

<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

</key-takeaways>

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

<table>
<thead>
  <tr>
    <th>
      Topic
    </th>
    
    <th>
      What You'll Learn
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/url-structure">
        URL Structure
      </a>
    </td>
    
    <td>
      Slugs, hyphens vs underscores, URL length, keyword placement
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/pagination">
        Pagination
      </a>
    </td>
    
    <td>
      Self-referencing canonicals, infinite scroll vs pagination, crawlable links
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/trailing-slashes">
        Trailing Slashes
      </a>
    </td>
    
    <td>
      Consistent URL formats, redirect configuration
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/query-parameters">
        Query Parameters
      </a>
    </td>
    
    <td>
      Filters, tracking params, canonical handling
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/i18n">
        Hreflang & i18n
      </a>
    </td>
    
    <td>
      Multilingual sites, x-default, return links
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/404-pages">
        404 Pages
      </a>
    </td>
    
    <td>
      Soft 404s, proper status codes, crawl budget
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/dynamic-routes">
        Dynamic Routes
      </a>
    </td>
    
    <td>
      Route params, per-route meta tags, SSR patterns
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/rendering">
        Rendering Modes
      </a>
    </td>
    
    <td>
      Hybrid, SSR, SSG & Edge - mixing strategies per route
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/internal-linking">
        Internal Linking
      </a>
    </td>
    
    <td>
      Hub and spoke architecture, PageRank flow, orphan pages
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/programmatic-seo">
        Programmatic SEO
      </a>
    </td>
    
    <td>
      Feature pages, comparison pages, alternatives at scale
    </td>
  </tr>
</tbody>
</table>

## Rendering Mode Quick Reference

<table>
<thead>
  <tr>
    <th>
      Mode
    </th>
    
    <th>
      Crawler Sees HTML
    </th>
    
    <th>
      Best For
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <strong>
        Hybrid
      </strong>
    </td>
    
    <td>
      Immediately (Mixed)
    </td>
    
    <td>
      <strong>
        The Standard.
      </strong>
      
       Optimization per route
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        SSR
      </strong>
    </td>
    
    <td>
      Immediately
    </td>
    
    <td>
      Dynamic content, personalization
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        SSG
      </strong>
    </td>
    
    <td>
      Immediately
    </td>
    
    <td>
      Blogs, docs, marketing pages
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        SPA
      </strong>
    </td>
    
    <td>
      After JavaScript
    </td>
    
    <td>
      Admin panels, authenticated apps
    </td>
  </tr>
</tbody>
</table>

Modern apps use **Hybrid Rendering** (via Route Rules) to mix these strategies. SPAs still require [prerendering](/learn-seo/vue/spa/prerendering) or SSR for SEO. Google's JavaScript rendering has a [second wave of indexing](https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics) that delays content discovery.

## URL Structure Quick Reference

**Path segments over query parameters:**

```text
✅ /products/electronics/laptop
❌ /products?category=electronics&item=laptop
```

**Hyphens over underscores:**

```text
✅ /vue-router-guide
❌ /vue_router_guide
```

**Lowercase, short URLs:**

```text
✅ /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:**

<table>
<thead>
  <tr>
    <th>
      Problem
    </th>
    
    <th>
      Solution
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Inconsistent trailing slashes
    </td>
    
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/trailing-slashes">
        Configure redirects
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Pagination without canonicals
    </td>
    
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/pagination">
        Self-referencing canonicals
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Infinite filter combinations
    </td>
    
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/query-parameters">
        Noindex or block in robots.txt
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Soft 404s returning 200
    </td>
    
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/404-pages">
        Proper status codes
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      Orphan pages with no links
    </td>
    
    <td>
      <a href="/learn-seo/vue/routes-and-rendering/internal-linking">
        Build internal linking structure
      </a>
    </td>
  </tr>
</tbody>
</table>

Sites under 10,000 pages rarely need to worry about crawl budget. Large sites should monitor [Google Search Console](https://search.google.com/search-console) crawl stats.

## 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">
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
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?

Nuxt 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)
