URL Structure for SEO in Nuxt

How URL paths affect search rankings and what to optimize (and what to ignore) in your Nuxt routes.
Harlan WiltonHarlan Wilton Published Updated

URLs are a minor ranking factor. Spend 5 minutes on them, not 5 hours. Google reads them, users see them in search results, but obsessing over perfect URLs won't move the needle.

Readable URLs Win

Compare these two URLs:

✅ /blog/nuxt-ssr-guide
❌ /blog/p?id=847&cat=2&ref=internal

The first tells both humans and bots what the page is about. The second is gibberish. Make URLs readable.

Hyphens Not Underscores

Google treats hyphens as word separators. Underscores are ignored.

✅ /performance-optimization
❌ /performance_optimization

Use hyphens in your route paths and component names.

URL Length

Shorter URLs are slightly better for:

  • User sharing (easier to copy/paste)
  • Search result display (don't get truncated)
  • Technical crawling (minimal impact)

But don't sacrifice clarity. /blog/seo-guide beats /seo if it's actually a blog post.

✅ /guides/seo-basics
✅ /blog/improving-core-web-vitals
❌ /g/sb
❌ /blog/a-comprehensive-guide-to-improving-your-core-web-vitals-and-page-speed-metrics

Keywords in URLs

Including keywords helps a tiny bit. Keyword stuffing makes you look spammy.

✅ /nuxt/ssr
❌ /nuxt-server-side-rendering-ssr-prerender-static-site-generation

If your page title is "Nuxt SSR Guide", use /nuxt-ssr-guide. Done. Don't optimize further.

URL Parameters and Query Strings

Query parameters (?page=2&sort=date) create duplicate content issues:

/blog
/blog?page=2
/blog?sort=date
/blog?page=2&sort=date

Google sees four different URLs for the same content. Pick one canonical URL and stick with it.

Nuxt's file-based routing uses clean paths:

pages/
  blog/
    index.vue          → /blog
    [slug].vue         → /blog/my-post
    page/
      [page].vue       → /blog/page/2

This generates /blog/my-post and /blog/page/2 instead of query parameters.

If you must use query parameters (filters, search), add canonical tags or use noindex.

Dynamic Routes in Nuxt

Dynamic routes work fine for SEO. Google crawls them like any other page.

pages/
  blog/
    [slug].vue         → /blog/seo-guide, /blog/web-vitals
  products/
    [category]/
      [id].vue         → /products/electronics/123

Access route params in your page:

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

Don't use dynamic routes for:

  • Session IDs (/page?session=abc123)
  • Tracking parameters (/page?utm_source=twitter)
  • Temporary tokens

These create infinite crawl loops. Use robots.txt or noindex to block them.

File-Based Routing Best Practices

Organize your pages directory semantically:

pages/
  blog/
    index.vue          → /blog
    [slug].vue         → /blog/[slug]
  docs/
    [category]/
      [page].vue       → /docs/[category]/[page]

Nuxt automatically generates routes from your file structure. Keep file names readable and semantic.

URL Changes and Redirects

Changed a URL? Set up a 301 redirect. Google transfers ranking signals to the new URL.

Nuxt handles redirects via routeRules in nuxt.config.ts:

export default defineNuxtConfig({
  routeRules: {
    '/old-blog-post': { redirect: '/blog/new-post' },
    '/legacy/**': { redirect: '/new/**' }
  }
})

Or in your server middleware for dynamic redirects:

// server/middleware/redirects.ts
export default defineEventHandler((event) => {
  const url = getRequestURL(event)

  if (url.pathname === '/old-path') {
    return sendRedirect(event, '/new-path', 301)
  }
})

Don't skip redirects. Broken links lose traffic and rankings.

What NOT to Do

Don't stuff keywords in every URL segment ❌ Don't use uppercase letters (inconsistent, case-sensitive) ❌ Don't add dates unless content is time-sensitive (/2024/01/post) ❌ Don't expose internal IDs (/products/db-id-847392) ❌ Don't create parameter variations of the same page ❌ Don't change URLs without redirects