Use path segments (/products/shoes) instead of query parameters (/products?id=123), keep URLs under 60 characters, and use hyphens between words. Nuxt's SSR renders your content server-side by default, so search engines see it immediately without waiting for JavaScript.
Google can render JavaScript, but the second-wave indexing delays content discovery by days or weeks. SSR avoids this entirely.
| Topic | What You'll Learn |
|---|---|
| URL Structure | Slugs, hyphens vs underscores, URL length, keyword placement |
| Pagination | Self-referencing canonicals, infinite scroll vs pagination, crawlable links |
| Trailing Slashes | Consistent URL formats, redirect configuration |
| Query Parameters | Filters, tracking params, canonical handling |
| Hreflang & i18n | Multilingual sites, x-default, return links |
| 404 Pages | Soft 404s, proper status codes, crawl budget |
| Dynamic Routes | Route params, per-route meta tags, SSR patterns |
| Rendering Modes | SSR vs SSG vs SPA, when to use each |
| Mode | Crawler Sees HTML | Best For |
|---|---|---|
| SSR (default) | Immediately | Dynamic content, personalization |
| SSG | Immediately | Blogs, docs, marketing pages |
| SPA | After JavaScript | Admin 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.
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.
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 |
| Pagination without canonicals | Self-referencing canonicals |
| Infinite filter combinations | Noindex or block in robots.txt |
| Soft 404s returning 200 | Proper status codes |
Sites under 10,000 pages rarely need to worry about crawl budget. Large sites should monitor Google Search Console crawl stats.
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.
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.