If you've worked with Japanese enterprise websites for any length of time, you've almost certainly encountered Movable Type. Six Apart's CMS has had a remarkably strong grip on the Japanese market since the mid-2000s, powering everything from corporate sites at major manufacturers to government portals and university websites. But here's the thing -- it's 2026, and the web has moved on. Your Movable Type installation probably hasn't.

I've helped migrate several Japanese enterprise sites off Movable Type over the past two years, and I'll be honest: it's not a trivial project. There are quirks around character encoding, content structures unique to Japanese corporate sites, and organizational concerns that make these migrations different from your typical WordPress-to-Next.js move. This guide covers everything I've learned the hard way.

Movable Type to Next.js Migration Guide for Japanese Companies

Table of Contents

Why Japanese Companies Are Leaving Movable Type

Let's get the obvious out of the way: Movable Type isn't dead. Six Apart Japan still maintains it, and Movable Type 8 (released in late 2024) added some modern features. But the writing is on the wall for several reasons.

Performance Concerns

Movable Type uses a static publishing model -- it rebuilds HTML files when content changes. This sounds great until you have a site with 15,000 pages and a content editor waiting 20 minutes for a rebuild to finish. I've seen Japanese corporate sites where editors would schedule rebuilds overnight because the process was so slow.

Next.js with ISR (Incremental Static Regeneration) or on-demand revalidation solves this completely. Pages regenerate individually in milliseconds.

Cost of Ownership

Movable Type licensing in Japan runs roughly ¥600,000-¥1,200,000 per year for enterprise licenses as of 2026. That's $4,000-$8,000 USD annually just for the CMS license, before hosting, plugins, or custom development. Compare that to a headless CMS like microCMS (popular in Japan, starting at ¥4,900/month for business plans) paired with Next.js on Vercel, and the math starts looking very different.

Developer Shortage

This is the big one nobody talks about publicly. Finding developers who know Perl (Movable Type's language) and are willing to work on MT templates is getting genuinely difficult in Japan. The median age of MT-experienced developers I've encountered is north of 45. Meanwhile, Next.js developers are everywhere -- it's the framework Japanese tech companies are hiring for in 2026.

Security and Compliance

Movable Type has had several serious CVEs over the years, including the infamous XMLRPC vulnerability (CVE-2021-20837) that was actively exploited against Japanese sites. With Japan's amended APPI (Act on the Protection of Personal Information) requirements tightening in 2025-2026, companies are re-evaluating their security posture.

Understanding Movable Type's Architecture

Before you can migrate, you need to understand what you're migrating from. Movable Type's data model is different from WordPress or most modern CMSes.

Core Data Structures

MT Concept Description Next.js/Headless Equivalent
Blog Top-level content container Site or workspace
Entry Blog post or article Content item (blog type)
Page Static page Content item (page type)
Category Hierarchical taxonomy Category/tag system
Template HTML templates with MT tags React components + layouts
Custom Field Extended entry fields Content model fields
Asset Uploaded media files Media/asset library
Website Parent container for blogs Multi-site configuration

Movable Type's template language uses tags like <mt:EntryTitle> and <mt:Entries>. These don't map 1:1 to anything in the modern stack -- you'll be rebuilding the presentation layer from scratch.

The Database Layer

MT supports MySQL, PostgreSQL, and SQLite. Most Japanese enterprise installations use MySQL. The database schema is well-documented but... eccentric. Custom fields are stored in a separate mt_entry_meta table using a key-value pattern, which makes extraction non-trivial.

Here's what the entry table looks like:

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;

Note the entry_text and entry_text_more split. MT splits body content into two fields -- a pattern from the early blogging era that you'll need to concatenate during migration.

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

Choosing Your Headless CMS Backend

Next.js is your frontend framework. But you need somewhere to manage content. For Japanese companies, I've narrowed it down to four realistic options.

microCMS

This is the default choice for Japanese companies, and for good reason. It's built by a Japanese company, has native Japanese UI, Japanese customer support, and data residency in Japan. Pricing starts at ¥4,900/month (Hobby is free for small projects). The API is clean, the webhook support works well with Next.js ISR, and your content editors won't need English skills.

Newt

Another Japanese-made headless CMS that's been gaining traction. It's slightly more developer-friendly than microCMS and has better content modeling flexibility. Good option if your site has complex content structures.

Contentful

The global enterprise choice. Strong localization support, excellent API, and a mature ecosystem. The downside for Japanese companies: support is in English, the UI is in English, and pricing is in USD. At $300/month for the Team plan (2026 pricing), it's significantly more expensive than Japanese alternatives.

Sanity

I mention Sanity because it's technically excellent, and its customizable Studio can be configured with Japanese labels. But the learning curve is steeper, and you won't find as many Japanese developers with Sanity experience.

CMS Japanese UI Japan Data Residency Starting Price Best For
microCMS ¥4,900/mo Most Japanese corporate sites
Newt ¥3,300/mo Complex content models
Contentful ❌ (EU/US) ~$300/mo Global enterprises
Sanity Partial $99/mo (Team) Developer-heavy teams

For most Japanese companies migrating from Movable Type, I recommend microCMS or Newt. The friction reduction of having everything in Japanese is worth more than you'd think. We've worked extensively with all of these through our headless CMS development practice.

Content Audit and Data Extraction

This is where the real work begins. Don't skip the audit phase -- I've seen migrations fail because teams jumped straight to extraction without understanding what they actually had.

Step 1: Inventory Everything

Connect to your MT database and run counts:

-- Count entries by blog
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;

-- Count custom fields per blog
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;

Step 2: Export Content

MT has a built-in export format, but it's limited. I prefer direct database extraction with a Python script:

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:
        # Combine text and text_more
        body = (entry['entry_text'] or '') + (entry['entry_text_more'] or '')
        entry['full_body'] = body
        # Handle encoding
        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

Step 3: Media Asset Migration

MT stores assets on the filesystem, usually under /path/to/mt/support/uploads/. You'll need to:

  1. Inventory all files and match them to database records in mt_asset
  2. Re-upload to your new CMS or a CDN (Cloudinary, imgix, or your CMS's built-in storage)
  3. Update all references in your content body HTML

This is tedious. Budget time for it.

Handling Japanese Content Specifics

This section is why I wrote this article. Generic migration guides don't cover these issues.

Character Encoding

Older Movable Type installations (pre-MT5) sometimes stored content in EUC-JP or Shift_JIS encoding, even if the database was nominally UTF-8. Check your actual data:

# Detect encoding issues
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

If you find encoding mismatches, convert everything to UTF-8 before importing into your new CMS. Broken mojibake (文字化け) on a corporate site is a career-limiting event.

Ruby Text (Furigana)

Japanese corporate sites frequently use ruby annotations -- small reading aids above kanji characters. MT templates often handle these with custom tags. In Next.js, you'll use standard HTML <ruby> elements:

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

Make sure your content migration script preserves any existing ruby markup.

Japanese Date Formatting

Japanese corporate sites often display dates in 和暦 (Japanese era format): 令和8年1月15日 instead of 2026-01-15. Handle this in your Next.js components:

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',
  });
}

