HTTP Redirects in Vue & Nuxt
Learn how to implement SEO-friendly redirects in Vue applications.
8 mins read
Last Updated
Published
Introduction
HTTP redirects tell search engines and users that content has moved to a new location. When implemented correctly, they preserve your SEO value while ensuring users find your content.
✅ Good for:
- Site migrations and redesigns
- URL structure changes
- Moving to new domains
- Fixing broken URLs
- Merging duplicate content
❌ Don't use for:
- Temporary content changes (use 302 redirects)
- Duplicate content (use canonical tags)
- Blocked content (use noindex)
- Cross-language content (use hreflang)
Quick Setup
In Vue applications, implement redirects at the server level:
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/old-page': { redirect: '/new-page' },
'/blog/:slug': { redirect: '/articles/:slug' }
}
})
// server/middleware/redirects.ts
export default defineEventHandler((event) => {
if (event.path === '/old-page') {
return sendRedirect(event, '/new-page', 301)
}
})
<!-- pages/old-page.vue -->
<script setup>
// Only use for simple cases
navigateTo('/new-page', { redirectCode: 301 })
</script>
Understanding Redirects
Redirect Types
301 : Permanent redirect - transfers SEO value302 : Temporary redirect - keeps SEO value on original URL307 : Temporary redirect (preserves HTTP method)308 : Permanent redirect (preserves HTTP method)
For SEO,
Important Notes
- Implement at server level when possible
- Avoid redirect chains (A → B → C)
- Keep redirects active for 6+ months
- Monitor in Search Console
- Consider impact on crawler budget
Common Patterns
Domain Migration
// server/middleware/domain.ts
export default defineEventHandler((event) => {
const host = getRequestHost(event)
// Redirect old domain to new
if (host === 'old-domain.com') {
return sendRedirect(
event,
`https://new-domain.com${event.path}`,
301
)
}
})
URL Structure Changes
export default defineNuxtConfig({
routeRules: {
// Single redirects
'/old': { redirect: '/new' },
// Pattern matching
'/blog/*': { redirect: '/articles/*' },
// Parameter mapping
'/products/:id': { redirect: '/shop/:id' }
}
})
HTTPS Enforcement
export default defineEventHandler((event) => {
if (!event.headers.get('x-forwarded-proto')?.includes('https')) {
return sendRedirect(
event,
`https://${getRequestHost(event)}${event.path}`,
301
)
}
})
Learn more about HTTPS in our security guide.
WWW Standardization
export default defineEventHandler((event) => {
const host = getRequestHost(event)
// Redirect non-www to www
if (!host.startsWith('www.')) {
return sendRedirect(
event,
`https://www.${host}${event.path}`,
301
)
}
})
Testing
Manual Checks
- Test direct URL access
- Verify correct status code (301 vs 302)
- Check redirect destination
- Monitor redirect chains
- Test with/without trailing slashes
- Verify query parameter handling
Using Tools
- Google Search Console - Monitor crawl errors
- Browser Dev Tools - Check network responses
- Screaming Frog - Bulk redirect testing
Common Issues
Redirect Chains
Bad:
/old → /interim → /final
Good:
/old → /final
/interim → /final
Mixed Content
When moving to HTTPS, update all resource URLs:
export default defineEventHandler((event) => {
// Redirect HTTP to HTTPS
if (event.headers.get('x-forwarded-proto') === 'http') {
return sendRedirect(
event,
`https://${getRequestHost(event)}${event.path}`,
301
)
}
})
Redirect Loops
Avoid circular redirects:
export default defineNuxtConfig({
// ❌ Bad
'/page-a': { redirect: '/page-b' ,
'/page-b': { redirect: '/page-a' ,
// ✅ Good
'/page-a': { redirect: '/final' },
'/page-b': { redirect: '/final' }
})
Related
Core Concepts
- Understanding Crawler Control - Complete guide
- Crawler Security - Secure implementation
Implementation Methods
- Canonical URLs - Managing duplicate content
- Meta Robots - Page-level control
- Robots.txt - Site-wide rules
Resources
- Google's Redirection Guidelines
- Sitemap Integration - URL discovery