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.
Compare these two URLs:
✅ /blog/vue-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.
Google treats hyphens as word separators. Underscores are ignored.
✅ /performance-optimization
❌ /performance_optimization
Use hyphens in your route paths and component names.
Shorter URLs are slightly better for:
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
Including keywords helps a tiny bit. Keyword stuffing makes you look spammy.
✅ /vue/ssr
❌ /vue-server-side-rendering-ssr-prerender-static-site-generation
If your page title is "Vue SSR Guide", use /vue-ssr-guide. Done. Don't optimize further.
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.
Vue Router dynamic segments use clean paths:
const routes = [
{
path: '/blog/:slug',
component: BlogPost
},
{
path: '/blog/page/:page',
component: BlogList
}
]
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 work fine for SEO. Google crawls them like any other page.
const routes = [
{
path: '/blog/:slug',
component: BlogPost
},
{
path: '/products/:category/:id',
component: Product
}
]
This generates:
/blog/seo-guide, /blog/web-vitals/products/electronics/123Don't use dynamic routes for:
/page?session=abc123)/page?utm_source=twitter)These create infinite crawl loops. Use robots.txt or noindex to block them.
Organize your routes semantically:
✅ Good structure:
const routes = [
{
path: '/blog',
component: BlogList
},
{
path: '/blog/:slug',
component: BlogPost
},
{
path: '/docs/:category/:page',
component: DocPage
}
]
❌ Confusing structure:
const routes = [
{
path: '/p/:id',
component: Post
},
{
path: '/c/:cat/i',
component: Item
}
]
Use route aliases for custom paths if needed:
{
path: '/about',
component: About,
alias: '/about-us'
}
Changed a URL? Set up a 301 redirect. Google transfers ranking signals to the new URL.
For Vue SPAs, handle redirects in your server configuration (Nginx, Apache, etc.):
# Nginx
location /old-blog-post {
return 301 /blog/new-post;
}
Or use Vue Router redirects (client-side only):
const routes = [
{
path: '/old-blog-post',
redirect: '/blog/new-post'
}
]
Note: Client-side redirects don't send proper 301 status codes. Use server-side redirects for SEO.
Don't skip redirects. Broken links lose traffic and rankings.
❌ 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
If you're using Nuxt, check out Nuxt SEO for built-in SEO features including automatic sitemap generation, route rules, and file-based routing.