Vertical Text Layouts

Some Japanese sites, particularly in publishing or traditional industries, use vertical text (縦書き). CSS handles this:

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

Next.js handles this fine, but test thoroughly across browsers.

Building the Next.js Frontend

With your content extracted and your CMS chosen, it's time to build. Here's the architecture I recommend for Japanese corporate sites.

App Router with Static Generation

Use Next.js 15's App Router with static generation for most pages. Japanese corporate sites are typically content-heavy with infrequent updates -- perfect for static generation with on-demand revalidation.

// 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 Configuration

Many Japanese corporate sites need both Japanese and English versions. Next.js App Router handles this with route groups or middleware-based locale detection:

// 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();
}

We've built dozens of bilingual Japanese corporate sites using Next.js -- our Next.js development team can walk you through the nuances.

This is non-negotiable. Japanese companies live and die by their Google search rankings (Yahoo! Japan uses Google's engine, so it's really just Google). A botched migration can tank organic traffic for months.

URL Mapping

Movable Type generates URLs with configurable patterns. Common ones I see on Japanese sites:

  • /blog/2024/01/entry-basename.html
  • /news/category/entry_basename.html
  • /archives/000123.html (the oldest pattern)

Create a complete URL mapping before you build anything:

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

function generateRedirects(mtEntries: MTEntry[]): RedirectMap[] {
  return mtEntries.map(entry => ({
    source: buildMTUrl(entry),  // Old MT URL pattern
    destination: `/news/${entry.entry_basename}`,  // New Next.js URL
    permanent: true,  // 301 redirect
  }));
}

Put these in your next.config.ts:

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

For sites with thousands of redirects, use middleware instead -- next.config.ts redirects have a practical limit.

Structured Data

Japanese Google results heavily feature rich snippets. Add JSON-LD for articles, FAQs, and organization info:

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) }}
    />
  );
}

