Nuxt Routing and SEO
- Use stable, descriptive URLs. Both path segments and query parameters can identify indexable content
- Rendering mode determines whether crawlers see your content immediately (SSR/SSG) or need to execute JavaScript first (SPA)
- Nuxt route rules let you mix SSR, SSG, ISR, and SWR per path instead of picking one mode for the whole app
- Inconsistent trailing slashes and unbounded query parameters create duplicate content that wastes crawl budget
Choose stable paths or query URLs that identify the page, and match rendering mode to what each route needs: static pages as SSG, dynamic pages as SSR, admin-only pages as SPA. Nuxt route rules let you mix all three per path instead of picking one mode for the whole app.
Section Overview
| Topic | What You'll Learn |
|---|---|
| URL Structure | Slugs, hyphens, and keyword placement |
| Pagination | Self-referencing canonicals and paginated content indexing |
| Trailing Slashes | Consistent URL formats and redirect configuration |
| Query Parameters | Filters, tracking params, and canonical handling |
| Hreflang & i18n | Multilingual sites, x-default, and return links |
| 404 Pages | Soft 404s, proper status codes, and crawl budget |
| Dynamic Routes | Route params and Nuxt 4 SSR patterns |
| Internal Linking | Hub and spoke architecture, link equity flow, orphan pages |
| Programmatic SEO | Feature pages, comparison pages, alternatives at scale |
| Rendering Modes | SSR, SSG, ISR, and Nuxt Islands compared |
Rendering Strategy
Interaction to Next Paint (INP) is one of Google's Core Web Vitals: a page experience signal used by its ranking systems, alongside other signals. Match your rendering strategy to what each route needs:
| Strategy | Benefit | Best For |
|---|---|---|
| Nuxt Islands | Minimal client JS | Static components (header, footer) |
| Edge Rendering | Can reduce network distance; measure response time | Global audiences |
| SWR / ISR | Static speed with freshness | Product catalogs, news feeds |
| Partial Hydration | Can reduce client work; measure INP | Content-heavy pages with widgets |
Nuxt uses SSR by default. Mix strategies per route with route rules:
export default defineNuxtConfig({
routeRules: {
'/blog/**': { isr: true }, // Requires a supported deployment preset
'/products/**': { swr: 3600 }, // Stale-While-Revalidate
'/dashboard/**': { ssr: false }, // Client-only (SPA)
'/api/**': { cors: true }
}
})URL Structure Quick Reference
Both formats can identify indexable content:
✅ /products/electronics/laptop
✅ /products?category=electronics&item=laptopHyphens over underscores:
✅ /nuxt-routing-guide
❌ /nuxt_routing_guideLowercase, short URLs:
✅ /blog/nuxt-seo
❌ /Blog/The-Complete-Guide-To-Nuxt-SEO-Optimization-2025Read 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 |
| Pagination without canonicals | Self-referencing canonicals |
| Infinite filter combinations | Noindex or block in robots.txt |
| Soft 404s returning 200 | Proper status codes |
| Orphan pages with no links | Build internal linking structure |
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. Smaller sites should keep sitemaps current and monitor index coverage in Google Search Console.
File-Based Routing
Nuxt creates routes automatically from the /pages directory:
pages/
blog/
[slug].vue → /blog/:slug
products/
[category]/
[id].vue → /products/:category/:idGenerates /blog/nuxt-seo-guide and /products/electronics/123.
This initial-load example requires your /api/posts/:slug endpoint returning title and excerpt, or404 for an absent post. Add route-change handling if the same component remains mounted:
<script setup lang="ts">
const route = useRoute()
const { data: post, error } = await useFetch<{ title: string, excerpt: string }>(`/api/posts/${encodeURIComponent(String(route.params.slug))}`)
if (error.value)
throw error.value
if (!post.value)
throw createError({ statusCode: 404, statusMessage: 'Post not found' })
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' }
]
})Configure language metadata and baseUrl, then apply useLocaleHead(). Installing the module alone does not add the complete head tags:
Follow the module's current SEO setup for language tags, canonical URLs, and alternate links.
Read Hreflang & i18n for configuration, bidirectional links, and common mistakes.
Pre-launch setup, post-launch verification, and ongoing monitoring. Interactive checklist with links to every guide.