The common migration checklist
Every migration on these pages follows the same phases. The path guides add what is specific to one source or target; this page is the frame they all fit into. Copy the checklists into your project's tracker and tick them off.
Migration hub · Tools: Exponential's import and export tools · Mapping: Mapping content to Exponential
Contents
- 1. Inventory: know what you have
- 2. Decide the scope and the owner of each part
- 3. Map the content model
- 4. URLs and redirects
- 5. Search engine metadata
- 6. Build the import and rehearse it
- 7. Test
- 8. Cut-over
- 9. Rollback
- 10. After go-live
- 11. Risks that recur
1. Inventory: know what you have
- To do: Every address of the old site. Crawl it (a sitemap alone misses orphan pages), export the server's access log of the last months, and list the addresses that search engines and other sites link to. This list drives the redirects in 4.
- To do: Every content type and how many items of each, in each language.
- To do: Media: images, documents, videos; where they are stored; total size; which are still referenced.
- To do: Users and groups: how many, which are editors, which are site members; whether passwords can move (they usually cannot, see 3).
- To do: Forms, comments, ratings, shop orders, newsletters: data that is not "content" but has to go somewhere, or be archived.
- To do: Integrations: single sign-on, search, analytics, payment, mail, feeds, APIs that other systems call.
- To do: Custom code: plugins, modules, extensions, templates, scheduled jobs.
- To do: Legal and retention: what must be kept, what must not be moved (personal data you no longer need is best left behind), who signs off.
2. Decide the scope and the owner of each part
| Part | Decide | Typical owner |
|---|---|---|
| Content to move | all, or a cut-off date, or only what still has traffic | content owner, editors |
| Design | carry over, refresh, or new | design, marketing |
| Addresses | keep identical, or new structure with redirects | SEO, developer |
| Users | move accounts, or ask users to register again | administrator, data protection |
| Features | which old features are needed on day one | project manager |
| Freeze | from when editors stop changing the old site, and how late changes are caught up | project manager, editors |
3. Map the content model
Write the mapping down as a table per content type before writing any import code. The columns that matter:
| Source type | Source field | Exponential class | Attribute (identifier) | Datatype | Conversion | Notes |
|---|---|---|---|---|---|---|
| e.g. Post | post_title | article | title | ezstring | none | required |
post_content | article | body | ezxmltext | HTML to XmlText | images become embeds | |
| categories | location | parent node | one main location, others as extra locations |
- To do: One class per source type, or fewer classes with a type selection: decide per type.
- To do: Every field mapped to an attribute or consciously dropped.
- To do: Rich text: decide how HTML becomes XmlText (or RichText on the Symfony platform) and what happens to inline styles, scripts and iframes (dropped, or turned into custom tags or embeds).
- To do: Taxonomy: locations (a tree), keywords (
ezkeyword), tags (eztags), or relations. - To do: Media: a separate image/file object per asset, related or embedded, so it can be reused.
- To do: Languages: one object with translations, not one object per language.
- To do: Users: the password hash types of the source are rarely readable by the target. Plan a reset (a mail with a link) unless the guide of your path says the hashes carry over.
- To do: Every object gets a remote id that names its source (
wp-post-1234), so re-running the import updates instead of duplicating, and so redirects can be generated from it.
The detail per concept is in Mapping content to Exponential.
4. URLs and redirects
- To do: For every old address, decide: same address on the new site, a 301 redirect to its new address, or a deliberate 410/404 (gone).
- To do: Generate the redirect table from the import: remote id to new node, old address to new address.
- To do: In Exponential, keep an old address in one of three ways (all documented in
URLs and aliases):
- The node's own URL alias: when the old path can be the new path (
about-us/team). Set the object's name or a custom alias so the alias matches. - A custom URL alias on the node that redirects (301) to the node's main address: one per old address that differs.
- A URL wildcard (
news/*toarticles/{1}) for whole groups that changed in a regular way.
- The node's own URL alias: when the old path can be the new path (
- To do: Addresses with query strings (
?p=123,index.php?id=5) or file extensions the alias system cleans: handle them in the web server or a small redirect module before Exponential, from the same table. - To do: Test every redirect automatically (status and destination), not by sampling.
- To do: Keep redirects for at least a year; search engines and old links need them that long.
5. Search engine metadata
- To do: Titles and meta descriptions: map them to attributes.
xrowmetadata(required incomposer.json) adds a metadata datatype with title, keywords and description, and an XML sitemap cronjob. - To do: Canonical addresses,
hreflangfor translations,robotsrules: reproduce in the pagelayout. - To do: An XML sitemap on the new site (
xrowmetadataorbcgooglesitemaps), submitted after go-live. - To do: Structured data (JSON-LD) the old site had: list it and rebuild it in templates.
- To do: Analytics and verification tags.
6. Build the import and rehearse it
- To do: Use the tools that exist first (Exponential's import and export tools); write a script only for what they cannot do.
- To do: Make the import repeatable: it reads a frozen export, matches on remote id, and updates what is already there.
- To do: Log every item: created, updated, skipped (and why).
- To do: Rehearse on a copy of the target at least twice. Time each run; the real cut-over window follows from it.
- To do: Count after each run: items per type and language, media files, users, redirects. Compare with the inventory.
7. Test
| Test | How |
|---|---|
| Counts | per type and language, against the inventory |
| Samples | the 50 most visited pages side by side, old and new |
| Rich text | headings, lists, tables, links, images, embedded media in a dozen complex items |
| Links | the link checker of the new site (URLs and aliases) and ./console exp:contentcheck for broken relations and missing files |
| Redirects | every row of the redirect table, automatically |
| Search | the site search finds new items; the search index is rebuilt (./console exp:updatesearchindex) |
| Permissions | editors can edit, anonymous visitors cannot see unpublished items |
| Performance | the main page types under load (benchmarking) |
| Accessibility | the templates, with an automatic checker and by keyboard |
8. Cut-over
- To do: Announce the freeze to editors; stop changes on the old site.
- To do: Final export, final import, counts, redirects test.
- To do: Lower the DNS time to live a day before; switch DNS or the proxy.
- To do: Clear caches and warm the most visited pages (
./console exp:warm,./console exp:preload --apply). - To do: Watch the logs (
./console exp:explogs) and the 404 list for the first hours; add redirects for what appears. - To do: Submit the sitemap; check the search console of each search engine for crawl errors.
9. Rollback
- To do: Keep the old site running, read-only, until sign-off. Rollback is switching DNS or the proxy back.
- To do: Keep a backup of the target taken just before the final import, so a failed final import can be repeated.
- To do: Decide in advance what triggers a rollback (for example: more than a set share of key pages broken, sign-in not working) and who decides.
- To do: Changes made on the new site after go-live are lost on a rollback unless they are recorded; keep the window short.
10. After go-live
- To do: 404 report daily for two weeks, then weekly.
- To do: Search ranking and traffic compared with before.
- To do: Old system archived (export plus database dump), then switched off at the agreed date.
- To do: Documentation of what was mapped, for the next migration.
11. Risks that recur
| Risk | Sign | Counter-measure |
|---|---|---|
| Lost addresses | traffic drops, 404s | a complete address inventory and automatic redirect tests |
| Broken rich text | odd markup, lost images | a conversion that is tested on the worst items first |
| Duplicates after re-runs | the same item twice | remote ids and update-on-match |
| Users locked out | sign-in failures | plan password resets and tell users before |
| Late content changes lost | editors complain | a short freeze, and a delta import for the last days |
| Underestimated templates | design not ready | start templates early, against the first rehearsal's content |
| Personal data moved without need | move only what you need; document the legal basis |
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.
This page is part of the Exponential documentation and is free documentation under the GNU Free Documentation License 1.3 or any later version (the license of this documentation).