日本企業向けMovable TypeからNext.js への移行ガイド

もし長年日本の企業向けウェブサイトに携わっているのであれば、Movable Typeを確実に目にしたことがあるでしょう。Six Apartの CMS は2000年代半ば以来、日本市場を強く支配しており、大手メーカーのコーポレートサイトから政府ポータルや大学のウェブサイトまで、あらゆるものを運用しています。しかし、ここが問題です — 現在は2026年であり、ウェブは大きく進化しています。あなたの Movable Type インストーレーションはおそらく進化していないでしょう。

過去2年間、日本の複数の企業サイトを Movable Type から移行する手助けをしてきました。正直に言うと、これは些細なプロジェクトではありません。文字エンコーディング周辺の癖、日本のコーポレートサイト固有のコンテンツ構造、一般的な WordPress-to-Next.js の移行とは異なる組織的な懸念があります。このガイドは、私が試行錯誤の中で学んだすべてをカバーしています。

Movable Type to Next.js Migration Guide for Japanese Companies

目次

日本企業が Movable Type を離れる理由

まず明白なことを言っておきましょう: Movable Type は死んでいません。Six Apart Japan はまだこれを保守しており、Movable Type 8(2024年後半にリリース)は現代的な機能を追加しました。しかし、いくつかの理由から、兆候は明らかです。

パフォーマンスの懸念

Movable Type は静的パブリッシング モデルを使用しています — コンテンツが変更されるとHTMLファイルを再構築します。15,000ページのサイトを持ち、コンテンツエディターが再構築の完了を20分待つまでは、これは素晴らしく聞こえます。日本の企業向けサイトでは、プロセスが非常に遅いため、エディターが夜間に再構築をスケジュールするケースを見てきました。

ISR(Incremental Static Regeneration)またはオンデマンド再検証を備えた Next.js は、これを完全に解決します。ページはミリ秒単位で個別に再生成されます。

所有コストの削減

2026年の日本での Movable Type ライセンスは、エンタープライズライセンスで年間約¥600,000~¥1,200,000です。ホスティング、プラグイン、カスタム開発の前に、CMS ライセンスだけで年間$4,000~$8,000 USD です。日本で人気のある microCMS などのヘッドレス CMS (ビジネスプランで月額¥4,900から開始) と Vercel の Next.js とペアリングした場合を比較すると、計算が非常に異なって見え始めます。

開発者不足

これは誰も公に話さない大きな問題です。Perl(Movable Type の言語)を知っており、MT テンプレートの操作をいとわない開発者を見つけることは、日本で本当に難しくなっています。私が出会った MT 経験のある開発者の中央年齢は45歳を超えています。一方、Next.js 開発者はいたるところにいます — 2026年の日本の技術企業が採用している フレームワークです。

セキュリティと コンプライアンス

Movable Type は長年にわたっていくつかの深刻な CVE を経験してきました。これには、日本のサイトに対して積極的に悪用された悪名高い XMLRPC 脆弱性(CVE-2021-20837)が含まれます。日本の改正 APPI(個人情報保護法)要件が2025~2026年に厳しくなるにつれて、企業は自社のセキュリティ体勢を再評価しています。

Movable Type のアーキテクチャの理解

移行を開始する前に、何から移行するのかを理解する必要があります。Movable Type のデータモデルは、WordPress やほとんどの最新的な CMS とは異なります。

コア データ構造

MT コンセプト 説明 Next.js/ヘッドレス相当物
Blog トップレベルのコンテンツ コンテナ サイトまたはワークスペース
Entry ブログ投稿または記事 コンテンツアイテム(ブログタイプ)
Page 静的ページ コンテンツアイテム(ページタイプ)
Category 階層タクソノミー カテゴリ/タグシステム
Template MT タグ付きHTMLテンプレート React コンポーネント + レイアウト
Custom Field 拡張エントリ フィールド コンテンツ モデル フィールド
Asset アップロードされたメディア ファイル メディア/アセット ライブラリ
Website ブログの親コンテナ マルチサイト構成

Movable Type のテンプレート言語は、<mt:EntryTitle><mt:Entries> などのタグを使用します。これらは最新のスタックのものと 1:1 でマップされません — プレゼンテーション層を最初から再構築する必要があります。

データベース レイヤー

