2024年後半、あるシリーズCの金融サービスSaaS企業が、実際に損失を出していた問題を抱えて私たちのところへやってきました。マーケティングサイト、カスタマーポータル、ドキュメンテーションハブのすべてがWordPressで運用されており、プレミアムプラグインの複雑怪奇なネットワーク、年420,000ドルのエンタープライズCMSライセンススタック、そしてコンプライアンスチームを不安にさせるページロード時間を抱えていました。彼らは1秒たりともダウンタイムなしで最新のヘッドレスアーキテクチャに移行する必要がありました。金融サービスではダウンタイムは規制監視、信頼喪失、そして非常に深刻な人物からの非常に高くつく電話を意味するからです。

これが、いかにしてそれを成し遂げたかの全ストーリーです。

目次

WordPress to Next.js Migration: Financial SaaS Saves $420K ARR

スタート地点:プレッシャーの下にあるWordPressモノリス

状況を説明しましょう。この企業 — NDAもあるので、FinEdgeと呼びましょう — は3つの異なるウェブプロパティにまたがる約12,000ページのコンテンツを保有していました:

  1. マーケティングサイト — 製品ページ、ランディングページ、2,400以上の投稿を持つブログ
  2. カスタマーポータル — アカウントダッシュボード、オンボーディングフロー、ドキュメント管理
  3. ドキュメンテーションハブ — APIドキュメント、コンプライアンスガイド、統合チュートリアル

3つすべてが単一のWordPressマルチサイトインストールで実行されており、WP Engineのエンタープライズティアでホストされていました。プラグイン状況は...何とも言えません。47個のアクティブなプラグインが実行されていました。これには、WPGraphQL、Advanced Custom Fields Pro、Yoast SEO Premium、WP Rocket、Gravity Formsが含まれ、さらに彼らの前のエージェンシーが構築したカスタムプラグインがSOC 2コンプライアンスログをコンテンツ変更のために処理していました。

実際の問題点:

  • モバイルでの平均ページロード時間4.2秒(Google CrUXデータ)
  • 68%のページでCore Web Vitalsが不合格 — LCPは中央値5.1秒で悪かった
  • 年間420,000ドルのライセンス — WP Engineエンタープライズホスティング、プレミアムプラグイン、WAF、CDN、別のステージング環境にまたがる
  • ピーク時間中のWordPressアドミンの応答待ち8~12秒 — コンテンツエディタの場合
  • セキュリティパッチ — 2週間ごとに専門のDevOps時間が必要。金融サービスの規制当局は甘くありません
  • プレビューデプロイメントなし — コンテンツチームはステージングにプッシュして、キャッシュ無効化に4分待つ必要がありました

エンジニアリング担当VP は発見呼び出し中に私たちに言いました:「ウェブサイトインフラに2人のシニアエンジニアより多くを費やしている。それでもまだ遅い。」

ヘッドレスNext.jsが正しい選択だった理由

アーキテクチャフェーズ中に複数のオプションを評価しました。テーブルに上がっていたのは:

オプション 利点 欠点 推定年間費用
WordPress(最適化) チームに馴染み深い、マイグレーション不要 相変わらず遅い、ライセンス変わらず $420,000
Webflow Enterprise ビジュアル編集、高速デプロイ ポータル/アプリニーズに限定的、ベンダーロックイン $180,000
Next.js + Sanity 高速、柔軟、リアルタイムプレビュー マイグレーションの手間、チーム習熟に時間 $38,000
Next.js + Contentful エンタープライズ機能が強い、優れたDX ユーザーあたりの価格がスケールしない $95,000
Astro + Storyblok 静的コンテンツに最適、軽量 動的ポータルニーズに実績不足 $42,000

私たちはNext.js 14(App Router)+ SanityをヘッドレスCMSとして採用しました。理由は:

  • FinEdgeのポータルは、サーバーサイドレンダリングが必要な動的で認証されたルートを持っていました。Next.jsはReact Server Componentsでこれをネイティブに処理します。
  • SanityのリアルタイムコラボレーションとGROQクエリ言語は、コンテンツエディタにWordPressよりも劇的に優れた体験をもたらしました。
  • 価格モデル(SanityのGrowthプラン99ドル/月 + Vercel Pro)はインフラ費用を年間420,000ドルから約38,000ドルに削減しました。
  • 彼らのエンジニアリングチームはすでにReactを知っていました。Next.jsへのランプアップは数ヶ月ではなく数日で測定されました。

