Nuxt Routing and SEO

URL structure and rendering mode determine whether search engines can crawl, index, and rank your Nuxt application.
Harlan WiltonHarlan Wilton6 mins read Published Updated

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.

Nuxt renders on the server by default, ensuring crawlers see your content immediately.

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
Rendering ModesSSR vs SSG vs SPA, when to use each

Rendering Mode Quick Reference

ModeCrawler Sees HTMLBest For
SSR (default)ImmediatelyDynamic content, personalization
SSGImmediatelyBlogs, docs, marketing pages
SPAAfter JavaScriptAdmin panels, authenticated apps

Nuxt uses SSR by default. Configure rendering per route with routeRules in nuxt.config.ts:

export default defineNuxtConfig({
  routeRules: {
    '/blog/**': { prerender: true }, // SSG
    '/dashboard/**': { ssr: false }, // SPA
    '/api/**': { ssr: false } // Client-only
  }
})

Google's JavaScript rendering has a second wave of indexing that delays content discovery. SSR avoids this delay.

URL Structure Quick Reference

Path segments over query parameters:

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

Hyphens over underscores:

✅ /nuxt-routing-guide
❌ /nuxt_routing_guide

Lowercase, short URLs:

✅ /blog/nuxt-seo
❌ /Blog/The-Complete-Guide-To-Nuxt-SEO-Optimization-2025

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

ProblemSolution
Inconsistent trailing slashesConfigure redirects
Pagination without canonicalsSelf-referencing canonicals
Infinite filter combinationsNoindex or block in robots.txt
Soft 404s returning 200Proper status codes

Sites under 10,000 pages rarely need to worry about crawl budget. Large sites should monitor Google Search Console crawl stats.

File-Based Routing

Nuxt creates routes automatically from the /pages directory:

pages/
  blog/
    [slug].vue       → /blog/:slug
  products/
    [category]/
      [id].vue       → /products/:category/:id

Generates /blog/nuxt-seo-guide and /products/electronics/123.

Each dynamic route needs unique meta tags:

<script setup lang="ts">
const route = useRoute()
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`)

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

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

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' }
  ]
})

The @nuxtjs/i18n module handles this automatically:

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    locales: ['en', 'fr'],
    defaultLocale: 'en',
    strategy: 'prefix_except_default'
  }
})

Read Hreflang & i18n for configuration, bidirectional links, and common mistakes.