MT は MySQL、PostgreSQL、SQLite をサポートしています。ほとんどの日本企業インストールは MySQL を使用しています。データベーススキーマはよく文書化されていますが...独特です。カスタム フィールドは key-value パターンを使用して別の mt_entry_meta テーブルに格納されており、これにより抽出が些細ではありません。

エントリ テーブルは次のようになります:

SELECT 
  entry_id,
  entry_title,
  entry_text,
  entry_text_more,
  entry_excerpt,
  entry_created_on,
  entry_modified_on,
  entry_basename,
  entry_status
FROM mt_entry
WHERE entry_blog_id = 1
  AND entry_status = 2  -- 2 = published
ORDER BY entry_created_on DESC;

entry_textentry_text_more の分割に注意してください。MT はボディコンテンツを2つのフィールドに分割します — ブログの初期段階からのパターンで、移行中に連結する必要があります。

Movable Type to Next.js Migration Guide for Japanese Companies - architecture

ヘッドレス CMS バックエンドの選択

Next.js はあなたのフロントエンド フレームワークです。しかし、コンテンツを管理する場所が必要です。日本企業向けに、4つの現実的なオプションに絞り込みました。

microCMS

これは日本企業のデフォルトの選択であり、理由があります。日本の企業によって構築され、ネイティブな日本語UI、日本語カスタマーサポート、日本のデータ レジデンシーがあります。料金は月額¥4,900から始まります(Hobby は小規模プロジェクト向けに無料)。API はクリーンで、Webhook サポートは Next.js ISR とうまく機能し、コンテンツエディターは英語スキルを必要としません。

Newt

日本企業によって構築された別のヘッドレス CMS で、人気が高まっています。microCMS よりも若干開発者に優しく、コンテンツモデリングの柔軟性が向上しています。複雑なコンテンツ構造を持つサイトに最適です。

Contentful

グローバル エンタープライズの選択肢。強力なローカライゼーション サポート、優れた API、および成熟したエコシステムがあります。日本企業にとっての欠点: サポートは英語で、UI は英語で、料金は USD です。2026年の料金では月額$300のTeamプラン で、日本の代替手段よりも大幅に高価です。

Sanity

Sanity を言及する理由は、技術的には優れており、カスタマイズ可能な Studio を日本語ラベルで構成できるからです。しかし、学習曲線は急勾配であり、Sanity 経験を持つ日本の開発者は多くありません。

CMS 日本語 UI 日本データ レジデンシー 開始価格 最適用途
microCMS ¥4,900/月 ほとんどの日本企業サイト
Newt ¥3,300/月 複雑なコンテンツ モデル
Contentful ❌ (EU/US) ~$300/月 グローバル エンタープライズ
Sanity 部分的 $99/月 (Team) 開発者中心のチーム

Movable Type から移行するほとんどの日本企業に対して、microCMS または Newt をお勧めします。すべてが日本語にあるという摩擦削減は、あなたが思っているよりも価値があります。当社は ヘッドレス CMS 開発プラクティス を通じてこれらすべてを広範に使用してきました。

コンテンツ監査とデータ抽出

ここが本当の仕事が始まるところです。監査フェーズをスキップしないでください — 実際に持っているものを理解せずに、抽出に直接飛び込んだために移行が失敗したケースを見てきました。

ステップ 1: すべてをインベントリする

MT データベースに接続して、カウントを実行します:

-- ブログ別にエントリをカウント
SELECT 
  b.blog_name,
  COUNT(e.entry_id) as entry_count
FROM mt_entry e
JOIN mt_blog b ON e.entry_blog_id = b.blog_id
WHERE e.entry_status = 2
GROUP BY b.blog_name;

-- ブログあたりのカスタム フィールドをカウント
SELECT 
  b.blog_name,
  em.entry_meta_type,
  COUNT(*) as field_count
FROM mt_entry_meta em
JOIN mt_entry e ON em.entry_meta_entry_id = e.entry_id
JOIN mt_blog b ON e.entry_blog_id = b.blog_id
GROUP BY b.blog_name, em.entry_meta_type;

ステップ 2: コンテンツをエクスポート

MT には組み込みのエクスポート形式がありますが、制限があります。Python スクリプトでの直接的なデータベース抽出を好みます:

import mysql.connector
import json
import html