ドキュメンテーションハブは主に静的コンテンツであるため、Astroを真剣に検討しましたが、すべてを1つのフレームワークに統一する運用上の単純さが勝利しました。ドキュメントサイトがスタンドアロンプロジェクトだった場合、Astroが選択肢だったでしょう。

マイグレーションアーキテクチャ

ここが、設計したハイレベルアーキテクチャです:

┌─────────────────┐     ┌──────────────────┐
│   Sanity CMS     │────▶│  Next.js on       │
│   (Content)      │     │  Vercel (Edge)    │
└─────────────────┘     └──────────────────┘
         │                        │
         │                        ▼
         │               ┌──────────────────┐
         │               │  Cloudflare       │
         │               │  (DNS + WAF)      │
         │               └──────────────────┘
         │                        │
         ▼                        ▼
┌─────────────────┐     ┌──────────────────┐
│  Media Pipeline  │     │  End Users        │
│  (Cloudinary)    │     └──────────────────┘
└─────────────────┘

主要なコンポーネント:

コンテンツレイヤー

  • Sanity をマーケティングコンテンツ、ブログ投稿、ドキュメンテーションの一次CMSとして
  • 既存のWordPressコンテンツタイプにマッピングされたカスタムSanityスキーマ
  • Portable Text を豊富なコンテンツに使用(WordPressのGutenbergブロックを置き換え)

アプリケーションレイヤー

  • Next.js 14 App Router付き、Vercel Pro プランでデプロイ
  • マーケティングサイトとドキュメント用のReact Server Components
  • クライアントコンポーネントは実際にインタラクティビティが必要な場所のみ(フォーム、ダッシュボード、インタラクティブチャート)
  • ポータルルートの認証用ミドルウェア、既存のAuth0セットアップと統合

インフラレイヤー

  • Vercel ホスティングとエッジ関数用
  • Cloudflare DNS管理と追加のWAFルール用(金融サービスコンプライアンス要件)
  • Cloudinary 画像最適化と変換用 — 3つのWordPressイメージプラグインを置き換え

WordPress to Next.js Migration: Financial SaaS Saves $420K ARR - architecture

ゼロダウンタイム戦略:パラレルラン

ここが私を夜眠らせなかった部分です。FinEdgeは少しのダウンタイムも負うことができませんでした。彼らのカスタマーポータルは金融取引を処理しており、あらゆる中断は規制当局への強制的な事故報告をトリガーします。

ここが、やり遂げた方法です:

フェーズ1:コンテンツ同期(1~3週目)

マイグレーション期間中に継続的に実行されたカスタムWordPress-to-Sanity同期パイプラインを構築しました:

// WP-to-Sanity同期ワーカーの簡略版
import { createClient } from '@sanity/client'
import WPGraphQL from './wp-graphql-client'

const sanity = createClient({
  projectId: process.env.SANITY_PROJECT_ID,
  dataset: 'production',
  token: process.env.SANITY_WRITE_TOKEN,
  apiVersion: '2024-10-01',
  useCdn: false,
})

async function syncPosts(since: string) {
  const posts = await WPGraphQL.getModifiedPosts(since)
  
  const transaction = sanity.transaction()
  
  for (const post of posts) {
    const sanityDoc = transformWPToSanity(post)
    transaction.createOrReplace(sanityDoc)
  }
  
  await transaction.commit()
  console.log(`Synced ${posts.length} posts`)
}

// cronで5分ごとに実行

これにより、コンテンツエディタはマイグレーション全体を通じてWordPressで作業し続けることができました。彼らが行ったすべての変更は5分以内にSanityに自動的に同期されました。

フェーズ2:並行デプロイ(4~8週目)

Next.jsサイトをサブドメイン(next.finedge.com)にデプロイし、両方のサイトを同時に実行しました。QAプロセスはすべてのページを比較しました:

  • Playwrightによる200以上の重要ページでのビジュアルリグレッションテスト
  • SEOパリティチェック(メタタグ、構造化データ、canonical URL、サイトマップ)
  • すべてのページテンプレートでのパフォーマンスベンチマーク
  • アクセシビリティ監査(WCAG 2.1 AA — 金融サービスに必須)

フェーズ3:カットオーバー(9週目)

