Skip to content
Migration Service

WordPress Multisite Migration to Next.js

  • Spawns 250+ prefixed tables for a 25-site network with no cross-site querying built in
  • Stores serialized data in wp_options and wp_postmeta that breaks on URL or domain migrations
  • Shares one user table with serialized per-site capabilities that fragment during plugin updates
  • Breaks all subsites simultaneously when a network-activated plugin ships an incompatible update
  • Delivers Lighthouse mobile scores of 35–55 due to serialized data parsing overhead
  • Slows page loads 40–60% compared to standalone WordPress from table-join complexity
  • Ships one Next.js codebase with route-based multi-tenancy serving unlimited locations from a single deploy
  • Enforces data isolation at the database layer with Supabase RLS policies -- no app-code authorization bugs
  • Achieves Lighthouse mobile scores of 95–100 and TTFB under 300ms via Vercel Edge and static generation
  • Replaces WordPress network admin with a modern per-location content dashboard your team learns in one session
  • Cuts hosting costs 60–80% by replacing managed Multisite plans with Vercel + Supabase free or pro tiers
  • Eliminates network-wide plugin failures -- per-location content updates deploy independently with zero risk

WordPress multisite migration is what we call the process of moving a WordPress Multisite network -- prefixed tables, serialized options, shared users and all -- onto a single Next.js and Supabase application, with Row Level Security enforcing per-location data isolation instead of shared database tables. We build this for platform operators running networks of 5 to 80+ subsites who've hit the point where wp_2_posts, wp_3_posts and wp_4_posts multiplying faster than queries can handle stops being a joke about database sprawl and becomes an actual outage risk. Here's what changes: every subsite's prefixed tables get extracted and mapped to a location_id, serialized data in wp_options and wp_postmeta gets properly deserialized rather than string-replaced, and the shared wp_users table with its per-site capability blobs gets rebuilt as a clean role model in Supabase Auth. What we end up with is one codebase serving unlimited locations, RLS policies doing the isolation work the database layer should've been doing all along, and a per-location dashboard replacing WordPress's network admin switcher. Timeline runs from 4-6 weeks for a 5-10 subsite network up to 10-16 weeks for 50+ subsites with heavy custom integrations -- we start every engagement with an audit of wp_blogs and every subsite's plugin footprint so we can scope it properly. Pricing is fixed-fee, quoted after that audit; see /pricing/ for how we structure it. This isn't a lift-and-shift. It's a rebuild of the isolation model Multisite never had, using tools -- Supabase RLS, Next.js route-based tenancy -- that didn't exist when Multisite shipped.