def extract_mt_entries(config):
    conn = mysql.connector.connect(**config)
    cursor = conn.cursor(dictionary=True)
    
    cursor.execute("""
        SELECT 
            e.entry_id,
            e.entry_title,
            e.entry_text,
            e.entry_text_more,
            e.entry_excerpt,
            e.entry_basename,
            e.entry_created_on,
            e.entry_modified_on,
            GROUP_CONCAT(c.category_label) as categories
        FROM mt_entry e
        LEFT JOIN mt_placement p ON e.entry_id = p.placement_entry_id
        LEFT JOIN mt_category c ON p.placement_category_id = c.category_id
        WHERE e.entry_status = 2
        GROUP BY e.entry_id
    """)
    
    entries = cursor.fetchall()
    
    for entry in entries:
        # テキストと text_more を結合
        body = (entry['entry_text'] or '') + (entry['entry_text_more'] or '')
        entry['full_body'] = body
        # エンコーディングを処理
        entry['entry_title'] = entry['entry_title']
    
    with open('mt_export.json', 'w', encoding='utf-8') as f:
        json.dump(entries, f, ensure_ascii=False, default=str, indent=2)
    
    return entries

ステップ 3: メディア アセットの移行

MT は通常 /path/to/mt/support/uploads/ の下のファイル システムにアセットを格納します。以下を実行する必要があります:

  1. すべてのファイルをインベントリして、mt_asset のデータベース レコードにマッチング
  2. 新しい CMS または CDN(Cloudinary、imgix、または CMS の組み込みストレージ)に再アップロード
  3. コンテンツ本体 HTML のすべての参照を更新

これは面倒です。時間を確保してください。

日本語コンテンツの特殊性への対応

このセクションが、私がこの記事を書いた理由です。一般的な移行ガイドはこれらの問題をカバーしていません。

文字エンコーディング

古い Movable Type インストレーション(MT5 以前)は、データベースが名目上 UTF-8 であっても、コンテンツが EUC-JP または Shift_JIS エンコーディングで格納されていることがあります。実際のデータを確認してください:

# エンコーディングの問題を検出
import chardet

def check_encoding(text_bytes):
    result = chardet.detect(text_bytes)
    if result['encoding'] != 'utf-8':
        print(f"Warning: detected {result['encoding']} "
              f"with {result['confidence']:.0%} confidence")
    return result

エンコーディングのミスマッチが見つかった場合は、新しい CMS にインポートする前に、すべてを UTF-8 に変換してください。企業サイト上の壊れた文字化けは、キャリアに悪影響を与えるイベントです。

ルビ文字(ふりがな)

日本の企業向けサイトは、ルビ アノテーション(漢字文字の上に小さく付された読み方)を頻繁に使用します。MT テンプレートはしばしばカスタム タグでこれらを処理します。Next.js では、標準的な HTML <ruby> 要素を使用します:

// components/RubyText.tsx
export function RubyText({ base, reading }: { base: string; reading: string }) {
  return (
    <ruby>
      {base}
      <rp>(</rp>
      <rt>{reading}</rt>
      <rp>)</rp>
    </ruby>
  );
}

既存のルビ マークアップを保持するようにコンテンツ移行スクリプトが確実に保持されていることを確認してください。

日本語の日付フォーマット

日本の企業向けサイトは、令和8年1月15日など、和暦(日本の年号形式)で日付を表示することが多いです。Next.js コンポーネントでこれを処理します:

function formatJapaneseDate(dateString: string): string {
  const date = new Date(dateString);
  return date.toLocaleDateString('ja-JP-u-ca-japanese', {
    era: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  });
}

縦書きレイアウト

一部の日本のサイト、特に出版または伝統的な業界のサイトでは、縦書き(縦方向のテキスト)を使用しています。CSS がこれを処理します:

.vertical-text {
  writing-mode: vertical-rl;
  text-orientation: mixed;
}

Next.js はこれを問題なく処理しますが、ブラウザ全体でテストしてください。

Next.js フロントエンドの構築

コンテンツを抽出し、CMS を選択したので、構築する時が来ました。日本の企業向けサイトに推奨するアーキテクチャは次のとおりです。

静的生成を備えた App Router

Next.js 15 の App Router を使用して、ほとんどのページに対して静的生成を行います。日本の企業向けサイトは通常、コンテンツが多く、更新が頻繁ではありません — オンデマンド再検証での静的生成に最適です。

// app/news/[slug]/page.tsx
import { getArticle, getAllArticleSlugs } from '@/lib/cms';

export async function generateStaticParams() {
  const slugs = await getAllArticleSlugs();
  return slugs.map((slug) => ({ slug }));
}

