---
title: "Site Migration SEO for Vue Apps"
description: "Migrate domains, redesign URLs, or switch frameworks without losing search rankings."
canonical_url: "https://nuxtseo.com/learn-seo/vue/launch-and-listen/site-migration"
last_updated: "2026-01-29"
---

<key-takeaways>

- Well-executed migrations recover 90-95% of traffic within 30 days
- Create 1:1 URL mapping spreadsheet before touching production
- Keep redirects for at least one year. longer if they still get hits

</key-takeaways>

Site migrations lose search rankings when done wrong. [Well-executed migrations recover 90-95% of traffic within 30 days](https://www.matthewedgar.net/how-long-keep-redirects/). Poor migrations can take 6-12 months to recover or never reach previous levels.

The difference is planning, proper redirects, and post-migration monitoring.

## Types of Migrations

Each migration type affects SEO differently:

![Migration Decision Tree](/images/learn-seo/vue/migration-decision-tree.svg)

**Domain change** (old.com → new.com): Requires [Change of Address tool in Google Search Console](https://support.google.com/webmasters/answer/9370220) and strict 1:1 URL mapping. Keep redirects for [at least one year](https://www.searchenginejournal.com/google-keep-301-redirects-in-place-for-a-year/428998/).

**Protocol change** (HTTP → HTTPS): Update all canonical tags to HTTPS versions. Forgetting this creates redirect loops. redirects send Google to HTTPS, but canonicals point back to HTTP.

**URL structure change** (/blog/post → /posts/post): Most prone to redirect chains. Map every old URL to exactly one new URL. No intermediates.

**Platform/framework change**: Moving from WordPress to Vue, or Vue to Nuxt. URL structure usually changes. Full redirect mapping required.

**Site redesign with same URLs**: Lowest risk if URLs stay identical. Still validate canonical tags and internal links.

## Pre-Migration Checklist

Start here before touching production:

1. **Crawl old site completely**: Use [Screaming Frog](https://screamingfrog.co.uk) or similar to export all URLs. You need a full inventory.
2. **Export indexed URLs from Search Console**: Go to Coverage report → Valid → Export. These are URLs Google knows about.
3. **Document current rankings**: Screenshot Search Console Performance for top pages. You'll compare against this.
4. **Create redirect mapping spreadsheet**: Three columns: Old URL | New URL | Status (200, 301, 410). Map every single URL. No exceptions.

For large sites (10,000+ pages), consider [migrating in sections](https://developers.google.com/search/docs/crawling-indexing/site-move-with-url-changes). Test with a small section first, verify traffic holds, then migrate the rest.

## Redirect Mapping Strategy

Mapping is where migrations succeed or fail.

**1:1 mapping** (preferred): Each old URL redirects to exactly one new URL with identical or similar content.

```text
/blog/vue-seo-guide → /guides/vue-seo
/products/item-123 → /products/item-123 (unchanged)
```

**Pattern-based redirects**: For systematic URL changes. Use regex or route patterns to redirect entire sections.

```text
/blog/:slug → /articles/:slug
/category/:cat/page/:num → /c/:cat?page=:num
```

**Deleted pages**: Don't 404 pages that had traffic or backlinks. Redirect to the most relevant alternative. If truly no alternative exists, return 410 (Gone) instead of 404. signals permanent removal.

## Implementing Redirects in Vue

SEO requires server-side redirects. Client-side redirects (JavaScript) don't pass PageRank.

### Express Server

```ts
import express from 'express'

const app = express()

// Single redirect
app.get('/old-url', (req, res) => {
  res.redirect(301, '/new-url')
})

// Pattern redirect
app.get('/blog/:slug', (req, res) => {
  res.redirect(301, `/posts/${req.params.slug}`)
})

// Redirect map for bulk redirects
const redirects = {
  '/old-page-1': '/new-page-1',
  '/old-page-2': '/new-page-2',
  '/company/about': '/about'
}

app.use((req, res, next) => {
  const redirect = redirects[req.path]
  if (redirect) {
    return res.redirect(301, redirect)
  }
  next()
})
```

### Vite Server

```ts
// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    middleware: [
      (req, res, next) => {
        const redirects = {
          '/old-path': '/new-path',
          '/blog': '/posts'
        }

        const redirect = redirects[req.url]
        if (redirect) {
          res.writeHead(301, { Location: redirect })
          res.end()
          return
        }
        next()
      }
    ]
  }
})
```

### H3 Server (Nitro/Nuxt)

```ts
// server/middleware/redirects.ts
import { defineEventHandler, sendRedirect } from 'h3'

const redirects = {
  '/old-url': '/new-url',
  '/blog': '/posts'
}

export default defineEventHandler((event) => {
  const redirect = redirects[event.path]
  if (redirect) {
    return sendRedirect(event, redirect, 301)
  }
})
```

For large redirect maps (1000+ URLs), load from JSON file:

```ts
import redirectData from './redirects.json'

export default defineEventHandler((event) => {
  const redirect = redirectData[event.path]
  if (redirect) {
    return sendRedirect(event, redirect, 301)
  }
})
```

## Avoid Redirect Chains

[Redirect chains](https://netpeaksoftware.com/blog/top-10-site-migration-mistakes) happen when URL A redirects to B, which redirects to C. This dilutes PageRank and slows crawling.

Common scenario: You have old redirects (A → B) and add new migration redirects (B → C). Result: chain A → B → C.

Fix: Update all redirects to point directly to final destination. Consolidate old and new redirects into single-hop redirects.

```ts
// Bad: creates chain
// Old redirect: /page-v1 → /page-v2
// New redirect: /page-v2 → /page-v3
// Result: /page-v1 → /page-v2 → /page-v3

// Good: consolidate
const redirects = {
  '/page-v1': '/page-v3', // direct to final
  '/page-v2': '/page-v3'
}
```

Test redirects before launch: Each should return 301 status and resolve in one hop to 200 (OK).

## Update Canonical Tags

When URLs change, canonical tags must point to new URLs. [Canonical pointing to redirect](https://sitechecker.pro/site-audit-issues/canonical-points-redirect/) is a common migration mistake.

After migration, canonical tags should reference new URL structure:

```html
<!-- Bad: canonical points to old URL -->
<link rel="canonical" href="https://example.com/old-url">

<!-- Good: canonical points to new URL -->
<link rel="canonical" href="https://example.com/new-url">
```

In Vue with Unhead:

```ts
useHead({
  link: [
    { rel: 'canonical', href: 'https://example.com/new-url' }
  ]
})
```

Scan staging site before launch to verify all canonicals point to new URLs, not old ones.

## Post-Migration Steps

The hour after migration is critical.

1. **Update Search Console property**: For domain changes, use [Change of Address tool](https://support.google.com/webmasters/answer/9370220). This tells Google you've moved.
2. **Submit new sitemap**: Generate sitemap with new URLs. Submit in Search Console. Remove old sitemap from robots.txt.
3. **Request indexing of key pages**: In Search Console, request indexing for homepage and top 10-20 pages. Speeds up discovery.
4. **Monitor coverage report**: Check daily for errors. Look for 404s, soft 404s, redirect errors, or pages not followed.
5. **Watch server capacity**: [Google crawls more after migrations](https://developers.google.com/search/docs/crawling-indexing/site-move-with-url-changes). Redirects from old URLs trigger crawls of new URLs. Monitor server load.
6. **Check Analytics segmentation**: Set up date comparison in Google Analytics. before migration vs after. Track organic traffic specifically.

<tip title="Don't Forget AI Bots">

Ensure your redirects also work for AI crawlers like `GPTBot` and `PerplexityBot`. If they encounter loops or errors, you'll lose your citations in AI search results as you lose rankings in Google.

</tip>

## Recovery Timeline

![Migration Recovery Timeline](/images/learn-seo/vue/migration-recovery-gantt.svg)

Expect these phases:

**Week 1-2**: Traffic dip of [10-25% is normal](https://moz.com/blog/website-migration-guide). Google discovers redirects and starts reindexing.

**Week 3-4**: [Small sites recover](https://www.searchenginejournal.com/website-migration-guide/369728/) 90%+ of traffic if migration was clean. Large sites still reindexing.

**Month 2-3**: Most sites reach full recovery. Rankings stabilize. [Typical range is 30-60 days](https://www.localseoguide.com/how-long-does-it-take-to-recover-from-a-domain-migration/).

**Month 4-6**: Large sites (100,000+ pages) continue recovery. [Average across 892 migrations was 523 days](https://www.searchenginejournal.com/site-migration-study-data/484555/). but median is much lower.

**Keep redirects for 1+ year**: [Google recommends at least 12 months](https://www.searchenginejournal.com/google-keep-301-redirects-in-place-for-a-year/428998/). Longer if you still see traffic to old URLs. Never remove redirects that still get hits.

If traffic hasn't recovered after 3 months, audit for:

- Missing redirects (404s in coverage report)
- Redirect chains
- Canonical tags still pointing to old URLs
- Internal links still pointing to old URLs

## Common Migration Mistakes

**Redirect chains**: As mentioned, these dilute authority. [Consolidate old and new redirects](https://developers.google.com/search/docs/crawling-indexing/301-redirects) into single-hop redirects.

**Forgetting internal links**: Your site's internal links still point to old URLs, triggering unnecessary redirects. Update internal links to point directly to new URLs.

**Not updating canonical URLs**: Canonical tags create loops when they point to redirected URLs. [Update canonicals alongside redirects](https://web.dev/articles/canonicalization).

**Removing redirects too early**: Traffic sources outside your control (old backlinks, bookmarks, third-party sites) use old URLs indefinitely. Keep redirects for years, not months.

**Client-side redirects**: JavaScript redirects (`window.location`) don't pass PageRank. Google may not follow them. SEO requires server-side 301s.

**No redirect testing**: Test redirects on staging before launch. Verify each returns 301 and resolves to 200 in one hop.

**Forgetting mobile/AMP URLs**: If you had separate mobile URLs (m.example.com) or AMP versions, redirect those too.

## Using Nuxt?

Nuxt applications should use [server middleware for redirects](/learn-seo/nuxt/controlling-crawlers/redirects).

For full Nuxt migration guides, see [Launch & Listen section](/learn-seo/nuxt/launch-and-listen).

<checklist id="site-migration-vue" title="Site Migration Checklist">

- Crawl old site and export all URLs
- Export indexed URLs from Search Console Coverage report
- Create redirect mapping spreadsheet (Old URL → New URL)
- Implement server-side 301 redirects (not client-side)
- Update all canonical tags to new URLs
- Update internal links to point directly to new URLs
- Submit new sitemap and remove old one
- Use Change of Address tool (for domain changes)
- Monitor Coverage report daily for first 2 weeks
- Keep redirects active for at least 1 year

</checklist>