Who This Is For (and When It's the Wrong Call)

We take this migration on when there's a real network behind it: a franchise operation, a multi-location service business, an agency-managed portfolio of client sites, or a directory that's outgrown a single WordPress install. If you're staring at 25+ subsites and your database has crossed into three-digit table counts, you're who we're writing this for. We've written more on why Multisite's architecture breaks down at that scale in WordPress Multisite Isn't Multi-Site Architecture.

We'll tell you when it's the wrong call, too. If your network is 2-3 subsites with minimal content and no growth plans, the migration cost won't pay back -- just tidy up what you've got. If you depend on a specific WordPress plugin ecosystem with no equivalent (some niche booking or membership plugins genuinely don't have a clean headless replacement), scope that dependency before you commit, not after. And if you can't tolerate any downtime or SEO risk in the next quarter, this needs more lead time than a rushed migration allows -- rebuilding a redirect map for 80 subsites properly takes real weeks, not a weekend.

How We Do It

The process runs in phases, and the timeline scales with subsite count -- a 5-10 subsite network moves faster than an 80-subsite one, but the steps stay the same.

Audit (1-2 weeks). We query wp_blogs to enumerate every subsite, then crawl each one to inventory content volume, plugins, custom post types and domain mapping. What comes out is a migration specification with a subsite-by-subsite content breakdown.

Architecture design (1 week). We design the Supabase schema -- a locations table, content tables with location_id foreign keys, RLS policies per table -- and map the Next.js route structure. Every old URL gets mapped to its new equivalent before we write a line of migration code.

Content export (1-2 weeks). Standard content comes through the WP REST API. Everything the API can't surface -- ACF fields, custom plugin tables, serialized options -- comes through direct SQL against the prefixed tables. We run serialized strings through phpserialize rather than find-and-replace, because a naive string swap corrupts the length prefixes and breaks the whole option set. We've seen it happen; it's not a risk worth taking.

Build (2-6 weeks). The Next.js application takes shape here: route-based tenancy, RLS-enforced Supabase tables, a per-location admin dashboard. This is the phase where the timeline flexes most -- a network with standard pages and no custom integrations moves through it fast; one with booking systems and membership areas doesn't, and we don't pretend otherwise.

Content import (1-2 weeks). Batch import maps every wp_2_ prefixed table to location_id 2, and so on. Media URLs get rewritten to Supabase Storage paths. WordPress password hashes migrate to Supabase Auth and rehash on first login, so nobody has to reset a password.

Redirect mapping and launch (1-2 weeks). Every URL across every domain gets a 301. New sitemaps go to Google Search Console per former domain. We monitor indexing and Core Web Vitals for 30 days before we let the old hosting go.

Here's what you get at the end: a single Next.js codebase, a Supabase schema with RLS policies doing the tenant isolation, a content dashboard your team can learn in a session, a full redirect map, and 30 days of post-launch monitoring.

What We've Shipped

We've taken this pattern from WordPress into production more than once, and the results hold up.

SleepDr.com, a sleep medicine practice, moved from WordPress to Next.js 15 with Payload CMS and Supabase, with a HIPAA-safe architecture (patient forms handled via HIPAA-compliant Jotform, no PHI touching our servers), medical schema markup, 20 city landing pages and four-language support. Lighthouse went from 35 to 94 -- that's the exact range of scores we see on Multisite networks buried under serialized-data overhead, and we fix it the same way every time: strip the parsing weight, ship static where you can.

Not Another Sunday, a global coffee, pub and restaurant directory, runs on Next.js 15, Supabase and Vercel with 137,000 listings and 10,500 coffees ranked by a custom quality score, hundreds of programmatic SEO pages, and a crawl-budget strategy that keeps thin pages out of the index. It's the same route-based, database-driven pattern a multisite migration needs at scale -- one codebase serving thousands of location-equivalent pages instead of hundreds of WordPress database tables doing the same job worse.

Sources

Our redirect strategy follows Google's own guidance on 301 redirects and consolidating duplicate URLs -- both matter when you're mapping dozens of domains at once. The Lighthouse and Core Web Vitals targets we design against come from web.dev's Vitals documentation. We build the route-based tenancy pattern on the Next.js App Router.

Next Step

If your network's past the point where you can keep patching around prefixed tables and serialized data, get in touch and we'll scope an audit. See /pricing/ for how fixed-fee engagements are structured, or contact us directly to talk through your network's specifics.

How It Works

The migration process

01

Discovery & Audit

We map every page, post, media file, redirect, and plugin. Nothing gets missed.

02

Architecture Plan

New stack designed for your content structure, SEO requirements, and performance targets.

03

Staged Migration

Content migrated in batches. Each batch verified before the next begins.

04

SEO Preservation

301 redirects, canonical tags, sitemap, robots.txt — every ranking signal carried over.

05

Launch & Monitor

DNS cutover with zero downtime. 30-day monitoring period included.

Before vs After

WordPress Multisite vs Next.js + Supabase

Metric WordPress Multisite Next.js + Supabase
Lighthouse Mobile 35-55 95-100
TTFB 1.8-3.5s <0.3s
Database Tables (25 sites) 250+ 15-20 with RLS
Hosting Cost $200-800/mo $40-100/mo
Deploy Risk Network-wide outage from one plugin Atomic deploys with instant rollback
Cross-Site Query Custom SQL unions across prefixed tables Single query with location_id filter
FAQ

Common questions

How do you handle WordPress Multisite prefixed tables during migration?

Each subsite's prefixed tables like wp_2_posts and wp_3_options are queried directly and mapped to a location_id in Supabase rather than pulled through the WordPress REST API, because the API can't reliably surface complex data such as ACF fields and serialized postmeta. Losing content during that extraction isn't a risk we're willing to take, so direct SQL wins every time.

What happens to serialized data during a WordPress Multisite migration?

Serialized data in wp_options and wp_postmeta is deserialized with PHP's unserialize() or Python's phpserialize library, updated in place -- domain references, embedded URLs, configuration values -- then re-serialized and validated before anything touches Supabase, because a plain find-and-replace on those strings corrupts the length prefixes and breaks the whole option set. We've seen the naive approach break entire networks; proper deserialization is the only safe path.

How does Supabase Row Level Security replace Multisite's site isolation model?

Every content row in Supabase carries a location_id, and RLS policies enforce that authenticated users only access rows matching their assigned locations, so location managers see their own content and network admins see everything, with the isolation enforced at the database query level instead of application code. No application code can bypass it, which closes off a whole category of multi-tenant authorization bugs.

Do users need to reset passwords after a Multisite migration to Next.js?

No -- WordPress password hashes migrate directly into Supabase Auth, and bcrypt rehashing happens transparently the first time each user logs in, so people sign in with their existing credentials while the system upgrades the hash quietly in the background without any disruption to their workflow. There's no password reset email and no forced re-authentication step.

How long does a WordPress Multisite to Next.js migration take?

Timeline scales with network size: a 5-10 subsite network runs 4-6 weeks, a 10-25 subsite network runs 6-8 weeks, a 25-50 subsite network runs 8-12 weeks, and a 50+ subsite enterprise network with complex integrations runs 10-16 weeks, with every phase scoped precisely before work begins. Every engagement starts with an audit so we can scope it accurately before quoting a fixed fee.

Can we migrate WordPress Multisite subsites incrementally instead of all at once?

Yes -- subsites can migrate in batches, launching high-priority locations first while others stay on WordPress, with the Next.js application handling migrated locations natively while proxying or redirecting unmigrated ones until they're ready, which reduces overall launch risk significantly for large networks. It typically adds 2-4 weeks to the total timeline.

Ready to migrate?

Free assessment. We'll audit your current site and give you a clear migration plan — no commitment.

Get your free assessment →
Get in touch

Let's build
something together.

Whether it's a migration, a new build, or an SEO challenge — the Social Animal team would love to hear from you.

Get in touch →