WordPress to Next.js + Directus: Real Production Migration with Code Examples

After 12 months running a multi-city event platform (400+ content items, 15 city sites, multi-tenant architecture) on both WordPress and Next.js + Directus, here's the comprehensive technical comparison validated with industry data: performance benchmarks, security statistics, real case studies (Smashing Magazine, 10Clouds, LiveChat), SEO impact analysis, and production challenges with solutions.
What's Inside:
- WordPress 2025: Real stats (13.25s mobile, 5,948 vulnerabilities, 60% issues from plugins)
- Next.js production: 5x faster validated, 15-25% traffic increase, ROI in 6-12 months
- Directus deep-dive: Self-hosted benefits, TypeScript integration, real production experience
- Directus limitations: Image upload issues, UI config complexity, duplication bugs, environment sync
- SEO comparison: Core Web Vitals impact, mobile performance gap, ranking factors
- Industry case studies: 800ms → 80ms (Smashing), +25% traffic (10Clouds)
- Migration patterns: 5-10x speed gains, 50-75% less maintenance, proven timelines
- Technical implementation: Snapshots, types, SDK, permissions (156 rules), Docker gotchas
- Decision framework: When to choose each stack (backed by 30+ sources)
The Migration Context
What We Built:
- Multi-city event platform (15 independent city sites)
- 400+ content items with streaming media
- Event management across 15 independent cities
- Accessibility-first (WCAG 2.1 Level AA required)
- Previous tech: WordPress Multisite
Why We Migrated:
WordPress Multisite was becoming a maintenance burden with plugin conflicts, performance issues, and complex permission management across city teams.
Part 1: WordPress in 2025
What WordPress Does Really Well
1. Content Management is Instant
- Gutenberg editor: visual, intuitive, zero learning curve
- Non-technical editors productive in 5 minutes
- 60,000+ plugins for almost any feature
- Themes for quick design implementation
- Shared hosting: $5-30/month
2. Ecosystem is Unmatched
- SEO plugins (Yoast, Rank Math)
- E-commerce (WooCommerce)
- Forms, galleries, everything you need
- Community support everywhere
- WordPress.com for managed hosting
3. When WordPress Makes Perfect Sense
- Small business websites (5-20 pages)
- Blogs and content-first sites
- Non-technical team managing content
- Budget under $5K
- Need to launch quickly (1-2 weeks)
Where WordPress Struggles
1. Performance Ceiling
- Page loads: 3-5 seconds (even with caching)
- Database queries multiply with plugins
- PHP execution overhead on every request
- Difficult to achieve Lighthouse 90+ scores
Our WordPress Stats:
- Average page load: 4.2 seconds
- Lighthouse performance: 65/100
- Database queries per page: 80-120
- Time to Interactive: 6+ seconds
Industry Benchmarks (2025):
- WordPress average: 2.5s desktop, 13.25s mobile
- Only 57.8% of WordPress sites meet Google's LCP threshold (<2.5s)
- Mobile performance is 5x slower than desktop
- Our 4.2s is on the slower end, typical for multisite with plugins
2. Multisite Complexity
- Plugin compatibility nightmares
- Shared database = performance bottleneck
- Permission management across sites is painful
- Backup/restore complexity
- Updates break things regularly
Multisite Statistics:
- 30% of sites experience conflicts after updates (2023 data)
- Many plugins lack multisite compatibility testing
- Sites with 20+ plugins: 50% higher likelihood of performance issues
- 60% of WordPress issues stem from plugin conflicts
3. Maintenance Burden
- Weekly plugin updates
- Security patches (WordPress is a top attack target)
- PHP version compatibility issues
- Database optimization needed regularly
- Broken site after updates (happened 3 times)
- Regular maintenance required for optimal performance
Security Reality (2023-2024):
- 5,948 new vulnerabilities disclosed (24% increase from 2022)
- 93.25% originate from plugins, only 1.29% from WordPress core
- 31% are Critical/High severity requiring immediate attention
- XSS accounts for 50% of vulnerabilities, CSRF 15%, SQL injection 2%
- 48% of sites run outdated installations (prime attack targets)
- Only 69% of vulnerable plugins get patched; 26% never fixed
When to Stay on WordPress
✅ Non-technical content team (no developers)
✅ Budget under $5K for development
✅ Simple content site (blog, business site)
✅ Need 50+ plugins for features
✅ Shared hosting is sufficient
Part 2: Next.js 15 Production Experience
What Next.js Does Brilliantly
1. Performance is Exceptional
- Server-side rendering: HTML ready instantly
- Static generation: pre-built pages
- Image optimization built-in
- Code splitting automatic
Our Next.js Stats:
- Average page load: <1 second
- Lighthouse performance: 98/100
- Time to Interactive: 1.5 seconds
- First Contentful Paint: 0.4 seconds
Before → After:
- Page loads: 4.2s → 0.8s (5x faster)
- Lighthouse: 65 → 98 (51% improvement)
- Time to Interactive: 6s → 1.5s (4x faster)
Industry Validation:
- Next.js typically 40-60% faster than WordPress (multiple studies)
- Core Web Vitals: LCP 1.8s (Next.js) vs 4.2s (WordPress)
- FID: 45ms (Next.js) vs 280ms (WordPress)
- Mobile Lighthouse scores: +35-68% improvement over WordPress
- Real case (Digital Polygon): 51% mobile → 86% mobile after migration
2. Developer Experience is Modern
- TypeScript integration perfect
- Hot reload during development
- React component architecture
- Great documentation and tooling
- App Router is intuitive (once learned)
3. Scalability Built-In
- Handle 10K+ concurrent users
- Edge deployment (Vercel, Cloudflare)
- API routes for backend logic
- Middleware for authentication
- Multi-tenant architecture possible
Business Impact (Industry Data):
- 15-25% increase in organic traffic after migration (improved CWV = better rankings)
- 20-30% improvement in Core Web Vitals scores
- Typical ROI achieved within 6-12 months
- Lower bounce rates from faster page loads
- Better conversion rates from improved UX
Where Next.js Has Challenges
1. No Plugin Ecosystem
- Build every feature from scratch
- Authentication: code it yourself
- Forms: integrate a service
- SEO: implement metadata manually
- Image galleries: build components
Migration Considerations:
- Significant development time required for complex migrations
- WordPress setup is much faster for standard sites
2. Learning Curve
- React knowledge required
- Server Components vs Client Components
- App Router patterns (different from Pages Router)
- Build tools and configurations
- Deployment understanding needed
3. Hosting Complexity
- Can't use shared hosting
- Need Docker or Vercel/Netlify
- Environment variables management
- Build process required
- CI/CD pipeline needed
- VPS or managed hosting typically more expensive than WordPress shared hosting
Performance Note: Next.js 15 App Router
- App Router can be 2.5x slower for server-heavy apps (vs Pages Router)
- TTFB may be 2x slower for SSR use cases
- Vercel hosting optimizes App Router significantly
- Pages Router still faster for request-per-second workloads
- Choose based on your architecture: App Router for client-heavy, Pages for server-heavy
When Next.js Makes Sense
✅ Developer team available (React/TypeScript)
✅ Performance critical (e-commerce, SaaS)
✅ Multi-tenant or complex architecture
✅ Custom features needed
✅ Budget > $10K for development
Part 3: Directus CMS Real Experience
What Directus Excels At
1. Self-Hosted, Zero Licensing Fees
- Open source, MIT licensed
- Host anywhere (Docker, VPS, cloud)
- Full data ownership
- No per-user or API call fees
Cost Comparison:
- Directus self-hosted: $0/year (free under £3.97M revenue)
- Commercial headless CMS alternatives: $4,800-$6,000+/year
- Savings: $5-6K annually vs managed headless CMS services
2. TypeScript-Native API
- Auto-generated TypeScript types from schema
- Directus SDK (
@directus/sdk) with full type safety - REST and GraphQL APIs both available
- Webhook support for real-time updates
- Perfect Next.js Server Components integration
Real Implementation:
// Auto-generated types from Directus schema
import { EventItems, EventSchedules } from '@/data/directus-collections'
// Type-safe SDK usage
const items = await directusApi.request(
readItems('event_items', {
fields: ['*', 'image.*', 'categories.*'],
filter: { status: { _eq: 'published' } }
})
)
// TypeScript knows exact structure of 'items'
3. Snapshot-Based Schema Management
- Version control your entire schema
- 524KB
snapshot.yamlfile tracks everything - Collections, fields, relations, permissions
- Deploy schema changes via CLI
- Rollback schema if needed
Our Schema:
# Deploy schema from snapshot
directus schema apply ./cms/snapshots/snapshot.yaml
# Export current schema
directus schema snapshot ./cms/snapshots/snapshot.yaml
4. Flexible Data Modeling
- 17 collections in our project
- Relational data (many-to-many, etc.)
- Custom JSON fields for configuration
- No schema limitations
- Foreign key management
Our Directus Collections:
- Content Items, Schedules, Venues (400+ items)
- Cities, Partners, Contributors
- Blocks (26-block page builder system)
- Users with multi-tenant permissions
- Media files with access control
- Total: 1,000+ content items
Where Directus Has Limitations
1. Permission System Complexity
- JSON-based permission rules (not UI-based)
- Multi-tenant permissions require careful planning
- Testing permissions is tedious
- Took 2 days to set up initially
- Required custom validation scripts
Real Permission Challenge:
{
"policy": "Site_CityAdminPolicy",
"collection": "event_items",
"actions": ["create", "read", "update"],
"permissions": {
"_or": [
{ "website": { "id": { "_eq": "$CURRENT_USER.website" }}},
{ "website": { "id": { "_eq": "main" }}}
]
}
}
CityAdmin can see their city's content + main site content
Permission Management Scripts:
# Deploy 156 permission rules
npm run permissions:deploy
# Validate against test users
npm run permissions:validate
# Revert if broken
npm run permissions:revert
2. System Collections Workarounds
- SDK doesn't work for
directus_users,directus_roles - Must use raw REST API
- Less type-safe, more error-prone
- Hit this limitation week 7
The Workaround:
// Can't use SDK for system collections
const response = await fetch(
`${directusUrl}/users`,
{ headers: { Authorization: `Bearer ${token}` }}
)
// Manual type casting required
3. Docker Deployment Gotcha
- Custom plugins DON'T work in Docker
- Email SMTP requires
EMAIL_SMTP_IGNORE_TLS: true - Spent 4 hours debugging email issues
- Changed SMTP port from 465 → 587
- TLS certificates caused failures
What Broke:
# This failed in production
EMAIL_SMTP_PORT: 465
EMAIL_SMTP_SECURE: true
# Had to use this
EMAIL_SMTP_PORT: 587
EMAIL_SMTP_IGNORE_TLS: true
4. Learning Curve
- Not intuitive for non-technical users
- Relational data concepts needed
- Permission rules documentation sparse
- Community smaller than WordPress
- StackOverflow has fewer answers
- Training required for both developers and content editors
Real Production Feedback:
- Success story: Weber (smart grilling app) - 6M sessions, zero downtime, low latency
- Development savings: 4+ months saved vs custom build (reported by teams)
- Support reduction: 3x decrease in technical support needs
- Performance note: Can slow with large datasets and many concurrent users
- Setup complexity: Requires deeper technical understanding vs WordPress
Developer Experience Survey Data:
- 75% of developers use composable architectures (Netlify, 7K respondents)
- 61% ROI increase reported with headless CMS
- 58% time savings in development workflows
- TypeScript integration = fewer bugs, faster development
When Directus Works Best
✅ Developer team available
✅ Want data ownership (no SaaS lock-in)
✅ Complex relational data
✅ Multi-tenant permissions needed
✅ TypeScript project
✅ Need self-hosted CMS with zero licensing costs
Additional Directus Production Challenges (What We Learned)
After 12 months in production with Directus managing 400+ content items and 1,000+ total records, we encountered several limitations that aren't obvious during initial evaluation. Here are the real challenges we faced:
1. Image Upload & Optimization Limitations
The Problem:
- Directus does NOT automatically resize images on upload by default
- Transformations happen on first read, not upload
- Large images (>10MB) silently fail in UI with no clear error message
- No built-in automatic downscaling to prevent storage bloat
What This Means:
- Content editors can upload 8MB images that slow down your site
- You need custom hooks or third-party extensions to auto-resize
- Transformation presets must be whitelisted to prevent abuse
- Manual image optimization required before upload (frustrating for non-technical editors)
Our Solution:
- Built custom image optimization scripts (TinyPNG API + OpenAI for alt text)
- Added file size validation hooks
- Editor training: "Always optimize before upload"
- Required significant development time to implement
2. Default UI Field Configuration Complexity
The Problem:
- Cannot easily set default field visibility for all users
- System fields lack entries in directus_fields by default
- Each user can customize their layout, but admin can't enforce defaults
- No "lock" feature to prevent users from hiding critical fields
What This Means:
- Every new user sees ALL fields (overwhelming for editors)
- Must use Presets & Bookmarks to create default layouts
- System field customization requires database-level modifications
- Training overhead: teaching editors which fields to display
Our Experience:
- Editors initially confused by 30+ fields in content collection
- Created presets for each collection
- Still get support requests: "Where's the status field?"
3. Duplicate Functionality Breaks with Nested Relations
The Problem:
- "Save as Copy" doesn't work reliably with nested relationships
- Duplication creates blank child table entries instead of copying data
- Many-to-many nested relations create duplicates instead of updating
- Multiple relations create very long URLs → 414 error
Real Impact:
- Cannot duplicate items with nested categories/tags (M2M relations)
- Workaround: Add one nested relationship at a time, save after each
- Creating content templates impossible (defeats purpose of duplication)
- Editors manually re-enter relational data (time-consuming, error-prone)
Our Workaround:
- Built custom "clone item" script via API
- Properly handles nested M2M relations
- Required additional development time
4. Extension Ecosystem is Limited & Often Outdated
The Problem:
- Extensions may not be actively maintained after initial release
- No direct update button in Marketplace - must uninstall/reinstall
- Extensions can conflict with each other
- Much smaller ecosystem compared to WordPress (60,000+ plugins)
Reality Check:
- Limited useful extensions available compared to WordPress ecosystem
- Extensions can break after Directus updates
- Custom plugins don't work in Docker (mentioned earlier)
- Often easier to build custom API endpoints than find/fix extensions
Comparison:
- WordPress: Plugin for everything (form builders, SEO, backups, galleries)
- Directus: Build it yourself or use extensions (limited selection, maintenance risk)
5. DB-Driven Configs Cannot Sync Across Environments
The Problem:
- Permissions, flows, presets, dashboards stored in database, not snapshots
- Schema snapshots don't include these dynamic configurations
- No built-in way to sync dev → staging → production
- Manual recreation in each environment is error-prone
What Broke for Us:
- Spent 2 hours recreating 156 permission rules in production
- Flows created in dev not in staging (caught during QA)
- Dashboard layouts different per environment (confusing for editors)
- Presets lost when database refreshed
Solution (Requires External Tool):
- directus-sync CLI tool (third-party, by Tractr)
- Tracks dashboards, flows, permissions, policies, presets
- Requires directus-extension-sync installed on each instance
- Initial setup required but saves time on subsequent deployments
Commands:
# Compare local config with Directus instance
npx directus-sync diff
# Push local config to Directus instance
npx directus-sync push
Alternative:
- directus-extension-schema-sync - another third-party solution
- Export/import via custom scripts
- Manual recreation (not recommended)
6. Admin UI Performance & Stability Issues
The Problem:
- Checkbox Tree fields make UI unresponsive with typing delays
- Performance drops with large file counts (400K files = 45s response, heap crashes)
- 10 requests/sec = 1.5s average response time per request
- Connection pool timeouts with 3-40 concurrent users
Our Production Experience:
- Admin UI lags when 5+ editors logged in simultaneously
- Collections with 400+ items take 3-5 seconds to load
- File library (2,000+ images) noticeably slow
- Occasional "KnexTimeoutError" during peak usage
Symptoms:
- Editor complaints: "Why is it so slow?"
- Long tasks in Chrome DevTools (>50ms)
- JavaScript heap warnings in logs
- Need to refresh page to "unstick" UI
What Helps:
- Limit concurrent admin users (not always possible)
- Paginate large collections (default: 25 items per page)
- Use filters to reduce result sets
- Clear browser cache regularly
- Database connection pool tuning (trial and error)
Still Needs Work:
- UI responsiveness with large datasets
- Better loading states and feedback
- Connection pool management improvements
- More robust error handling
7. Customization Complexity
The Problem:
- Field names and types are immutable after creation
- Custom interfaces require building extensions
- System collection modifications need database-level access
- Documentation can be sparse for advanced customizations
Examples from Our Project:
- Wanted to rename field: had to create new field, migrate data, delete old
- Custom validation rules: built extension (8 hours development)
- Multi-step forms: completely custom frontend component
- Conditional field visibility: required custom interface
Skill Requirements:
- Vue.js knowledge for custom interfaces
- Node.js for hooks and custom endpoints
- Database knowledge for system field modifications
- Docker for extension deployment (if self-hosted)
The Honest Assessment
Directus is powerful but requires:
- Developer team with full-stack skills
- Time investment in tooling (image optimization, sync tools, custom extensions)
- Patience with ecosystem limitations
- Workarounds for production use cases
These aren't deal-breakers, but be prepared:
- Budget 20-30% more dev time for workarounds vs initial estimates
- Factor in maintenance of custom scripts/extensions
- Plan for editor training and ongoing support
- Test thoroughly with production data volumes
Would we still choose Directus?
Yes, for our use case (multi-tenant, complex permissions, TypeScript integration). But we'd budget differently and set clearer expectations with stakeholders about limitations.
When to reconsider Directus:
- Non-technical content team (too many rough edges)
- Need enterprise-grade admin UI polish
- Large concurrent user base (>20 simultaneous editors)
- Require extensive image management (thousands of uploads/month)
- Cannot invest in custom development for workarounds
Part 4: The Migration Reality
Development Timeline
Week 1-2: Foundation
- Set up Next.js 15 + App Router
- Deploy Directus with Docker Compose
- Configure multi-environment setup
- Plan data model (17 collections)
- Set up TypeScript strict mode
Week 3-6: Core Features
- Build 26-block page builder system
- Film catalog with relational data
- Event management + showtimes
- Video streaming integration
- Directus SDK integration
Week 7-10: Multi-Tenant Architecture
- Next.js middleware for city routing
- 156 permission rules (JSON config)
- City-specific data isolation
- Permission testing framework
- Hit system collections SDK limitation
Week 11-12: Migration & Polish
- Import scripts for 400+ films
- Data verification + rollback system
- Content team training (2 hours)
- Launch with reverse proxy fallback
- Email configuration debugging (4 hours)
Total: 12 weeks, 2 developers, 480 hours
Technical Implementation Deep-Dive
1. Directus Schema Snapshots
We version control the entire CMS schema as code:
cms/snapshots/
└── snapshot.yaml # 524KB, 15,000+ lines
What It Includes:
- 17 collections with all fields
- 156 permission rules
- Foreign key relationships
- Display templates and metadata
- Junction tables for many-to-many
Deployment:
# Apply schema to new environment
directus schema apply ./cms/snapshots/snapshot.yaml
# Export after changes
directus schema snapshot ./cms/snapshots/snapshot.yaml
# Version control with git
git commit -m "feat: add streaming access collection"
2. Auto-Generated TypeScript Types
Directus schema auto-generates TypeScript interfaces:
// src/data/directus-collections.d.ts (auto-generated)
export type ReelFilms = {
id: number
title: string
slug: string
synopsis?: string | null
runtime?: number | null
website?: number | ReelsWebsites | null
disabilities: ReelFilmsDataDisabilities[]
topics: ReelFilmsDataTopics[]
image?: string | DirectusFiles | null
status: 'draft' | 'published' | 'archived'
}
Type Safety Benefits:
- Autocomplete in VS Code
- Compile-time error checking
- Refactoring confidence
- Zero type definition maintenance
3. Caching Strategy
Next.js ISR + Directus cache management:
// Default 60-second revalidation
const directusApi = createDirectus(url)
.with(rest({
onRequest: (options) => ({
...options,
next: { revalidate: 60 }
})
}))
// Cache-busting API endpoint
POST /api/cache/clear
→ Clears Next.js cache
→ Clears Directus cache
→ Revalidates specific paths
Cache Clear Script:
npm run cache:clear
# Clears: films, events, pages, navigation
# Revalidates: /, /films, /events, city pages
4. Image Optimization Pipeline
Automated image processing:
// scripts/optimize-image.ts
1. Fetch image from Directus
2. Optimize with TinyPNG API (< 1MB)
3. Generate alt text with OpenAI GPT-4
4. Upload back to Directus
5. Update metadata
// Bulk optimization
npm run images:optimize
npm run images:describe
Results:
- Average image size: 2.5MB → 400KB (84% smaller)
- Automated alt text generation
- WCAG 2.1 AA compliance
5. Data Management Scripts
Import/export automation:
# Film import with verification
npm run films:import -- --csv=./films.csv
npm run films:verify # Check for issues
npm run films:revert # Rollback if needed
# Stream video import
npm run streams:import -- --csv=./videos.csv
# Website duplication (new city)
npm run duplicate -- --from=houston --to=cleveland
Import Features:
- CSV validation
- Duplicate detection
- Fuzzy matching (Video IDs)
- Transaction rollback
- Progress tracking
What We Gained
Performance:
- 5x faster page loads
- Better SEO rankings
- Improved user experience
- Lower bounce rates
Maintainability:
- Fewer breaking changes
- Type safety catches errors
- Better code organization
- Easier to add features
Scalability:
- Multi-tenant from scratch
- Can handle 10x traffic
- Easy to add new cities
- Custom features possible
What We Lost
Ease of Use:
- No visual page builder
- More technical setup
- Requires developers
- Longer feature development
Plugin Ecosystem:
- Build features from scratch
- No quick SEO plugin install
- Custom forms needed
- Integration work required
Challenges We Actually Hit (and Solutions)
Challenge 1: Docker Email Configuration
- Problem: Directus emails failing in production
- Root Cause: TLS certificate validation
- Time Lost: 4 hours debugging
- Solution:
EMAIL_SMTP_IGNORE_TLS: true+ port 587 - Lesson: Test email in staging first
Challenge 2: Permission Testing
- Problem: No UI to test 156 permission rules
- Impact: Manual testing took hours
- Solution: Built automated test suite
// src/lib/services/permissions/scripts/validate.ts
- Creates test users (MainAdmin, CityAdmin)
- Tests CRUD operations per collection
- Validates multi-tenant isolation
- Reports failures with details
- Result: 5-minute validation vs 2-hour manual test
Challenge 3: SDK Limitations for System Collections
- Problem:
directus_usersSDK doesn't work - Discovery: Week 7 (painful timing)
- Workaround: Raw REST API calls
// Lost type safety here
const users = await fetch(`${url}/users`, {
headers: { Authorization: `Bearer ${token}` }
})
- Lesson: Read SDK limitations docs early
Challenge 4: Image Optimization at Scale
- Problem: 400+ images, 2.5MB average
- Manual effort: 40 hours estimated
- Solution: Automated pipeline
- TinyPNG API for compression
- OpenAI for alt text generation
- Batch processing scripts
- Time saved: 38 hours (95% reduction)
Challenge 5: Multi-Tenant Data Leaks
- Problem: City A seeing City B's content
- Root Cause: Missing
websitefilter - Detection: Permission validation tests
- Fix: Required filters in all queries
// Every query needs this
filter: {
website: { id: { _eq: currentWebsite }}
}
- Prevention: Automated test suite
Challenge 6: Snapshot Conflicts
- Problem: Schema changes cause merge conflicts
- File:
snapshot.yaml(15,000 lines) - Frequency: 2-3 times during development
- Solution: Manual merge + reapply
- Lesson: Coordinate schema changes
Industry Migration Case Studies
Smashing Magazine: 800ms → 80ms (10x Faster)
- Challenge: 20K+ comments, thousands of articles, traffic spikes
- Result: HTML load time improved from 800ms to 80ms
- Benefit: Consistent performance during traffic spikes
- Tech: WordPress to JAMstack
- Key win: Better security, no performance degradation under load
10Clouds: +25% Traffic from Performance
- Challenge: Complex agency site with portfolio, blog, case studies
- Result: 25% increase in website traffic post-migration
- Benefits: Simplified architecture, more team autonomy
- Tech: WordPress to JAMstack with headless CMS
- Key win: Faster, more customizable, easier maintenance
LiveChat: Developer Focus Restored
- Challenge: Sysadmins supporting marketing pages instead of core product
- Problem: Plugin security concerns, caching challenges
- Timeline: Started 2017, flagship site migrated November 2019
- Result: Smooth transition, better analytics tracking
- Tech: WordPress to JAMstack with Netlify
- Key win: Team could focus on core product instead of WordPress maintenance
Localcoin: Better UX = Business Growth
- Challenge: Slow page speeds, dated tech stack hurting conversions
- Impact: Poor UX slowing business growth and customer satisfaction
- Result: Significantly reduced page weight and improved performance
- Tech: WordPress to Next.js
- Key win: Improved customer satisfaction and conversion rates
Common Migration Success Patterns:
- Performance improvements: 5-10x faster load times
- Maintenance reduction: 50-75% less time on updates/patches
- Traffic increases: 15-25% from better SEO (Core Web Vitals)
- Developer productivity: 40-60% faster feature development
- Team focus: More time on product, less on infrastructure
Common Migration Timeline:
- Small site (5-20 pages): 2-4 weeks
- Medium site (50-100 pages): 6-12 weeks
- Large/complex site (100+ pages, custom features): 12-24 weeks
- Enterprise migration: 6-12 months
Part 5: Technology Decision Framework
Choose WordPress If:
- Non-technical team managing content
- Budget under $5K
- Simple content site (blog, portfolio, business)
- Need quick launch (1-4 weeks)
- Want 60,000+ plugins available
- Shared hosting sufficient
- Visual page builder required
Choose Next.js + Directus If:
- Have developer team (React/TypeScript)
- Budget > $10K
- Performance critical (Core Web Vitals)
- Multi-tenant application
- Complex custom features
- Want data ownership (self-hosted)
- Long-term scalability important
- TypeScript project
Choose Next.js + Managed Headless CMS If:
- Want managed CMS service (no self-hosting)
- Budget > $20K/year
- Need enterprise support
- Don't want to manage infrastructure
- Prefer SaaS solution over self-hosted
Part 6: SEO Performance Comparison
WordPress SEO: Strengths
What WordPress Does Well:
- Quick setup: Yoast SEO and Rank Math plugins handle meta tags, sitemaps, schema
- User-friendly: Non-technical editors can optimize content
- Mature ecosystem: Extensive plugins for every SEO need
- Good for small business: Get started within hours with proven tools
- Established patterns: Most SEO agencies know WordPress well
The "Google Loves WordPress" Myth:
⚠️ Truth: WordPress is SEO-agnostic. Google doesn't favor WordPress. What matters:
- Theme quality and code implementation
- Site speed and Core Web Vitals
- Content quality and structure
- Technical implementation
Next.js SEO: Strengths
Why Next.js Excels at SEO:
- Server-side rendering: Content ready for crawlers (no client-side rendering delays)
- Static generation: Pre-rendered HTML = instant crawling
- Performance = ranking factor: Core Web Vitals directly impact rankings
- Built-in optimizations: Lazy loading, code splitting, image optimization
- Structured sitemaps: Full control over sitemap generation
- Middleware: Advanced control over headers, redirects, canonical URLs
Performance = SEO Advantage:
- Core Web Vitals are now ranking factors (since 2021)
- Next.js excels: LCP <2.5s, FID <100ms, CLS <0.1
- WordPress struggles: Especially on mobile (13.25s avg load time)
Real SEO Impact: The Data
Next.js After Migration:
- 15-25% increase in organic traffic (multiple case studies)
- 20-30% improvement in Core Web Vitals scores
- Mobile PageSpeed scores: +35-68% improvement
- Better mobile rankings (Google is mobile-first indexing)
- Lower bounce rates from faster loads
WordPress Mobile Challenge:
- Desktop performance often good (2.5s average)
- Mobile performance poor (13.25s average) - 5x slower
- Only 57.8% of WordPress sites meet LCP threshold
- Mobile performance gap hurts rankings
SEO Migration Best Practices
Critical SEO Tasks When Migrating:
-
301 Redirects (NON-NEGOTIABLE)
- Map every WordPress URL to Next.js URL
- Test all redirects before launch
- Monitor 404 errors in Google Search Console
- Use next.config.ts for permanent redirects
-
Preserve URL Structure (if possible)
- Keep same slugs and hierarchy
- If changing URLs, ensure 301 redirects
- Update internal links
-
Sitemap Updates
- Generate new sitemap.xml
- Submit to Google Search Console
- Include all pages, posts, dynamic routes
- Set proper priorities and update frequencies
-
Meta Tags & Schema
- Migrate all meta descriptions
- Port schema markup (JSON-LD)
- Ensure Open Graph tags
- Twitter Card meta tags
-
Image Optimization
- Optimize all images (<1MB)
- Add descriptive alt text
- Use Next.js Image component
- Implement lazy loading
-
Monitor Rankings
- Track rankings before migration (baseline)
- Watch Google Search Console closely
- Expect temporary fluctuations (2-4 weeks)
- Most sites see improvement after 4-8 weeks
The Verdict: Which is Better for SEO?
WordPress for SEO if:
- Small business, quick start
- Non-technical team
- Need plugin simplicity
- Budget under $5K
Next.js for SEO if:
- Performance critical (e-commerce, SaaS)
- Competitive keywords (every ms counts)
- Mobile-first strategy
- Developer resources available
- Long-term SEO investment
Reality Check:
Both can rank well with proper implementation. However:
- Next.js has performance advantage (faster = better rankings)
- WordPress has easier initial setup (plugins handle basics)
- Next.js requires custom SEO implementation (more control, more work)
- WordPress mobile performance is a real issue (5x slower than desktop)
Bottom Line:
If you can build it, Next.js will outperform WordPress on SEO purely from performance gains. But WordPress + optimization can also rank well if mobile performance is addressed.
Part 7: Key Takeaways
WordPress in 2025:
- Still excellent for small business sites
- Plugin ecosystem unmatched (60,000+)
- Performance ceiling is real (2.5s desktop, 13.25s mobile)
- Mobile performance is critical weakness (5x slower than desktop)
- 60% of issues from plugin conflicts, 93.25% of vulnerabilities from plugins
- 5,948 vulnerabilities in 2023 (24% increase from 2022)
- Multisite complexity: 30% experience conflicts after updates
- Maintenance burden: 5 hours/week
- Perfect for non-technical teams
- Shared hosting: $5-30/month
- Only 57.8% of WordPress sites meet Core Web Vitals standards
Next.js Benefits:
- Performance gains: 5x faster (4.2s → 0.8s) - industry: 40-60% faster
- Lighthouse: 65 → 98/100 (mobile: +35-68% improvement)
- Core Web Vitals: LCP 1.8s vs WordPress 4.2s, FID 45ms vs 280ms
- 15-25% organic traffic increase from improved rankings
- ROI within 6-12 months for most migrations
- Developer experience excellent (58% time savings reported)
- TypeScript productivity gains significant
- No plugin ecosystem (build from scratch)
- Learning curve: 1 week for React devs
- Scales to 10K+ concurrent users
- App Router note: Can be 2.5x slower for server-heavy apps (vs Pages Router)
Directus Reality:
- Self-hosted = $0 licensing (significant savings vs commercial alternatives)
- Open-source with Business Source License (free under £3.97M revenue)
- TypeScript auto-generation perfect
- Snapshot-based schema (524KB YAML)
- Permission complexity real (requires careful planning)
- System collections SDK limitation discovered during development
- Docker email configuration challenges
- Community smaller than WordPress but growing
- Success stories: Weber (6M sessions, zero downtime), significant dev time savings reported
- Performance can slow with large datasets and many concurrent users
- Developer experience: 61% ROI increase, 58% time savings with headless CMS
Directus Production Challenges (The Reality):
- No automatic image resizing on upload - requires custom hooks or extensions
- Cannot enforce default UI fields for all users - each user customizes, training overhead
- Duplication breaks with nested relations - requires custom clone script
- Limited extension ecosystem - fewer options than WordPress, maintenance risks
- DB-driven configs don't sync - requires third-party directus-sync tool
- Admin UI lags with 5+ concurrent users, 400+ items take 3-5s to load
- Customization complexity - immutable fields, requires Vue.js/Node.js skills
- Budget reality: Plan for additional dev time for workarounds
- When to reconsider: Non-technical team, >20 concurrent editors, extensive image management
Real Technical Challenges:
- Permission Testing - Built automated suite for faster validation
- Email SMTP - Requires
IGNORE_TLS: truein Docker - SDK Limitations - System collections need REST API
- Image Optimization - Automated pipeline implementation required
- Multi-Tenant Leaks - Required validation framework
- Snapshot Conflicts - 15,000-line YAML merge conflicts
Migration Success Factors:
- Have developer team (React/TypeScript)
- Budget adequate time for migration based on site complexity
- Build permission validation from day 1
- Automate image optimization early
- Test email in staging (TLS issues)
- Plan snapshot workflow (avoid conflicts)
- Train content team appropriately
- Use reverse proxy for zero-downtime
- Implement 301 redirects (non-negotiable for SEO)
- Monitor Core Web Vitals improvements (validate migration value)
Industry Migration Patterns:
- 5-10x faster load times post-migration
- 50-75% less maintenance time (no plugin updates/conflicts)
- 15-25% traffic increase from better SEO
- 40-60% faster feature development with TypeScript
- Case studies: Smashing Magazine (800ms → 80ms), 10Clouds (+25% traffic)
Production Tech Stack:
- Next.js 15 (App Router, Server Components, TypeScript strict)
- Directus 11.4 (self-hosted, Docker, snapshot-based schema)
- Directus SDK (
@directus/sdkv19+) with auto-generated types - Caching: Next.js ISR (60s revalidate) + cache-busting API
- Image pipeline: TinyPNG + OpenAI GPT-4 for alt text
- Scripts: Import/export, verification, rollback, permission validation
- Deployment: Docker Compose (Next.js + Directus + MySQL + Caddy)
- Hosting: VPS $50/month (15 city sites)
SEO Comparison:
- Next.js advantage: Performance = ranking factor (Core Web Vitals since 2021)
- WordPress advantage: Quick setup with proven plugins (Yoast, Rank Math)
- Reality: Both can rank, but Next.js has mobile performance edge
- Myth busted: "Google loves WordPress" is nonsense - performance matters, not platform
- Data: 15-25% organic traffic increase after Next.js migration (multiple case studies)
When NOT to Migrate:
- Non-technical team (no React developers)
- Budget under $10K
- Simple blog or brochure site (5-20 pages)
- Need 20+ plugins for features
- Can't invest 12+ weeks in migration
- WordPress performance is acceptable for your needs
Honest Bottom Line: WordPress isn't bad—it's perfect for its use case (small business, non-technical teams, quick launch). Next.js + Directus isn't better—it's different, with different trade-offs (performance-critical, developer teams, complex features). The data validates both approaches can succeed. Choose based on your team skills, budget, performance requirements, and long-term maintenance capacity—not hype or trends.
Key Decision Points:
- Team: WordPress for non-technical, Next.js for developers
- Performance: Next.js wins (especially mobile: 5x faster)
- Budget: WordPress cheaper initially, Next.js better ROI long-term
- Maintenance: WordPress requires more frequent maintenance, Next.js less overhead
- SEO: Both can rank, Next.js has performance advantage
- Time to Market: WordPress faster initial setup, Next.js requires longer development
- Scalability: Next.js handles complexity better (multi-tenant, custom features)