Automated WordPress to Sanity CMS Migration: A Zero-Downtime Blueprint in Next.js

Case Study & Engineering Blueprint: How I built a custom Node.js automation pipeline to transfer 200+ blog articles, stream featured images into Sanity's CDN, and preserve 100% of organic search authority during a Next.js App Router migration. Preview the live build on our staging environment at new.tribecadentalstudio.com!
The Challenge: Legacy Monolith vs. Modern Headless Architecture
When rebuilding the digital platform for Tribeca Dental Studio—a luxury multi-specialty dental practice in Lower Manhattan—we transitioned away from a legacy PHP/WordPress setup. Our goals were to leverage the performance of Next.js App Router and the editorial flexibility of Sanity CMS.
However, the practice had accumulated over 200 published blog articles, complete with featured images, meta tags, custom permalinks, and embedded HTML. Manually copy-pasting this content would have taken over 40 hours of manual labor and introduced human error.
To execute the migration efficiently, I engineered an automated Node.js script (import-wp.mjs). This pipeline fetched posts directly from the WordPress REST API (/wp-json/wp/v2/posts?_embed), sanitized legacy HTML strings, streamed featured media directly into Sanity's Asset CDN, and batch-created Sanity Studio documents—all in under two minutes.

Architectural Considerations
- Asset Pipeline Streaming: WordPress stores media links relative to local server paths (
/wp-content/uploads/). The script needed to fetch these remote images, convert them into binary buffers, and upload them directly into Sanity's Asset Pipeline. - Entity & String Sanitization: The WordPress REST API returns titles and excerpts filled with HTML entity codes (e.g.,
’,&). These required decoding and cleaning before document insertion. - SEO & Permastruct Preservation: Legacy blog posts lived on root-level paths (e.g.,
/crown-sensitive-to-cold-and-hot/). The new architecture needed dynamic routing or automated 301 redirects to ensure Google rankings remained untouched.
Terminal Commands & Execution
The entire migration process was executed locally via Node.js using terminal commands.
1. Set the Sanity Write Token
Configure your Sanity API Token as an environment variable (generated in the Sanity Dashboard under Settings $\rightarrow$ API $\rightarrow$ Tokens with Editor/Admin rights):
2. Execute the Migration Pipeline
Run the script directly from the root directory of your Next.js project:
3. Real-Time Terminal Output
Upon running the script, interactive terminal logs output real-time progress as each record is fetched, processed, and created in Sanity:
The Migration Script (import-wp.mjs)
Here is the Node.js automation script used to execute the dataset migration:
Results & Staging Preview
- Automation Efficiency: Transferred 200+ blog articles, meta tags, and media assets into Sanity's CDN in under 2 minutes.
- Zero SEO Loss: Kept legacy search authority intact while enabling Next.js static rendering for lightning-fast Core Web Vitals.
- Live Staging Build: Check out the migrated dataset and brand-new editorial layout live on our staging domain at new.tribecadentalstudio.com!
