# Migrating an Existing Site

> Port a client's existing website into Seedly Sites - the migrate command, the parity gate, what carries over for SEO, and what needs rebuilding.

Porting is one of the two ways to fill a new client site with content: point the migration tool at the client's existing website and it reproduces the site in the builder - structure, content, styling, brand, and blog - ready for review. This is how you take over a site without rebuilding it from scratch.

Migration today is operator-run from the command line. A one-click portal migration surface is planned but not built yet, so the CLI below is the supported path.

---

## What a Migration Does

Given the site's URL, the migration:

1. **Discovers the pages** (from the site's own page listing or sitemap)
2. **Extracts each page** with a real browser, capturing the rendered structure and computed styling
3. **Converts everything to builder elements** - real sections, rows, columns, headings, images, buttons, accordions - not screenshots or frozen HTML
4. **Captures the brand** - colors, fonts, and site chrome are written into the site's settings
5. **Imports media** into your storage and **remaps internal links** so pages point at each other, not at the old site
6. **Imports the blog** as posts
7. **Persists every page as a draft** in the target site

Because pages become native builder elements, the ported site is fully editable afterward - the migration is a starting point you own, not a locked-in copy.

### Drafts Only, Always

A migration never publishes and never deploys. Every page lands as a draft for your review. If imported images could not be brought into your own media storage, the affected pages are held as drafts and the tool tells you which URLs to fix - so a half-imported site cannot leak live.

---

## Running a Migration

From the platform repo, with your CMS running:

```bash
seedly migrate https://the-client-site.com \
  --tenant client-slug \
  --cms-base https://your-cms.example.com
```

The target site is found or created by slug. Useful flags:

| Flag | Use |
|------|-----|
| `--dry-run` | Extract and convert without persisting - inspect the result first |
| `--only home,about,services` | Port just these pages |
| `--limit 3` | Port the first few pages (testing) |
| `--blog-only` | Skip pages; import or re-import only the blog |
| `--qa` | Capture source-vs-result screenshots and score similarity after the run |

---

## The Parity Gate

After porting, diff each page against the live original:

```bash
seedly parity home \
  --orig https://the-client-site.com \
  --ours https://your-preview-url/site/client-slug
```

The parity check compares section by section - structural content plus desktop and mobile screenshots - and prints a coverage report: clean sections, sections with gaps, and anything dropped. Migration runs are also tracked in the portal's migration board, where each page carries its parity signal for triage.

Work the gaps in the builder before publishing anything.

---

## Honest Expectations: What Carries and What Does Not

**Migration reproduces the site closely - then you finish in the builder.** In practice runs land around 91 percent content parity before review. It is not pixel-perfect and we will not pretend otherwise; the parity report exists precisely to show you the remaining distance.

**Carries over:**

- Page structure, text, images, and styling as native builder elements
- Brand colors, fonts, and chrome
- Blog posts
- Canonical tags
- Internal links, remapped to the new site

**Handled at go-live (by you, with platform support):**

- **301 redirects** for any URLs that changed - managed per site and shipped with every [deploy](/docs/help/deploying)
- **Sitemap** - regenerated automatically on every deploy
- **External backlinks** - links on other websites keep working only via the 301s you set up; there is no way for any platform to edit other people's sites

**Does not carry over:**

- **Forms** - a scraped form would post to the old host, so forms arrive as placeholders. Re-add each one as an embed ([Forms](/docs/help/forms))
- **Custom plugin code** from the old platform - anything that ran server-side or as a proprietary plugin needs a native or embedded replacement
- **Domain-locked widgets** (some review and booking embeds) render blank until the real domain goes live - do not "fix" these pre-launch

---

## The Full Takeover Flow

1. Create the client site (or let `migrate` create it by slug)
2. Run the migration; inspect with `--dry-run` first if the site is unusual
3. Run the parity check per page; fix gaps in the builder, native fields first
4. Re-embed forms; note any domain-locked widgets for post-launch
5. Review and publish the pages
6. Set up 301 redirects for changed URLs
7. Set the custom domain and [deploy](/docs/help/deploying)

One rule to respect: **migration is a one-time initial import.** Re-run it only before hand-editing begins - after takeover, the builder is the source of truth.

---

## Summary

| Question | Answer |
|----------|--------|
| Input | The live site's URL |
| Output | Draft pages of native builder elements + brand + media + blog |
| Fidelity | Close (roughly 91 percent content parity), verified per page by the parity gate |
| Publishes anything? | Never - drafts only, you publish and deploy |
| Forms / plugins | Do not survive - re-embed forms, replace plugin behavior |
| SEO | 301s + canonicals + remapped internal links + regenerated sitemap |

---
Source: https://seedlysites.com/docs/help/port-a-site
