# How migrations work

Source: https://modulify.ai/docs/migrate/overview

Move an existing site or store to Modulify in one go, follow the migration while it runs, and finish the move once it is done.

A migration moves an existing site or store into a new Modulify site in one go. You connect the platform it lives on, and Modulify reads it, copies it and builds a new site from it in the background. The site you get is a normal Modulify site: you change it with the AI, publish it and put your own domain on it like any other.

## What a migration does

A migration reads your site with the access you give it, then rebuilds it on Modulify. Depending on the platform, it:

- Saves your content and records, such as products, blog posts and CMS items, in the site database as they were. Right after the migration, the AI builds tables from them, and the tables show up in the [CMS](https://modulify.ai/docs/data/cms).
- Copies your images and files into the site [storage](https://modulify.ai/docs/data/storage), so the new site does not load them from the old platform.
- Copies your published pages as pages of the new site, with their styles and fonts.
- Keeps your redirects, so old links still lead somewhere.

Each platform page below lists exactly what comes across from that platform and where it lands.

## Start a migration

Click **+** on the prompt on Home, and under **Import** choose the platform your site is on. The import dialog asks for the site's address and for access to it, and you confirm that you may rebuild the site by ticking **I own this site, or I have permission to rebuild it.** A migration always starts a new site, so inside a project's chat the migration options under **Import** are greyed out. When the dialog cannot read the site or check its access because the site or the platform did not answer or is busy, it says so with a **Try again** button, so you can check again without changing what you entered.

You can also start on modulify.ai before you have an account. [modulify.ai/migrate](https://modulify.ai/migrate) has a page for each platform, such as [modulify.ai/migrate/webflow](https://modulify.ai/migrate/webflow). Type your site's address and choose **Preview my site** to see a picture of the site and the platform it is on, then choose **Import this site**. Home opens the import dialog for that platform with the address already filled in, once you have logged in or signed up. When the site is on another platform than the page's, the preview says which one, and **Import this site** opens that platform's dialog. The page's other buttons, such as **Import my Webflow site**, open the same dialog without an address. The page address keeps the site as `?site=`, so `https://modulify.ai/migrate/webflow?site=yoursite.webflow.io` previews it straight away.

The dialog and the card on the prompt show a picture of the site. When the platform makes one of the site itself, as Webflow does, that picture is used, so it shows the design even when the site asks for a password. Otherwise it is a screenshot of the published home page. When that home page is a password page on Shopify, Webflow or Wix, no screenshot is taken: the card shows the image the site uses when it is shared instead, or no picture when it has none, and the dialog warns that the home page asks for a password and what that means for the migration. While the migration runs, the new site's card on your dashboard shows the same picture, until the first preview of the new site replaces it.

## While it runs

The migration shows in the new site's chat as a normal message. While it runs, the message reads `Importing <site name> from <platform>. The AI takes over as soon as it finishes.`, and a row under it shows the step it is on with a count such as **2/5**. Select the row to open the activity panel with every step in order:

| Step | What happens |
| --- | --- |
| **Reading the site** | The content and records are read from the platform |
| **Copying images** | Images and files are copied into the site storage |
| **Saving the data for the AI** | The records are saved in the site database, for the AI to build its tables from |
| **Building pages** | The published pages are turned into pages of the new site |
| **Saving pages** | Everything is saved to the site |

While a step works through a list, its row counts it. **Reading the site** counts the pages it has read, such as **Reading the site (120 of 480 pages)**, **Copying images** counts the images and files, such as **Copying images (340 of 2,100)**, and **Saving the data for the AI** counts the records. On Webflow the number of pages can grow while the step runs, as the migration finds the pages of CMS items.

When it is done, the message reads `Imported <site name> from <platform>.` and the row reads **Did 5 actions**. Anything that did not fully come across is listed under **Warnings from the import**, each with the reason.

If the migration stops for a reason that is not yours to fix, such as a step that ran too long or pages that could not be saved, it starts again on its own once, and the message adds `The first try stopped, so the import started again on its own.` This happens once for each try, the first one and each one you start with **Try again**. A migration cut off while Modulify's servers restart for an update starts again on its own as well, and that does not count as its one restart. The same message shows in the main chat of the site in the mobile app.

If it stops again, or stops for a reason you have to fix first, such as a connection that is missing or no longer accepted, or a site that is not published, the message reads `The import of <site name> from <platform> stopped.`, the row shows the step it stopped at, and an alert under it gives the reason. Once the reason is fixed, choose **Try again** in the alert to run the migration again. It uses the connection the site already has, so you do not connect again, and it replaces what the failed run created.

When the old site does not answer, is busy, or answers with an error on its side, the migration asks again a few times before it moves on. It does this for every page, image, font and file it copies, and for each request to Webflow, Framer, Wix and Shopify. A migration that stops making progress, or runs for too long, starts again on its own once. If that try stops too, it ends with "The import stopped before it finished" or "The import took longer than an import is allowed to run, so it was stopped before it finished", and you choose **Try again** to run it once more. An image or file that takes too long to copy is skipped and keeps loading from the old site, with a warning, so one slow file does not hold the rest up.

## When it finishes

As soon as a migration finishes, the AI takes the site over in the same chat on its own. The automatic message that starts it is not shown, so the migration flows straight into the AI's answer. The AI reads the migration's notes, builds the tables the site needs from your records and fills them, connects the pages that show that data, such as a blog list or the copied CMS item pages, to those tables while keeping them looking the same, copies into the site storage any images and files the migration could not copy, and checks the pages. It then answers with what came across, listing the pages, the tables it built with their row counts, the languages and the warnings, and with what still needs work.

The site keeps looking and working exactly like the original. The AI never applies a design of its own to a migrated site, and it changes how a page looks only when you ask it to. When pages did not come across, it rebuilds them exactly as the original had them from what the migration saved, such as your Shopify theme, and when nothing was saved to rebuild them from, it asks you first.

If you were already chatting, the chat gets the same details with your next message instead. While a migration is still running, the chat tells you so and waits before changing files, and once it is done the chat builds on the migrated site instead of starting it over. The migration saves notes for the chat in the site's code at `.modulify/import/README.md`, and when the chat needs more than the notes, it reads the old site directly.

## How your records become tables

A migration does not create tables itself. It saves every record it reads, such as a CMS item, a product, an order or a form submission, as it was in one hidden table of the site database, `_import_rows`, with one row per record:

| Column | What it holds |
| --- | --- |
| `dataset` | The collection or kind of record it belongs to |
| `id` | Its id on the old platform |
| `slug` | Its slug |
| `data` | Its fields, as a JSON object |

In `data`, a link to another record holds that record's id on the old platform, and a list of links is a JSON array of ids. An image or file holds its address, or an object whose `url` is the address. Translations are under `_translations`, keyed by language code and then by field, and `_created`, `_updated` and `_published` keep the original dates. A CMS item that was a draft or archived on the old platform has `_draft` or `_archived` set, and gets no page of its own. `_import_rows` is hidden in the [CMS](https://modulify.ai/docs/data/cms) unless you turn on **Show system collections**.

The AI builds the tables from these records with its usual database tools, the same way it builds any table, so the CMS shows them properly: links between records become references between tables, translated fields get a column for each language, and a field that was required on the old platform stays required when every record has a value for it. It usually builds one table for each collection or kind of record, and it picks the names of the tables and columns itself. For records that hold personal data, such as customers, orders and form submissions, it builds the table from the list of fields without reading the records. Each platform page says which records those are. The AI leaves `_import_rows` in place, so a table can be filled from it again.

The migration notes have a section named after the platform, such as "Data from Webflow", that lists every dataset with how many items it holds, its fields, which datasets its links point to and whether it holds personal data. If the records could not be saved, the migration warns "The imported data could not be saved in the site database, so the AI can only build the tables from what it reads again from the original site."

## After a migration

- Read the warnings first. Each one says what did not come across and, where you can fix it, how.
- Click through the pages in the [preview](https://modulify.ai/docs/editor/preview) and compare them with the old site.
- Check the tables the AI built in the [CMS](https://modulify.ai/docs/data/cms). If the site needs a table the AI did not build, ask the chat for it.
- Ask the chat to build what the old platform did for you at runtime, such as a cart, a checkout, search or member accounts. The copied pages show these parts, but they do not work until they are rebuilt.
- [Publish](https://modulify.ai/docs/publish/publish-a-site) the site and [connect your domain](https://modulify.ai/docs/publish/custom-domains). Keep the old site live until your domain points to Modulify.

## Pick your platform

- [Migrate from Shopify](https://modulify.ai/docs/migrate/shopify): Products, customers, full order history, content, translations, images and storefront pages.

- [Migrate from Webflow](https://modulify.ai/docs/migrate/webflow): Pages and styles, CMS collections and items, products, languages, forms and redirects.

- [Migrate from Framer](https://modulify.ai/docs/migrate/framer): Pages, CMS collections and items, images, fonts, languages, forms and redirects.

- [Migrate from Wix](https://modulify.ai/docs/migrate/wix): Pages and design, CMS collections, store, blog, bookings, events, contacts, orders and files.

To start a site from the code in a GitHub repository instead, see [Import from GitHub](https://modulify.ai/docs/build/import-from-github).