実際のスイッチは退屈でした — 正確にはそれが望むところです。Cloudflareのロードバランシングを使用してトラフィックを段階的にシフトしました:

  • 時間0: トラフィックの5%がNext.js、95%がWordPress
  • 時間2: 25% / 75%(エラー率、Core Web Vitalsを監視)
  • 時間6: 50% / 50%
  • 時間12: 90% / 10%
  • 時間24: 100% Next.js、WordPressは読み取り専用モード
  • 2週目: WordPressを廃止

エラーなし。ダウンタイムなし。監視ダッシュボードは退屈なほど緑色でした。

パフォーマンス結果:3倍以上の高速化

以下は、マイグレーション後30日間、GoogleCrUXデータとVercel Analyticsを使用して測定された実数です:

メトリクス WordPress(前) Next.js(後) 改善
LCP(p75) 5.1秒 1.2秒 4.25倍高速化
FID / INP(p75) 280ms 68ms 4.1倍高速化
CLS(p75) 0.18 0.02 9倍改善
TTFB(p75) 1.8秒 0.12秒 15倍高速化
Lighthouse Performance 34 96 +62ポイント
CWVを通過するページ 32% 98% +66%
Time to Interactive 6.8秒 1.4秒 4.9倍高速化

「3倍高速化」というヘッドラインは実際には過小評価です。ほとんどのメトリクスでは、4~5倍の改善が見られました。TTFBがスター選手でした — VercelのEdge NetworkとISR(Incremental Static Regeneration)のおかげで1.8秒から120ミリ秒に。

マイグレーション後の最初の90日間で、オーガニックトラフィックが31%増加しました。SEOチームはこれを主にCore Web Vitalsの改善とGooglebotのクローリング速度の向上に起因するとしています。

420,000ドルのライセンス削減の内訳

お金について話しましょう。420,000ドルが正確にどこへ向かっていて、それが何に置き換わったかは以下の通りです:

行項目 WordPress年間費用 Next.js年間費用 削減額
WP Engine Enterprise ホスティング $150,000 $150,000
Vercel Pro(Team プラン) $2,400
プレミアムプラグインライセンス(47プラグイン) $28,000 $28,000
Sanity Growth プラン $1,188
Cloudinary Pro $2,388
エンタープライズWAF(Sucuri) $36,000 $36,000
Cloudflare Pro $2,400
カスタムWordPress保守契約 $96,000 $96,000
CDN(WP Engine外) $24,000 $24,000
ステージング環境ホスティング $18,000 $18,000
WordPressセキュリティ監査(四半期ごと) $48,000 $48,000
DevOpsチーム時間(部分FTE) $120,000 $30,000 $90,000
合計 $520,000 $38,376 $481,624

実際の削減は420,000ドルではなく、約482,000ドルになりました。発見フェーズからの元の420,000ドルの推定値は保守的でした — 最初はDevOps時間の削減や四半期ごとのセキュリティ監査の廃止を説明していませんでした(VercelとCloudflareはこれらの監査がカバーしたもののほとんどを処理します)。

ROI計算は単純です。FinEdgeのマイグレーションプロジェクトは、10週間のエンゲージメント中、エージェンシー料金で約185,000ドルの費用がかかりました。その投資は5ヶ月以内に回収されました。

技術的な詳細:主要な実装詳細

ISRで2,400個のブログ投稿を処理する

ビルド時にすべての2,400個のブログ投稿を静的生成しませんでした。それはデプロイメントを痛いほど遅くしてしまいます。代わりに、オンデマンド再検証付きのISRを使用しました:

// app/blog/[slug]/page.tsx
import { sanityFetch } from '@/lib/sanity'
import { postQuery } from '@/lib/queries'

export const revalidate = 3600 // フォールバックとして1時間ごとに再検証

export async function generateStaticParams() {
  // トラフィック別の上位100投稿のみを事前生成
  const topPosts = await sanityFetch({
    query: `*[_type == "post"] | order(pageViews desc) [0...100] { "slug": slug.current }`
  })
  return topPosts.map((post) => ({ slug: post.slug }))
}

export default async function BlogPost({ params }) {
  const post = await sanityFetch({
    query: postQuery,
    params: { slug: params.slug },
    tags: [`post:${params.slug}`]
  })
  
  // ... 投稿をレンダリング
}

コンテンツエディタがSanityで発行または更新するとき、webhookが再検証エンドポイントにヒットします:

// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache'
import { NextRequest } from 'next/server'

export async function POST(req: NextRequest) {
  const body = await req.json()
  const secret = req.headers.get('x-sanity-webhook-secret')
  
  if (secret !== process.env.SANITY_WEBHOOK_SECRET) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }
  
  // 特定のコンテンツを再検証
  if (body._type === 'post') {
    revalidateTag(`post:${body.slug.current}`)
    revalidateTag('posts-list')
  }
  
  return Response.json({ revalidated: true })
}