export default async function NewsArticle({ 
  params 
}: { 
  params: Promise<{ slug: string }> 
}) {
  const { slug } = await params;
  const article = await getArticle(slug);
  
  return (
    <article>
      <h1>{article.title}</h1>
      <time dateTime={article.publishedAt}>
        {formatJapaneseDate(article.publishedAt)}
      </time>
      <div dangerouslySetInnerHTML={{ __html: article.body }} />
    </article>
  );
}

i18n 構成

多くの日本の企業向けサイトは、日本語版と英語版の両方が必要です。Next.js App Router は、ルートグループまたはミドルウェアベースのロケール検出で、これを処理します:

// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;
  const locale = pathname.startsWith('/en') ? 'en' : 'ja';
  
  request.headers.set('x-locale', locale);
  return NextResponse.next();
}

当社は Next.js を使用してダースの二言語日本企業向けサイトを構築してきました — 当社の Next.js 開発チーム はニュアンスを説明できます。

日本語検索向けSEO移行戦略

これは交渉不可能です。日本企業は Google 検索ランキングで生きています(Yahoo! Japan は Google のエンジンを使用しているため、実際には Google だけです)。ぼやけた移行は、有機トラフィックを数か月間停滞させる可能性があります。

URL マッピング

Movable Type は、設定可能なパターンを持つ URL を生成します。日本のサイトで見かける一般的なものは:

  • /blog/2024/01/entry-basename.html
  • /news/category/entry_basename.html
  • /archives/000123.html (最も古いパターン)

何かを構築する前に、完全な URL マッピングを作成してください:

// scripts/generate-redirects.ts
interface RedirectMap {
  source: string;
  destination: string;
  permanent: boolean;
}

function generateRedirects(mtEntries: MTEntry[]): RedirectMap[] {
  return mtEntries.map(entry => ({
    source: buildMTUrl(entry),  // 古い MT URL パターン
    destination: `/news/${entry.entry_basename}`,  // 新しい Next.js URL
    permanent: true,  // 301 リダイレクト
  }));
}

これらを next.config.ts に入力してください:

const nextConfig = {
  async redirects() {
    const redirects = await import('./redirects.json');
    return redirects.default;
  },
};

数千のリダイレクトを持つサイトの場合、代わりにミドルウェアを使用します — next.config.ts リダイレクトには実用的な制限があります。

構造化データ

日本の Google 結果は、リッチ スニペットを大きく特徴としています。記事、FAQ、組織情報に JSON-LD を追加してください:

function ArticleJsonLd({ article }: { article: Article }) {
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: article.title,
    datePublished: article.publishedAt,
    dateModified: article.updatedAt,
    author: {
      '@type': 'Organization',
      name: article.companyName,
    },
    inLanguage: 'ja',
  };

  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
    />
  );
}

デプロイとインフラストラクチャ

日本の視聴者にとって、レイテンシーは重要です。ここで機能するものは:

プラットフォーム 日本のエッジ ノード 最適用途 月額料金(典型的)
Vercel Tokyo ほとんどの Next.js サイト $20-150/月
AWS (CloudFront + Lambda@Edge) Tokyo, Osaka エンタープライズ コンプライアンス $100-500/月
Google Cloud Run + Cloud CDN Tokyo GCP ネイティブ チーム $50-200/月
Cloudflare Pages Tokyo + 多数 シンプルな静的サイト 無料-$25/月

Vercel が私のデフォルトの推奨事項です。Next.js のために目的を構築され、東京のエッジ ノードがあり、DX は比類のないものです。厳密なデータ レジデンシー要件を持つ企業(政府、金融)の場合、ap-northeast-1(東京)の AWS が安全な選択肢です。

Next.js の代わりに Astro をコンテンツが豊富で相互作用が最小限のサイトに対して検討している場合、それは有効な選択肢です — Astro 開発機能 を確認してください。

タイムラインと予算計画

完了した実際の移行に基づいて、期待できることは以下の通りです:

フェーズ 期間 主要活動
発見と監査 2~3週間 コンテンツ インベントリ、ステークホルダー インタビュー、URL マッピング
CMS セットアップとコンテンツ モデリング 2~4週間 スキーマ設計、コンテンツ移行スクリプト
コンテンツ移行 3~6週間 データ転送、メディア移行、QA
フロントエンド開発 6~10週間 Next.js ビルド、コンポーネント ライブラリ、i18n
SEO および QA 2~3週間 リダイレクト テスト、パフォーマンス チューニング、クロスブラウザ QA
ステージングロールアウト 1~2週間 DNS カットオーバー、監視、ホットフィックス

