# CMS migration SEO: change platform without losing URLs, metadata or schema

> Moving from WordPress to Shopify, Webflow or a headless setup changes more than the design. How to keep URLs where you can, redirect the rest and carry titles, descriptions, structured data and content across.

Updated 2026-09-26 · Technical SEO · HTML version: https://getreport.app/guides/cms-migration-seo

A CMS migration, such as moving from WordPress to Shopify, Webflow or a headless front end, keeps your rankings when three things survive the move: the URLs, or a one-hop 301 from each old URL to its new one; the on-page signals, such as titles, descriptions, headings, internal links and structured data; and a site Google can render and index from launch day. Platforms differ most in the URLs they allow and in what their import tools leave behind. This guide is for site owners and the people building the new site: it shows how to plan a platform change template by template, where each platform forces URL changes, and how to verify the result. For migrations in general, including domain and https moves, start with the [website migration guide](https://getreport.app/guides/website-migration-seo).

## Quick answer

- **Keep every URL the new platform lets you keep.** Slugs are usually free; fixed prefixes such as Shopify's `/products/` are not.
- **Map every URL that must change** to its closest new equivalent, and redirect it in one 301 hop on launch day.
- **Inventory the SEO fields before you export:** titles, meta descriptions, canonicals, `noindex` settings, hreflang, alt text and structured data often live in plugins that import tools skip.
- **Compare templates, not just pages.** Check one product, one category, one article and one landing page on staging against the live site.
- **Make sure the new site renders on the server,** or that content and links appear in the HTML without JavaScript.
- **Verify on staging, on launch day and a week later** with every old URL, using the [migration redirect validator](https://getreport.app/tools/migration-validator).

## Why a platform change is riskier than it looks

A new CMS looks like a design project, so SEO is often checked last. But a platform decides the things search engines read: the URL pattern, the HTML each template outputs, what goes in the `<head>`, how pagination and filters work, and whether content is in the HTML or appears only after JavaScript runs. When those change, Google has to re-learn the site.

The losses after a CMS migration usually come from four gaps:

1. **URLs changed without a redirect,** because the new platform uses different prefixes or slugs and nobody mapped them.
2. **SEO fields left behind.** Custom titles and meta descriptions written in a WordPress SEO plugin are stored in plugin fields, not in the post content, so a content import brings the text but not the metadata.
3. **Thinner templates.** Category pages without their intro text, products without their FAQ block, articles without author or date, lost breadcrumbs and related links.
4. **Missing structured data.** Product, breadcrumb, article and organization markup that a plugin produced on the old site and nothing produces on the new one.

All four are visible on staging if you look before launch.

## Step 1: inventory what the old site has

Export more than the content. For every indexable URL, record:

| Field | Where it usually lives on the old site |
| --- | --- |
| URL | Sitemap, crawl, analytics landing pages, Search Console pages with impressions |
| Title tag and meta description | SEO plugin fields, not the page body |
| H1 and main headings | Page content or template |
| Canonical and `noindex` settings | SEO plugin or template |
| hreflang | Multilingual plugin or template |
| Structured data types | SEO or schema plugin, theme |
| Image alt text | Media library |
| Internal links in navigation, footer, breadcrumbs | Theme menus and widgets |
| Existing redirects | Redirect plugin, `.htaccess`, CDN |

A crawl with an SEO crawler gives you most of this in one export. For the pages that matter most, the full getReport report gives a snapshot you can compare later, with titles, descriptions, headings, canonical, structured data and speed per page. The [before-and-after measurement guide](https://getreport.app/guides/measuring-before-and-after-a-redesign) shows how to choose those key pages and what baseline to record.

Do not forget the existing redirects. Rules from earlier relaunches, in a WordPress redirect plugin or `.htaccess`, disappear with the old platform unless you carry them across, and old links from other sites start answering 404 again.

## Step 2: keep URLs where the platform allows

Every platform lets you set the last part of a URL, the slug. Where they differ is the path in front of it:

| Platform | Typical URL patterns you cannot change freely |
| --- | --- |
| Shopify | `/products/{handle}`, `/collections/{handle}`, `/pages/{handle}`, `/blogs/{blog}/{article}` |
| Webflow | CMS items at `/{collection}/{item}`; static pages can be nested in folders |
| Wix | Blog posts under `/post/`, store products under `/product-page/` by default |
| WordPress | Almost anything, set by permalinks and custom post types |
| Headless or custom | Anything the developer builds |

Moving from WordPress to Shopify therefore changes every product and category URL, even when every slug stays the same: `/shop/red-runner/` becomes `/products/red-runner`. Moving from Shopify to WordPress with WooCommerce, the reverse is true, and you can often recreate Shopify's paths exactly with WooCommerce's permalink settings.

Rules of thumb:

- **Keep slugs identical** wherever you can, including the trailing slash convention. It makes mapping mechanical.
- **Keep static pages at the same paths.** About, contact, services and landing pages can almost always keep their URLs.
- **Do not change URLs for tidiness.** A shorter slug is not worth a redirect and weeks of recrawling.
- **Check how the new platform handles the trailing slash and letter case,** and pick the form it serves as canonical.

## Step 3: map and redirect the URLs that change

Every old URL that has traffic, links or rankings needs a one-hop 301 to its closest equivalent: product to product, category to category, article to article. Build the list as a two-column spreadsheet, old and new. When slugs stayed the same, most rows can be matched automatically by slug, and only the leftovers need a human.

The [redirect mapping guide](https://getreport.app/guides/redirect-mapping-for-site-migration) walks through collecting the old URLs, matching them, handling pages with no equivalent and testing the map. The generator turns the finished list into rules:

> **Free tool:** [301 redirect .htaccess and nginx rule generator](https://getreport.app/tools/redirect-generator): Get 301 redirect .htaccess rules, or nginx, Cloudflare, Netlify, Vercel and Caddy rules, from your list of old and new URLs. Free, runs in your browser.

Where the redirects live depends on the new platform:

- **Shopify** has URL redirects in the admin (under Content → Menus → URL redirects in current versions) with CSV import. Shopify only applies a redirect when nothing exists at the old path, and its redirects are permanent 301s.
- **Webflow** has 301 redirects under Site settings → Publishing, including patterns with capture groups for whole folders.
- **WordPress** uses a redirect plugin or server rules; see [WordPress redirects](https://getreport.app/guides/wordpress-redirects).
- **Headless and custom sites** can redirect at the host or CDN, such as Netlify, Vercel or Cloudflare, before the app loads, which is the fastest option on any platform.

Check whether the platform limits the number of redirects or how query strings are matched. Old URLs such as `/index.php?id=12` need rules that match the query string, which not every redirect tool supports; a CDN rule usually can.

## Step 4: carry the on-page signals across

Go through the new site one template at a time, on staging, and compare it with the old live page of the same type:

- **Title and meta description.** Custom values moved into the new platform's SEO fields, not replaced by a default pattern such as "Product name – Store name" everywhere.
- **Headings.** One `h1` per page with the same wording, and the same subheadings on long pages.
- **Body content.** The same text, including category intros, product descriptions, FAQ blocks and specifications. Import tools often drop anything that lived in a page builder's shortcodes or custom fields.
- **Images.** The same images with their alt text, at sensible sizes.
- **Internal links.** Navigation, breadcrumbs, related products and in-text links pointing at the new URLs, not at old ones that now redirect.
- **Canonical tags** pointing at each page's own new URL, and `noindex` only where you intend it.
- **hreflang** for multilingual sites, with every language version on its new URL.
- **Structured data.** The same types as before: Product with price and availability, BreadcrumbList, Article, Organization. Run the [schema validator](https://getreport.app/tools/schema-validator) on each template.

Then run the full getReport report on each staging template. These findings catch most of what gets lost:

> **Check: The page has a <title>.** The title is the headline Google shows in results and the text in the browser tab. Without it, the page is hard to find and hard to recognise.
>
> 1. Add a <title> inside <head> that describes this page in 30–60 characters.
> 2. In WordPress, set it under the page's SEO panel (Yoast, Rank Math) or the page title.

> **Check: Meta description is present.** The description is the two-line preview under your result. Without it, Google picks a random sentence from the page.
>
> 1. Add <meta name="description" content="…"> with 70–160 characters that say what the page offers.
> 2. In WordPress, most SEO plugins add a field for it on every page.

> **Check: Canonical tag is present.** Without a canonical URL, search engines may index duplicate versions of this page (with and without trailing slash, with UTM parameters) and split its ranking signals.
>
> 1. Add <link rel="canonical" href="https://your-site.com/page/"> in <head>.
> 2. In WordPress, Yoast or Rank Math add this automatically — check it is not disabled for this page.

> **Check: Structured data found.** Structured data lets Google show rich results such as prices, review stars, breadcrumbs and event dates. Without it, or when every block has a syntax error, Google reads none and your listing is plain text.
>
> 1. Add a JSON-LD script describing the page's main entity (Organization, Product, Article…). If the page already has one that cannot be parsed, fix its syntax first.
> 2. Most CMS SEO plugins generate this for you; check their schema settings.

> **Check: The page can be indexed.** To appear in search, a page must return HTTP 200, carry no noindex directive and be allowed in robots.txt. If any of the three fails, the page is invisible to searchers.
>
> 1. Open the technical detail to see which condition fails, then fix that one; the individual findings above have the steps.
> 2. After the fix, request indexing in Google Search Console to speed things up.

## Step 5: check that the new platform renders for Google

Hosted platforms such as Shopify and Webflow send content in the HTML. Headless setups and JavaScript frameworks may not: if the product text and links appear only after scripts run, Google has to render the page to see them, and other crawlers, including link previews and many AI crawlers, may never see them. Make sure the framework renders pages on the server or at build time. getReport measures how much of the visible text needs JavaScript:

> **Check: The visible text is present without JavaScript.** Google renders JavaScript later and with a budget, so text that only appears after scripts run can be indexed late or not at all. Other search engines and link previews may never see it.
>
> 1. Serve the main content in the HTML (server-side rendering or static generation) and use JavaScript only to enhance it.
> 2. Check the difference in the technical detail; menus and widgets are fine, headlines and body copy are not.

The [JavaScript SEO guide](https://getreport.app/guides/javascript-seo) explains server rendering, static generation and what to ask your developer.

## Step 6: launch and verify

On launch day, switch DNS or the platform, publish the redirects at the same moment, remove any staging password or `noindex`, and submit the new XML sitemap in Search Console. The Search Console property stays the same when the domain does not change.

Then run every old URL through the validator:

> **Free tool:** [301 redirect map validator for site migrations](https://getreport.app/tools/migration-validator): Check your 301 redirect map after a migration. Paste up to 1,000 old and new URL pairs and see which land right, chain, go temporary or are lost. Free.

Paste the redirect map, up to 1,000 pairs per run. Each old URL is requested and followed hop by hop, and every pair gets a verdict: correct, wrong target, not redirected or gone, chain, temporary redirect, or a target that is broken or set to `noindex`. Run it on staging before launch if the redirects can be tested there, on launch day, and a week later when caches have caught up.

In the following weeks, watch Search Console's Page indexing report for rising "Not found (404)" counts, check the 404 log of your new platform or server for old URLs you missed, and compare your key pages against the baseline. The [site migration checklist](https://getreport.app/guides/site-migration-checklist-domain-https-cms) has every launch-day and after-launch task in order. If you are also changing the domain, read [changing domain name without losing SEO](https://getreport.app/guides/domain-change-seo) as well.

## Platform notes

**WordPress to Shopify.** Products and collections move to `/products/` and `/collections/`, so every shop URL changes. Blog posts move under `/blogs/news/` or another blog handle. Shopify's theme outputs Product structured data in most themes; check yours. Filter and sort URLs change completely; do not try to redirect every filter combination, only the category pages. [What you can and cannot fix on Shopify](https://getreport.app/guides/shopify-what-you-can-and-cannot-fix) lists the platform's SEO limits.

**WordPress to Webflow.** Blog posts become CMS items under a collection path such as `/blog/{slug}`, so a WordPress blog that used `/{slug}/` at the root needs redirects for every post, which Webflow's pattern redirects can cover in one rule only if the old URLs share a folder. The [Webflow SEO settings guide](https://getreport.app/guides/webflow-performance-and-seo-settings) covers titles, sitemaps and canonicals there.

**Any CMS to headless.** You control the URLs completely, so keep them all. The risks move to rendering, the `<head>` output of each route, and redirects, which now have to be configured at the host.

## Common mistakes

- **Importing content and assuming metadata came with it.** Check titles and descriptions on staging, page by page for key pages.
- **Letting the new platform's defaults write every title.** A pattern is fine as a fallback, not as a replacement for pages that ranked.
- **Dropping old redirects** from the previous platform. Carry them across and point them at the final new URLs.
- **Redirecting everything to the new home page** because mapping was too much work.
- **Launching with staging protection on,** a `noindex` or a `Disallow: /`. Check within the hour.
- **Changing design, content and URLs in one launch** with no baseline, so nobody can say which change caused a drop.

## Questions people ask

### Will changing my CMS affect my SEO?

It can, in either direction. If URLs stay the same or redirect in one hop, and titles, content, internal links and structured data come across, rankings usually settle within a few weeks. Traffic drops when old URLs answer 404, metadata is lost in the import, templates get thinner, or the new site depends on JavaScript to show content.

### Do I need redirects if my slugs stay the same on the new platform?

Only if the full URL changes. A slug that stays `red-runner` but moves from `/shop/red-runner/` to `/products/red-runner` is a new URL, so it needs a 301. If the path, slug and trailing slash are identical, no redirect is needed. Compare full URLs in your map, not just slugs.

### How do I move SEO titles and descriptions from WordPress to another CMS?

Export them separately. SEO plugins such as Yoast SEO and Rank Math store titles and descriptions in their own fields, which standard content exports and many import apps skip. Crawl the old site to export each URL's title and description, then import them into the new platform's SEO fields, or check key pages by hand on staging.