コンテンツ更新はライブサイトに3秒以内に表示されます。WordPressとWP Rocketで持っていた4分のキャッシュ無効化と比較してください。

カスタマーポータル用の認証

ポータルルートはサーバーサイド認証が必要でした。Next.jsミドルウェアを既存のAuth0セットアップと組み合わせて使用しました:

// middleware.ts
import { NextResponse } from 'next/server'
import { getSession } from '@auth0/nextjs-auth0/edge'

export async function middleware(req) {
  if (req.nextUrl.pathname.startsWith('/portal')) {
    const session = await getSession(req, NextResponse.next())
    
    if (!session?.user) {
      return NextResponse.redirect(new URL('/api/auth/login', req.url))
    }
  }
  
  return NextResponse.next()
}

export const config = {
  matcher: ['/portal/:path*']
}

これはエッジで実行されるため、認証されていないリクエストはアプリケーションサーバーに到達する前にリダイレクトされます。高速で安全です。

301リダイレクトマップ

マイグレーション中に構造が変わったURLは約340個ありました。金融サービスサイトは絶対にリンク切れを持つことはできません。規制ファイリング、パートナーサイト、履歴コンテンツからの各インバウンドリンクは正しく解決される必要があります。

next.config.jsに再ルーティングマップを構築し、エディター管理の再ルーティングのためのSanityからの動的ルーティング検索で補足しました:

// next.config.js(部分)
module.exports = {
  async redirects() {
    return [
      // 既知のURL変更のための静的リダイレクト
      ...require('./redirects.json').map(r => ({
        source: r.from,
        destination: r.to,
        permanent: true,
      })),
    ]
  },
}

ローンチ後6ヶ月で、Google Search Console はマイグレーションからの404エラーがゼロを示しています。すべてのリダイレクトが機能しています。

教訓:苦労してから学んだこと

1. WordPress Gutenberg ブロックは変換が面倒です

Gutenberg ブロックを Sanity の Portable Text に変換する作業を過小評価しました。FinEdge は 23 種類の異なるブロックタイプを使用していました。これには彼らの前のエージェンシーが構築したカスタムブロックを含みます。コンテンツ変換に、あなたが考えるより少なくとも 20% 多くの時間を予算化してください。

2. コンテンツエディタトレーニングは不可欠です

Sanity Studio は直感的ですが、WordPressではありません。3 つの 90 分間のトレーニングセッションを実施し、ガイド付きワークフローを持つカスタム Sanity Studio を作成しました。コンテンツチームは懐疑的から熱意あるまで 2 週間以内に進みましたが、そのトレーニング投資は重要でした。

3. 金融サービスコンプライアンスは複雑さを追加します

すべてのデプロイには監査証跡が必要でした。すべてのコンテンツ変更はタイムスタンプとユーザーアトリビューションでログされる必要がありました。カスタム Sanity プラグインを構築し、すべてのドキュメント変更を追記専用監査テーブルに既存の PostgreSQL データベースに記録しました。これにより、元のスコープに含まれていない追加の 1 週間がかかりました。

4. フォームを忘れないでください

Gravity Forms は WordPress サイトで 14 種類の異なるフォームタイプを処理していました。フロントエンドで React Hook Form + Zod 検証、バックエンドでサーバーアクション、既存の HubSpot CRM への提出で置き換えました。このマイグレーションだけで丸 1 週間かかりました。

タイムラインとチーム構成

総プロジェクト期間:10週間

重点 チーム
1 アーキテクチャ、Sanity スキーマ設計、コンテンツ監査 2 開発者、1 アーキテクト
2-3 コンテンツ同期パイプライン、Sanity Studio カスタマイズ 2 開発者、1 コンテンツストラテジスト
4-5 マーケティングサイト構築(Next.js) 3 開発者
6-7 ポータルマイグレーション、認証、フォーム 3 開発者
8 ドキュメンテーションハブ、SEO 監査、リダイレクトマップ 2 開発者、1 SEO スペシャリスト
9 QA、ビジュアルリグレッション、パフォーマンステスト 2 開発者、1 QA
10 段階的トラフィックカットオーバー、監視、WordPress 廃止 2 開発者、1 DevOps