合計: 16~28週間 1,000~10,000ページの典型的な日本企業向けサイトの場合。

予算面では、複雑さに応じて ¥5,000,000~¥15,000,000($33,000~$100,000 USD)を見ている状態です。多くのように思えるかもしれませんが、あなたはすでに年間¥1,000,000 以上の MT ライセンスと専門的な開発に支払っている可能性があります。移行は、削減されたオペレーションコストと改善された開発者のベロシティを通じて、2~3年以内に自身の代金を払います。

あなたの特定の状況に関する詳細な見積もりが必要ですか?当社に連絡してください または 価格ページ でエンゲージメント モデルを確認してください。

FAQ

Next.js を使用して Movable Type をヘッドレス CMS として保持できますか?

技術的にはい — Movable Type 7 以上には、フロントエンドにコンテンツを提供できるデータ API があります。しかし、それは遅く、文書化が不十分で、再検証用の Webhook がありません。私はこのアプローチを1つのプロジェクトで試し、それをお勧めしません。MT の API 制限を回避するのに、適切なヘッドレス CMS に移行するよりも多くの時間を費やします。

MT 再構築モデルと Next.js ISR をどのように処理しますか?

それらは根本的に異なっています。MT は一度にサイト全体を再構築します(バッチ静的生成)。Next.js ISR はオンデマンドで個々のページを再生成します。これは、エディターが再構築の完了を待つ代わりに、インスタント パブリッシュ時間を取得することを意味します。メンタル モデルの転換は実際にはエディターにとって簡単です — 彼らは公開をクリックするだけで、ページは数秒以内にライブになります。

移行中に MT プラグインはどうなりますか?

すべての MT プラグインには、置き換えまたは再実装が必要です。一般的なもの(MT ベースのフォーム プラグインなど)は、Next.js フォーム処理または Formspree などのサービスに置き換えられます。検索プラグインは Algolia または CMS の組み込み検索に置き換えられます。監査フェーズ中に完全なプラグイン インベントリを作成してください。

移行中に Google ランキングが低下しますか?

できていますが、する必要はありません。重要な要素は: すべての URL に対する 301 リダイレクト、同一または改善されたページ タイトルとメタ説明の保持、内部リンク構造の保持、更新されたサイトマップの送信です。Google SEO 戦略をカバーしたアップグレードでランキングが実際に改善された移行を見てきました。理由は、新しいサイトがより高速で、Core Web Vitals スコアが向上していたからです。

Yahoo! Japan などの日本固有の SEO 要素をどのように処理しますか?

Yahoo! Japan は2010年以来 Google の検索エンジンを使用しているため、Google SEO 戦略は Yahoo! をカバーしています。唯一の例外は Yahoo! Japan の独自プロパティ(Yahoo! News など)で、別の送信プロセスがあります。一般的なオーガニック検索については、Google に焦点を当てており、カバーしています。

すべてのコンテンツを移行すべきか、それともこれをクリーンアップする機会として使用すべきですか?

常にクリーンアップしてください。完了したすべての日本企業向けサイト移行では、コンテンツの30~50%は古く、冗長であるか、ゼロトラフィック でした。デッド コンテンツを移行するのは無駄な時間であり、サイトのトピック的権限を薄めます。アナリティクス データを使用して、移行する価値があるページを識別し、残りを放置してください(404ではなく、410 Gone レスポンスを含めて)。

移行中に Movable Type と Next.js を並行して実行できますか?

はい、またはお勧めします。サブドメインまたはパスベースのルーティングを使用して、新しい Next.js サイトを移行されたセクション用に提供し、MT が残りを処理しながら。これにより、危険な大規模な切り替えの代わりに、フェーズで移行できます。nginx または Cloudflare Workers を使用したリバース プロキシ構成はこれを簡潔にします。

Movable Type の組み込みアクセス制御とメンバー機能について

MT サイトがメンバー ログイン、ゲートされたコンテンツ、またはロールベースのアクセスを使用している場合、Next.js で認証を実装する必要があります。NextAuth.js(現在 Auth.js)はこれに適切に機能するか、Clerk または Auth0 などのサービスを使用できます。これにより複雑さとコストが追加されます — 初日から計画に含めてください。