HTTP Redirects in Nuxt

Learn how to implement SEO-friendly redirects in Nuxt applications.

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:

Quick Setup

In Nuxt 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 value
  • 302: Temporary redirect - keeps SEO value on original URL
  • 307: Temporary redirect (preserves HTTP method)
  • 308: Permanent redirect (preserves HTTP method)

For SEO, 301 redirects are most common as they pass ranking signals to the new URL.

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

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // Single redirects
    '/old': { redirect: '/new' },

    // Pattern matching
    '/blog/*': { redirect: '/articles/*' },

    // Parameter mapping
    '/products/:id': { redirect: '/shop/:id' }
  }
})

HTTPS Enforcement

server/middleware/https.ts
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

server/middleware/www.ts
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

  1. Test direct URL access
  2. Verify correct status code (301 vs 302)
  3. Check redirect destination
  4. Monitor redirect chains
  5. Test with/without trailing slashes
  6. Verify query parameter handling

Using Tools

Common Issues

Redirect Chains

Bad:

/old → /interim → /final

Good:

/old → /final
/interim → /final

Mixed Content

When moving to HTTPS, update all resource URLs:

server/middleware/https.ts
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:

nuxt.config.ts
export default defineNuxtConfig({
  // ❌ Bad
  '/page-a': { redirect: '/page-b' },
  '/page-b': { redirect: '/page-a' },

  // ✅ Good
  '/page-a': { redirect: '/final' },
  '/page-b': { redirect: '/final' }
})

Core Concepts

Implementation Methods

Resources