ピークチームサイズは 4 人でした。プロジェクトのほとんどは 2~3 人の開発者で実行されました。これは 15 人、6 ヶ月のエンゲージメントではありません — 計画された良好なマイグレーションを実行する、焦点を絞った経験豊富なチームです。

あなたの組織で同様のマイグレーションを検討している場合、ヘッドレス CMS 開発アプローチ を文書化しており、料金体系 は透過的です。また、あなたの特定の状況について話し合うために通話に応じるのも喜んでです — ここで連絡してください

FAQ

WordPress から Next.js へのマイグレーションは通常どのくらいかかりますか? この複雑さのサイト(12,000ページ、カスタマーポータル、ドキュメンテーションハブ)では、経験豊富なチームで 10 週間が現実的です。100~500 ページの単純なマーケティングサイトは 4~6 週間でマイグレーションできます。最大の変数はコンテンツの複雑さです — 何個のカスタム投稿タイプ、ブロックタイプ、プラグイン依存機能を実行しているかです。

WordPress を Next.js にダウンタイムなしでマイグレーションできますか? はい、ただし計画が必要です。重要なのは両方のシステムをコンテンツ同期パイプラインを伴って平行で実行してから、DNS レベルのトラフィックシフティングを使用して段階的にユーザーを新しいサイトに移動させることです。複数のクライアントの場合、これを正常に実行しました。重要な要件は、遷移期間中、コンテンツが両方のシステム間で同期したままであることです。

WordPress からヘッドレス CMS へのマイグレーション費用はいくらですか? スコープに大きく依存します。単純なマーケティングサイトマイグレーションは $30,000~$60,000 で実行できる場合があります。FinEdge のようなエンタープライズマイグレーション — カスタマーポータル、コンプライアンス要件、12,000 ページ — は $185,000 でした。絶対的なコストより ROI 計算がより重要です。FinEdge の投資はライセンス削減だけで 5 ヶ月以内に回収されました。

Next.js は実際に WordPress より高速ですか? 事実上すべての場合で、はい — 有意に高速です。WordPress は各リクエストで HTML を生成します(重くキャッシュされていない限り)。WP Rocket のようなキャッシュプラグインでも、PHP の応答時間と WordPress エコシステムの重みで制限されます。Next.js は ISR または静的生成でプリビルドされたページをエッジから提供します。通常、Core Web Vitals で 3~5 倍の改善が見られます。

Next.js でどのヘッドレス CMS を使用すべきですか? チームと要件に大きく依存します。Sanity はカスタムコンテンツモデリングとリアルタイムコラボレーションで優れています。Contentful はより構造化された独断的なアプローチを求めるエンタープライズチームに強いですが、ユーザーあたり費用が高くなります。Storyblok は視覚的編集が優先事項の場合に優れています。より単純なサイトでは、Git リポジトリ内のマークダウンファイルでも機能します。これはプロジェクトごとに評価します — 万能な答えはありません。

WordPress から Next.js に移行するときに SEO を失いますか? 正しく実行すれば、いいえ。重要な 3 つのこと:既存の URL が 404 を返さないように包括的な 301 リダイレクトマップを作成すること、すべてのメタタグと構造化データを保持すること、カットオーバー直後に更新されたサイトマップを Google Search Console に提出することです。FinEdge は主に Core Web Vitals 改善により駆動される、カットオーバー後 90 日以内にオーガニックトラフィックで 31% 増加が見られました。

マイグレーション後、WordPress プラグインはどうなりますか? 各プラグインの機能は複製または置き換える必要があります。一部は単純です — SEO プラグインは Next.js コンポーネント内のメタデータに置き換えられ、キャッシュプラグインは不要になり、フォームプラグインは React フォームライブラリに置き換えられます。他のプラグイン(カスタムコンプライアンスログプラグインなど)には、作成されたカスタム置き換えコードが必要です。これが、発見中の徹底的なプラグイン監査が重要である理由です。

ヘッドレスに移動した後、コンテンツエディタは引き続きビジュアルエディタを使用できますか? はい。Sanity Studio はカスタマイズ可能な編集インターフェイスをリアルタイムプレビュー付きで提供します。WordPress ブロックエディタとは異なりますが、最初の学習曲線の後、ほとんどのコンテンツチームがこれを好みます。Sanity の Presentation ツールは現在、ライブプレビューでクリックしたを編集できるようにする真のビジュアル編集を提供します。また、Vercel でプレビューデプロイメントを設定したため、エディタはコンテンツを公開する前に、それがどのように見えるかを正確に確認できます。