Browse the docs ▾

Tutorials

Move a site or catalogue to Opmiz

Bring posts and products across in bulk, keep old addresses where you can, and give the owner a list for the rest.

The brief: "Move my 300-post WordPress blog and my 200-product shop to Opmiz."
You'll end with the content and catalogue on Opmiz, ready to publish, a matching design in the draft, and a list of old addresses for the owner.

What moves, and how

Posts and pages

import_items. Can keep their old addresses.

Tag or category pages

add_tag_page, then preview_tag_pages. Can keep their old addresses.

Products

import_products. Their addresses are /l/<name>/<listing_id>, so old ones need redirects.

Images

Copied in from https addresses during an import.

Design

Rebuild it with ops. There is no theme or site importer. See Build a site from a screenshot or design.

Customers, past orders, passwords

Not available through the tools. Agree with the owner what happens to these before you start.

Domain and payments

The owner does these in the dashboard, last.

1. Get the source data

Work from an export, a public feed or the API of the old platform, with the owner's permission. Scripts on your own machine can turn it into rows, and the words need not pass through the conversation. Check that the plan covers the product count, and note the old site's URL pattern.

2. Create the structure first

Rows must fit what exists, so before the import make the content type with add_item_page, its fields with preview_content_fields, and any product category fields with add_category_fields. The CMS tutorial gives the order. Add a date field, as imports don't carry dates otherwise.

3. Prepare the rows

Addresses

A slug starting with / puts an item at exactly that address, up to three parts: /snacks/poha-3. One content type can hold items under many first parts.

Links

Rewrite links between posts to their new addresses before you send them.

Keys

Give every row an idempotency_key, such as its id on the old site. A retry within a day then returns what was already made instead of duplicating it, so finish a move's imports promptly.

HTML

Set body_format: "html" for posts already in HTML. Product description is plain words, and HTML belongs in specifications.

Images

https only. http:// images in a body are refused, so upgrade or re-host them.

4. Do a dry run, then a small batch

Call the import tool without items to get an upload link, then send the file with the curl -T command it gives. Do it first with dry_run: true, which checks every row and fetches no images. Each link takes one file, so call again for a new link. Next, import about ten real rows and look at them before sending the rest.

5. Import everything

One import runs at a time per business. Poll get_import with limit: 0 while it runs, then only: "failed" to see what failed. Fix those rows and send them again with the same keys.

6. Build the lists and tag pages

Sort by the date field, as newest only follows the order items were made. Then add a tag page and save up to 100 tag addresses per call.

7. Recreate the design

Take screenshots of the old site as a reference, if it's the owner's. Work through the design tutorial on the draft.

8. Publish in the right order

Everything stays out of sight until now. Publish with one token per import: preview_item_publish {import_id}, then publish_item. Imports over 20 items continue in the background, and get_import shows progress. Then preview_site_publish and publish_site. Do all of this after the owner's yes. If the site is already live, publish catalogue and design together so that visitors don't see a mix of old pages and new products.

9. Hand over redirects and the domain

Apps can't add redirects, so give the owner a list of each old address and its new one, for Site › Domain in the dashboard. They should connect the domain last, once they've checked the site on its Opmiz address. A custom domain needs a paid plan that includes it.
Check a sample of old links on the new site before the domain moves. Search rankings depend on old addresses continuing to work.

One row for import_items (NDJSON)

{ "idempotency_key": "wp-1841",
  "title": "Quick poha",
  "slug": "/snacks/poha-3",
  "summary": "Ready in fifteen minutes.",
  "body": "<p>Rinse the poha …</p>",
  "body_format": "html",
  "tags": ["Snacks"],
  "cover_url": "https://old.example/p.jpg",
  "fields": {
    "published_on": "2023-07-16" } }

Send the file

import_items {
  "org_id": 1042,
  "content_type_id": 402,
  "dry_run": true }

→ an upload link and a curl command

curl -T posts.ndjson "<the link>"

get_import {
  "org_id": 1042,
  "import_id": 88,
  "only": "failed" }

For the owner

Old address        → New address
/products/kurta-m  → /l/kurta/4821
/about-us/         → /about

Please add these in Site › Domain.