Deployment and Infrastructure

For Japanese audiences, latency matters. Here's what works:

Platform Japan Edge Nodes Best For Monthly Cost (typical)
Vercel Tokyo Most Next.js sites $20-150/mo
AWS (CloudFront + Lambda@Edge) Tokyo, Osaka Enterprise compliance $100-500/mo
Google Cloud Run + Cloud CDN Tokyo GCP-native teams $50-200/mo
Cloudflare Pages Tokyo + many Simple static sites Free-$25/mo

Vercel is my default recommendation. It's purpose-built for Next.js, has a Tokyo edge node, and the DX is unmatched. For companies with strict data residency requirements (government, financial), AWS in ap-northeast-1 (Tokyo) is the safe choice.

If you're considering Astro instead of Next.js for a content-heavy site with minimal interactivity, that's a valid choice too -- check our Astro development capabilities.

Timeline and Budget Planning

Based on actual migrations I've completed, here's what to expect:

Phase Duration Key Activities
Discovery & Audit 2-3 weeks Content inventory, stakeholder interviews, URL mapping
CMS Setup & Content Modeling 2-4 weeks Schema design, content migration scripts
Content Migration 3-6 weeks Data transfer, media migration, QA
Frontend Development 6-10 weeks Next.js build, component library, i18n
SEO & QA 2-3 weeks Redirect testing, performance tuning, cross-browser QA
Staged Rollout 1-2 weeks DNS cutover, monitoring, hotfixes

Total: 16-28 weeks for a typical Japanese corporate site with 1,000-10,000 pages.

Budget-wise, you're looking at ¥5,000,000-¥15,000,000 ($33,000-$100,000 USD) depending on complexity. That might seem like a lot, but consider: you're likely paying ¥1,000,000+ annually for MT licensing and specialized development already. The migration pays for itself within 2-3 years through reduced operational costs and improved developer velocity.

Need a detailed estimate for your specific situation? Reach out to us or check our pricing page for engagement models.

FAQ

Can we keep using Movable Type as a headless CMS with Next.js?

Technically yes -- Movable Type 7+ has a Data API that can serve content to a frontend. But it's slow, poorly documented, and lacks webhooks for revalidation. I've tried this approach on one project and wouldn't recommend it. You'll spend more time working around MT's API limitations than you would migrating to a proper headless CMS.

How do we handle the MT rebuild model vs. Next.js ISR?

They're fundamentally different. MT rebuilds entire site sections at once (batch static generation). Next.js ISR regenerates individual pages on demand. This means your editors get instant publish times instead of waiting for rebuilds. The mental model shift is actually easier for editors -- they just hit publish and the page is live within seconds.

What happens to our MT plugins during migration?

Every MT plugin needs a replacement or re-implementation. Common ones like contact forms (MT-based form plugins) get replaced with Next.js form handling or services like Formspree. Search plugins get replaced with Algolia or the CMS's built-in search. Make a complete plugin inventory during the audit phase.

Will our Google rankings drop during migration?

They can, but they don't have to. The critical factors are: 301 redirects for every URL, maintaining identical or improved page titles and meta descriptions, preserving internal link structure, and submitting an updated sitemap. I've seen migrations where rankings actually improved because the new site was faster and had better Core Web Vitals scores.

How do we handle Japanese-specific SEO elements like Yahoo! Japan?

Yahoo! Japan has used Google's search engine since 2010, so your Google SEO strategy covers Yahoo! too. The one exception is Yahoo! Japan's own properties (Yahoo! News, etc.) which have separate submission processes. For general organic search, focus on Google and you're covered.

Should we migrate all content or use this as an opportunity to clean up?

Always clean up. In every Japanese corporate site migration I've done, 30-50% of content was outdated, redundant, or had zero traffic. Migrating dead content wastes time and dilutes your site's topical authority. Use analytics data to identify pages worth migrating and let the rest go (with proper 410 Gone responses, not 404s).

Can we run Movable Type and Next.js in parallel during migration?

Yes, and I recommend it. Use a subdomain or path-based routing to serve the new Next.js site for migrated sections while MT handles the rest. This lets you migrate in phases rather than doing a risky big-bang cutover. Reverse proxy configurations with nginx or Cloudflare Workers make this straightforward.

What about Movable Type's built-in access control and member features?

If your MT site uses member login, gated content, or role-based access, you'll need to implement authentication in Next.js. NextAuth.js (now Auth.js) works well for this, or you can use a service like Clerk or Auth0. This adds complexity and cost -- factor it into your planning from day one.