Routes and Rendering in Vue & Nuxt SEO

How URL structure and rendering modes affect search engine crawling, indexing, and ranking in Vue and Nuxt applications.

Introduction

Search engines read your URLs before they render your content. The URL /products/shoes ranks better than /products?category=shoes because it's clearer. The URL /about/ and /about are treated as different pages unless you tell crawlers otherwise.

Your choice of rendering mode (SSR, SSG, SPA) determines whether search engines see your content immediately or have to wait for JavaScript to execute. Most crawlers can handle JavaScript, but not all do it well.

Rendering Modes

Nuxt supports three rendering modes. Each has different implications for how search engines access your content.

Server-Side Rendering (SSR)

The server generates HTML on every request. Crawlers receive full HTML immediately.

nuxt.config.ts
export default defineNuxtConfig({
  ssr: true // default
})

When to use SSR:

  • Content changes frequently (news sites, social feeds)
  • Pages need personalization
  • Real-time data display

SEO impact: Best for most sites. Crawlers get full content immediately. Server load increases with traffic.

Static Site Generation (SSG)

HTML is pre-rendered at build time. All pages exist as static files.

nuxt.config.ts
export default defineNuxtConfig({
  ssr: true,
  nitro: {
    static: true
  }
})

When to use SSG:

  • Content changes infrequently (blogs, documentation)
  • Known set of pages at build time
  • Maximum performance needed

SEO impact: Excellent. Fast response times. Crawlers get instant HTML. Requires rebuild for content updates.

Single Page Application (SPA)

Browser renders everything. Server sends minimal HTML shell.

nuxt.config.ts
export default defineNuxtConfig({
  ssr: false
})

When to use SPA:

  • Behind authentication
  • Admin panels, dashboards
  • Apps that don't need SEO

SEO impact: Poor. Search engines must execute JavaScript. Google handles this, but other crawlers struggle. Avoid for public content.

Mode Comparison

ModeCrawler Sees HTMLInitial LoadServer LoadBest For
SSRImmediatelyFastHighDynamic content, frequently updated
SSGImmediatelyFastestNoneStatic content, blogs, docs
SPAAfter JavaScriptSlowLowAuthenticated apps, admin panels

URL Structure Matters

Trailing Slashes

Search engines treat /about and /about/ as different pages. Pick one format and stick to it.

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // Redirect /about to /about/
    '/about': { redirect: { to: '/about/', statusCode: 301 } }
  }
})

Read the trailing slashes guide for implementation details.

Clean URLs

Query parameters make URLs harder to crawl and rank.

Bad:

/products?category=shoes&color=red&sort=price

Good:

/products/shoes/red?sort=price

Put important information in the path. Use query parameters for filters and sorting only.

Dynamic Routes

Nuxt's file-based routing creates SEO-friendly URLs automatically.

pages/
  products/
    [category]/
      [id].vue

This generates /products/shoes/123 instead of /products?category=shoes&id=123.

Read the routes guide for advanced patterns.

Hybrid Rendering

Mix rendering modes per route. Use SSR for public pages, SPA for authenticated sections.

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true }, // SSG
    '/products/**': { ssr: true }, // SSR
    '/admin/**': { ssr: false } // SPA
  }
})

Read the rendering modes guide for complete examples.

Quick Implementation

Force trailing slashes:

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/**': {
      redirect: {
        to: (path) => path.endsWith('/') ? undefined : path + '/',
        statusCode: 301
      }
    }
  }
})

Prerender specific pages:

nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ['/about', '/contact', '/products']
    }
  }
})

Dynamic route with SSG:

pages/blog/[slug].vue
<script setup>
const route = useRoute()
const { data } = await useFetch(`/api/posts/${route.params.slug}`)

// Tell Nuxt which slugs exist at build time
definePageMeta({
  // This can be done via server/api or build hook
})
</script>

Why URL Structure Matters

URLs appear in search results. Users see them before clicking. /learn/seo-basics tells users what the page contains. /page?id=1523 doesn't.

Search engines use URLs to understand site hierarchy. /products/shoes/running shows clear categorization. /item/12345 doesn't.

Broken URL changes lose search rankings. Use 301 redirects when restructuring. Never break external links.

Crawl Budget

Google allocates limited time to crawl your site. Poor URL structure wastes this budget.

Problems that burn crawl budget:

  • Duplicate content from inconsistent trailing slashes
  • Pagination without canonical tags
  • Infinite URL variations from filters
  • Redirect chains (/a/b/c)

Performance Impact

Rendering mode affects Time to First Byte (TTFB), a ranking factor.

  • SSG: ~10ms TTFB
  • SSR: ~100-300ms TTFB
  • SPA: Fast TTFB but slow First Contentful Paint

Search engines wait for content to appear. SSG and SSR show content immediately. SPA requires JavaScript execution first.

Continue reading about trailing slashes ->