---
title: "HTTP Redirects for SEO in Nuxt"
description: "Configure permanent redirects in Nuxt with routeRules. Check status codes, destination URLs, and redirect loops before a migration."
canonical_url: "https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/redirects"
last_updated: "2026-10-05"
---

> Index of every page on this site: [llms.txt](https://nuxtseo.com/llms.txt)

::key-takeaways
- Permanent redirects provide a strong canonicalization signal; use them for permanent moves
- Prefer server-side redirects; Google can process JavaScript redirects, but rendering failures can prevent detection
- Avoid redirect chains: point every old URL straight at its final destination instead of hopping through intermediate pages
- Keep a redirect live for at least a year after a migration so Google's systems see it enough times to treat it as permanent
::

A 301 redirect indicates a permanent move. [Google treats permanent redirects as a strong canonicalization signal](https://developers.google.com/search/docs/crawling-indexing/301-redirects).

A redirect exposes the replacement URL in the HTTP response. This does not guarantee that search rankings or AI citations carry over.

Use 301 or 308 for permanent moves: site migrations, URL restructuring, domain changes, and deleted pages with a direct replacement. For duplicate content use [canonical tags](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/canonical-urls) instead. For temporary moves use 302 or 307.

## Quick Setup

Nuxt handles redirects through `routeRules` in your config or server middleware:

::code-group
```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    '/old-page': { redirect: { to: '/new-page', statusCode: 301 } },
    '/blog/**': { redirect: { to: '/articles/**', statusCode: 301 } }
  }
})
```

Use pathname-aware server middleware for dynamic redirects. Preserve content query parameters and verify the final destination. The routeRules example above is the bounded fixed/wildcard recipe tested here.
::

## 301 vs 302 Redirects

### When to Use Each

**301 (Permanent)**: a strong signal that the destination should be canonical. Use it for:

- Permanent content moves
- Domain migrations
- URL structure changes
- Deleted pages with direct replacements
- HTTP to HTTPS upgrades

**302 (Temporary)**: a weaker canonicalization signal. Use it for temporary changes such as:

- A/B testing
- Temporary promotions
- Maintenance pages
- Out-of-stock product redirects

If a 302 stays active for months with no plan to revert, switch to a 301: permanent redirects provide a stronger canonicalization signal, telling its indexing pipeline that the destination URL should be the one it indexes ([Search Central](https://developers.google.com/search/docs/crawling-indexing/301-redirects)).

**307/308**: like 302/301 but preserve the HTTP method (a POST stays a POST). 308 is also a supported permanent redirect.

### How Long to Keep Redirects Active

[Google recommends keeping migration redirects for at least a year](https://developers.google.com/search/docs/crawling-indexing/site-move-with-url-changes). Keep useful redirects longer if old links still receive traffic.

Keep redirects even longer if:

- External sites still link to the old URLs
- Old URLs still receive referral traffic
- High-value pages have many backlinks

Removing redirects can break old links. Keep them while users or crawlers still rely on the original URLs.

### Avoid Redirect Chains

Redirect chains (A → B → C) waste [crawl budget](https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers#when-crawler-control-matters) and slow page speed; each hop adds a request and can delay navigation. TTFB is not a Core Web Vital. Google's crawlers follow up to [10 redirect hops](https://developers.google.com/search/docs/crawling-indexing/http-network-errors#3xx-redirection) by default, then give up. Redirect directly to the final destination:

Bad:

```plaintext
/old → /interim → /final
```

Good:

```plaintext
/old → /final
/interim → /final
```

## Common Patterns

### Domain Migration

Deploy this catch-all redirect only on the old host. Applying it to the replacement host can create a loop.

::code-group
```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    // Redirect entire old domain to new domain
    '/**': {
      redirect: {
        to: 'https://new-domain.com/**',
        statusCode: 301
      }
    }
  }
})
```

```ts [server/middleware/domain.ts]
export default defineEventHandler((event) => {
  const host = getRequestHost(event)
  if (host === 'old-domain.com') {
    return sendRedirect(event, `https://new-domain.com${event.path}`, 301)
  }
})
```
::

### URL Structure Changes

::code-group
```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    '/old': { redirect: { to: '/new', statusCode: 301 } },
    '/blog/**': { redirect: { to: '/articles/**', statusCode: 301 } },
    '/products/**': { redirect: { to: '/shop/**', statusCode: 301 } }
  }
})
```

Use the routeRules mapping above for these permanent moves. A custom middleware alternative must parse pathname and query separately; it is not supplied here.
::

### HTTPS Enforcement

Configure HTTP-to-HTTPS redirects at your trusted host or proxy. HSTS tells supporting browsers to use HTTPS after receiving the policy; the header itself is not an HTTP redirect.

Do not use an untrusted Host header to construct a redirect destination. See the [security guide](https://nuxtseo.com/learn-seo/nuxt/routes-and-rendering/security).

### WWW Standardization

Configure one preferred host at your hosting provider. Redirect the other host to its matching path on the preferred host.

Do not build redirect destinations from an untrusted Host header. Test both host variants and check for loops before enabling the rule.

## Testing Redirects

Verify redirects work correctly before deploying:

1. **Check status code**: use browser dev tools Network tab, confirm the intended 301/308 or 302/307
2. **Test destination**: make sure the redirect points to the correct final URL
3. **Verify no chains**: confirm a single hop to the destination
4. **Test trailing slashes**: check with and without a trailing slash
5. **Check query parameters**: verify parameters carry over if needed

Useful tools:

- [Google Search Console](https://search.google.com/search-console): monitor crawl errors and redirect issues
- Browser dev tools Network tab: check status codes and headers
- [Screaming Frog](https://www.screamingfrog.co.uk/seo-spider/): bulk redirect testing and chain detection
- curl: `curl -I https://example.com/old-page` shows redirect headers

## Common Mistakes

### Redirecting to Irrelevant Pages

Mass-redirecting deleted pages to your homepage sends users and crawlers to unrelated content. It discards the topical relevance the old URL had built up, and it reads as lazy to anyone who lands there looking for the page they clicked.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    // ❌ Bad - mass redirects to homepage
    '/blog/**': { redirect: '/' },

    // ✅ Good - redirect to relevant content
    '/blog/vue-tips': { redirect: { to: '/articles/vue-tips', statusCode: 301 } },
    '/blog/seo-guide': { redirect: { to: '/articles/seo-guide', statusCode: 301 } }
  }
})
```

### Redirect Loops

If page A redirects to B and B redirects to A, requests loop. This example sends both old URLs to one final destination:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    // ✅ Good - both redirect to final destination
    '/page-a': { redirect: { to: '/final', statusCode: 301 } },
    '/page-b': { redirect: { to: '/final', statusCode: 301 } }
  }
})
```

### Client-Side Redirects and Stale Internal Links

[Google can process JavaScript redirects](https://developers.google.com/search/docs/crawling-indexing/301-redirects), but rendering can fail. Prefer an HTTP redirect when you control the server.

Relying on redirects for internal links wastes server resources and slows page speed. Update internal links to point directly at the new URLs, and keep redirects for external links and old bookmarks.

## Checklist

::checklist{#nuxt-redirects}
- Permanent URL moves use the intended server-side 301 or 308
- Redirects are set with `routeRules` or server middleware, not client-side JavaScript
- Old URLs redirect directly to their final destination, no chains
- No redirect loops
- Redirects stay active for at least a year after a migration
- Internal links point directly at the new URLs
::

## Sitemap

See the full [sitemap](https://nuxtseo.com/sitemap.md) for all pages.
