Migrate from Shopify
Move a Shopify store to Modulify with its products, customers, full order history, content, translations, images and storefront pages, and see where each part lands in your new site.
On this page
A Shopify migration moves a store into a new Modulify site in one go. The catalog, the content, the customers and the full order history go into the site database, images and files go into the site storage, and the published storefront pages become pages of the site. This page explains how the migration works, how to run it, where each part of the store lands and what to do once it has finished. The import dialog itself is covered step by step in Import from Shopify.
Before you start
- You need the Shopify admin of the store, with permission to create apps in the organization that owns it. Shopify gives tokens only to an app created in the same organization as the store.
- Have the store address ready. It can be your own domain or the store's
myshopify.comaddress. - To have the published storefront pages copied as they are, the online store must not be password protected. When it is, the store data and the theme still come across, and the AI builds the pages from the theme instead, exactly as the theme has them.
- The migration only reads. Every scope it asks for is a read scope, so nothing in your store changes, and the store keeps running while you build the new site.
If the store already has a custom app made in the Shopify admin, you can use its Admin API access token instead of creating a new app. Shopify stopped creating these custom apps on January 1, 2026, and shows their token only once.
How the migration works
The migration runs in the background in seven parts:
- Connect. Modulify finds the store's
myshopify.comaddress, exchanges the Client ID and Client secret of your app for an access token, and keeps the token, the Client ID and the Client secret encrypted with your site, so the migration can refresh the token and run again. - Read the store data. The data is read through Shopify's Admin API. The largest parts (products, customers, orders, stock levels and collections) are requested as Shopify bulk exports, which Shopify prepares on its side. When Shopify does not start an export in time, that part is read page by page instead, so it still comes across. The live theme is read through the Admin API too: its Liquid templates, sections, snippets, settings and text, and its stylesheets, scripts, fonts and images.
- Read the storefront. The published pages of the online store are read with the theme's stylesheets, scripts and fonts.
- Copy images and files into the site storage, so the new site does not load them from Shopify.
- Save the data in the site database as it was, one dataset per kind of record, with the links between records and the translations, for the AI to build the tables from.
- Build the pages: one page per storefront page, the shared header and footer, working contact and newsletter forms, a sitemap and the store's redirects. The theme is saved next to them.
- Save the site, together with a guide (
SHOPIFY.md) and notes (.modulify/import/README.md) that tell the AI what came across.
While it runs, the site's chat shows the step it is on, and Did 5 actions when it is done. Right after, the AI builds the tables from the store data and connects the pages that show it. See How migrations work for the steps, the warnings and what the AI does next.
Run the migration
Create an app in Shopify
In your Shopify admin, go to Settings, then Apps, choose Develop apps, then Build apps in Dev Dashboard. Choose Create app, then Start from Dev Dashboard, give the app a name and choose Create.
Add the scopes and release the app
On the app's Versions page, add the scopes that the import dialog lists under Scopes to add, under Access. For App URL you can use https://shopify.dev/apps/default-app-home. Then choose Release. A scope you leave out only affects the data that needs it. Orders older than 60 days need read_all_orders as well as read_orders, translations need read_translations, and the theme needs read_themes.
Install the app on the store
Choose Install app, pick the store and choose Install.
Open the import
Click + on the prompt on Home and choose From Shopify under Import. Enter the store address in Store address.
Connect the store
Under Connect a Shopify app, paste the Client ID and Client secret from the Credentials card in the app's App settings, then select Connect. The dialog shows Shopify is connected, and any scope the app does not have is listed under Not granted, so these parts will not come across. If you waited too long, it shows Connection expired: select Start again and connect once more.
Start the migration
Tick I own this site, or I have permission to rebuild it. and select Confirm. The store shows as a card on the prompt, with a picture of it and what the import found. Select Import site to create the site and start the migration.
What comes across
The store data comes across as datasets, which the AI builds into tables right after the migration.
| In Shopify | In Modulify |
|---|---|
| Store details: name, contact email, currency, address, time zone, languages and store metafields | Store dataset |
| Products with description, images and videos, options and color swatches, tags, status, SEO and metafields | Products dataset |
| Variants with price, compare at price, SKU, barcode, weight, cost per item, country of origin, HS code and metafields | Product variants dataset, linked to their product |
| Stock at each location, and the locations | Stock levels and Locations datasets |
| Collections with their rules, image, SEO, metafields and product order | Collections dataset, linked to their products |
| Pages, blogs, blog posts and blog comments | Pages, Blogs, Blog posts and Blog comments datasets |
| Store policies | Policies dataset |
| Navigation menus with their nested items | Menus dataset |
| URL redirects | Redirects dataset, and redirects on the new site |
| Files: images, videos, documents and 3D models | Files dataset, with the files copied to the site storage |
| Custom data (metaobjects) | One dataset per custom data type |
| Customers with contact details, email and SMS marketing consent, addresses, tags and notes | Customers dataset |
| Orders with totals before and after changes, taxes, shipping, fulfillments with tracking, refunds and transactions | Orders dataset, linked to the customer |
| The items of each order with quantity, price, discounts and taxes | Order items dataset, linked to the order, product and variant |
| Draft orders | Draft orders dataset |
| Discounts with their codes, rules and use | Discounts dataset |
| Gift cards with their balance | Gift cards dataset |
| Translations of products, collections, pages, blogs, blog posts, policies and custom data | Kept with those records, by language |
| Published storefront pages with the theme's styles, scripts and fonts | Pages of the new site |
| The live theme: Liquid templates, sections, snippets, settings and text | Saved in the site at .modulify/import/theme, for the AI to build pages from |
| The theme's stylesheets, scripts, fonts and images | Copied to public/shopify/theme/assets |
| Contact and newsletter forms | Working forms that save to the site database |
One migration reads up to 5,000 products, and up to that many records of each other catalog and content dataset. It reads up to 10,000 customers, and up to that many orders, draft orders, blog comments and gift cards. It copies up to 300 storefront pages and up to 20,000 images and files. Anything past those limits is named in the warnings.
How the data is stored
The migration does not create tables. The store data waits in the hidden _import_rows table of the site database, one dataset per kind of record, and the AI builds the tables from it as soon as the migration finishes, as How migrations work describes. It picks the names of the tables and columns itself, and the tables show up in the CMS, where _import_rows stays hidden.
- Every record keeps its Shopify id in
id, a record with a Shopify handle keeps it inslug, anddataholds its fields as JSON. - Records point at each other by Shopify id. A variant holds the id of its product, an order the id of its customer, an order item the ids of its order, product and variant, a stock level the ids of its variant and location, and a blog post the id of its blog. A collection lists the ids of its products, and its
product_orderfield keeps the order the store showed them in. - Money fields are numbers in the store currency, with the currency in
currency. An order also keeps every amount in both the store currency and the customer's currency intotals. The store record keeps how the store writes prices inmoney_formatandmoney_with_currency_format, and a variant sold by weight, volume or length keeps its unit price inunit_priceandunit_price_measurement. - A metafield that has a definition in Shopify has its own field. Every other metafield is kept in a
metafieldsfield, keyed by namespace and key. - Rich text is HTML, and dates are in UTC.
shopify_created_atandshopify_updated_atkeep the dates from Shopify. - Image and file fields hold the address of the copy in the site storage. A file that could not be copied still points to Shopify. The warnings say how many there are, the notes list them, and the AI copies them when it takes over.
- A store with more than one language keeps the translations with each record under
_translations, keyed by language code and then by field, and the site's languages are declared. The AI gives the tables a column per language for them, as Multiple languages describes.
The migration also saves a guide called SHOPIFY.md at the root of the site. It lists every dataset with its row count, how the datasets link, where the copied pages, the theme and the styles live and what did not come across, and the site chat is told to read it before building on the store. You can open it like any other file.
Customers, orders, draft orders, gift cards and blog comments contain personal data of your customers. They are stored in your site's database, and the AI builds their tables from the list of their fields without reading them. Keep them out of public pages, and only show them to people who are allowed to see them. On some Shopify plans, Shopify hides customer names, emails, phone numbers and addresses from apps, and the migration says when they were hidden.
What does not come across
Some things never leave Shopify:
- Customer passwords, saved payment methods and full gift card codes. Shopify never gives them out, so a gift card keeps only its last characters.
- The cart, the checkout, search and customer accounts, which run on Shopify itself. The copied pages show them, but they do not work until they are rebuilt.
- Shopify apps, and the data an app keeps on its own servers, such as reviews in many review apps. Apps on the storefront are not copied, because they run on Shopify.
Some parts of the store are not part of a migration yet: shipping and tax settings, store credit, returns, abandoned checkouts, customer segments, subscriptions, B2B companies and price lists. Theme app extensions, the app blocks in a theme, run on Shopify and do not come across. The copied pages, menus and product options are in the store's primary language, and only the first page of a collection or blog is copied.
After the migration
When the migration finishes, the AI takes over on its own. It reads the guide and the notes, builds the tables the store needs from the store data, connects the pages that show that data to those tables while keeping them looking the same, and checks the pages. When no storefront pages could be copied, it builds them from your theme instead, exactly as the theme has them, and it never applies a design of its own. Then it answers with what came across, including the tables it built with their row counts, and what still needs work. If you were already chatting, it gets the same details with your next message instead. From then on the chat builds on the imported store and never starts it over, and when it needs more it reads your storefront directly.
- Read the warnings under Warnings from the import. Each one says what did not come across and, where you can fix it, how.
- Click through the pages in the preview. The copied pages start as snapshots of the store, so a product, collection or blog page that does not read its table yet shows the store as it was.
- Ask the chat to connect any page that still shows the store as it was, for example to have the product pages read the tables of products and variants, so a change in the CMS shows on the site.
- Decide how you sell. The checkout stays on Shopify until you replace it: ask the chat to build a cart and checkout with a payment provider, or keep linking to your Shopify store for now.
- Check the forms by sending a test message from the contact page.
- Check the fonts. Theme fonts are copied with the pages and the theme, and fonts from the Shopify font library are licensed for Shopify stores, so check their license before you publish.
- Publish the site and connect your domain. The store's redirects carry over, so old links keep working.
- Keep your Shopify store open until your domain points to Modulify. You can uninstall the Shopify app once the migration has finished.
Troubleshooting
Shopify says it only gives tokens to an app in the same organization
The message is Shopify only gives tokens to an app created in the same organization as the store. Create the app in the Dev Dashboard of the organization that owns this store! Create the app from the Dev Dashboard of the organization that owns the store, then connect again.
The app is not installed on the store
The message is The app is not installed on this store yet. Install it on the store from the Dev Dashboard, then connect again! Choose Install app in the Dev Dashboard, pick the store and connect again.
Shopify does not accept the Client ID and Client secret
The message is Shopify did not accept the Client ID and Client secret. Copy both again from the app settings in the Dev Dashboard! Copy both values again from the Credentials card in App settings, without spaces.
Shopify cannot find the store
The message is Shopify could not find that store. Check the store address and try again! Enter the store's myshopify.com address, which the Shopify admin shows under Settings, then Domains.
Only recent orders came across
The app does not have read_all_orders, so Shopify gave only the orders from the last 60 days. Add the scope to a new version of the app, release it and run the migration again into a new site.
Customer names and emails are empty
Shopify hid the customers' personal data from the app, which it does on some plans. The rest of each customer, such as their orders and totals, still comes across.
No store pages were copied
The online store is password protected, so its published pages could not be copied. When the app has read_themes, the AI builds the pages from your theme instead, exactly as the theme has them. To have the published pages copied as they are, remove the password in Shopify, then run the migration again into a new site. The store data comes across either way.
The theme did not come across
The app does not have read_themes. Add the scope to a new version of the app, release it and run the migration again into a new site.
Some images still load from Shopify
They could not be copied, or the store has more images and files than one migration copies. They keep working from Shopify. The AI copies the ones that failed when it takes over, and you can ask the chat to move the rest.
A warning says "The imported data could not be saved in the site database"
The store data could not be saved for the AI. It reads the products, collections, pages, blog posts and menus again from your storefront to build their tables. Customers, orders and the other store data cannot be read that way, so run the migration again into a new site to bring them across.