Southern Sparkle Design: Wix to WordPress

Southern Sparkle Design (southernsparkledesign.com) is a friend’s small business making custom homecoming mums and garters in Dallas–Fort Worth. Its site ran on Wix. I am moving it to WordPress: the whole site rebuilt page for page, kept in git, and previewed on a staging address before the real domain moves.

The problem

A Wix site can’t be checked into a repository. Content, look and apps live in Wix’s dashboard. Before rebuilding it I had to learn what it ran on. Seen from outside, the store could have been Wix Stores or Ecwid embedded in Wix, and that decided whether products, orders and payments had to be migrated or could stay put. The site also used Wix Bookings, Forms, Members and Pro Gallery, and had several pages nothing linked to. The owner’s text had to arrive unchanged: a move, not a rewrite.

What I built

  • An inventory of the Wix site, built by a real-browser crawl with Playwright: 423 URLs, 391 of them under the online store. It records the pages, an old-to-new URL map, public store fields, the apps in use and the measured design.
  • A custom block theme with no parent theme and no page builder. Its colours are that measurement, and both Wix fonts, Playfair Display and Lato, are open-licence, so they are bundled unchanged.
  • Every page as block markup in the repo, seventeen pages with the owner’s text copied verbatim.
  • A small site plugin holding the contact form, the redirects for old Wix addresses, and each page’s search title, description, link preview, site icon and structured data.
  • An idempotent deploy script, and a check script that tests every page, the menu, the store, every old Wix address and the links.

How it works

It is one more site on my WordPress multisite, beside angelulz.com and merryonmaintx.com: public, but marked noindex so it can’t compete with the live Wix site in search.

The crawl answered the store question: the requests went to Ecwid, and the store id was in every product image URL. So the real store runs on the preview through Ecwid’s WordPress plugin, wired in by that id, and every old store address still answers at the same path. The contact form keeps each message on the site and mails it through the network’s Amazon SES route, behind spam checks that include Akismet.

The deploy runs WordPress’s command-line tools in a throwaway container: it installs the theme and plugin, imports media keyed by sha256 so duplicates collapse, upserts pages and purges the page cache. A second run must change nothing. WebP images and correct gallery sizes took the home page on a phone down to 3.8 MB, where it had been 8.9 MB.

Decisions and trade-offs

  • Keep Ecwid instead of moving to WooCommerce. WooCommerce would have meant a product import, new payments and new store URLs; with Ecwid only the layout moves. The cost is a dependency on the store’s Ecwid plan, which has to move off Wix before Wix is cancelled.
  • A custom block theme in git instead of a builder or a third-party theme. Everything deploys from the repo and can be rebuilt with nothing else. The price is that the owner can’t restyle the site through a builder, and the owner’s edits and the repo can disagree.
  • Never overwrite a page the owner edited. The deploy records what it wrote to each page, leaves a page changed since then alone, and stops until the repo takes the edit or it is replaced on purpose. I gave up the simpler “the repo always wins”. A side effect: WordPress rewrites every image tag on save, so one save of an unchanged page marks it edited.
  • A hosted scheduler instead of a booking plugin. Wix Bookings is being replaced by a hosted appointment scheduler, so there is less to run on my server. Until those exist, the Book buttons go to Consultation or Contact.

What’s next

Phases 1, 2, 4 and 5 are done: the preview, the store, the form, the redirects and the search details. Still open: the owner’s review of the preview; the cutover, which moves DNS off Wix with the business’s mail records copied first, maps the domain, lifts noindex and settles one old gallery address the server refuses to forward; and the handover, which decides which pages the owner edits in WordPress. Where the site is hosted long term is the owner’s decision.

Built with

WordPress multisite, a custom block theme, PHP, Python, Node and Playwright, bash, Ecwid, Amazon SES, Akismet, nginx, Traefik, Docker, Cloudflare.