システム開発

Next.js 16の静的書き出し(output export)とMDXでテックブログを作る方法

  • #Next.js
  • #MDX
  • #静的サイト

スエキチシステムのサイトは、Next.js 16 の静的書き出し(output: 'export')で運用しています。今回、この構成を変えずにテックブログを追加しました。この記事では、その実装手順と、つまずいたポイントを紹介します。

静的書き出しのままブログは作れるのか?

結論として、作れます。記事を MDX ファイルで管理し、generateStaticParams で全記事のパスを列挙すれば、ビルド時にすべての記事が HTML として書き出されます。

一方で、静的書き出しでは次の機能が使えません。

使えない機能ブログでの影響対応
ISR(再検証)公開後に自動更新できない記事追加時に再ビルドする
リダイレクト・リライト旧URLの転送ができないホスティング側で設定する
画像最適化(デフォルトローダー)自動でリサイズされないWebPに変換してから配置する

@next/mdx をどう設定するか?

next.config.ts を createMDX でラップします。ポイントは、Turbopack ではプラグインを文字列で指定することです。関数を渡すとビルドに失敗します。

next.config.ts
import createMDX from '@next/mdx';
 
const withMDX = createMDX({
  options: {
    remarkPlugins: ['remark-frontmatter', 'remark-gfm'],
    rehypePlugins: [
      'rehype-slug',
      ['rehype-pretty-code', { theme: 'github-light', keepBackground: false }],
    ],
  },
});
 
export default withMDX(nextConfig);

App Router では、プロジェクト直下に mdx-components.tsx も必要です。ここで <a> を差し替え、サイト内リンクは next/link、外部リンクは別タブで開くようにしました。

記事ページはどう生成するか?

記事一覧やメタデータは、gray-matter で MDX の frontmatter を読み取って作ります。本文の描画は dynamic import に任せます。

app/blog/[slug]/page.tsx
export const dynamicParams = false;
 
export function generateStaticParams() {
  return getAllPosts().map((post) => ({ slug: post.slug }));
}
 
export default async function BlogPostPage({ params }) {
  const { slug } = await params;
  const { default: Content } = await import(`../../../content/blog/${slug}.mdx`);
  return <Content />;
}

frontmatter はビルド時に検証し、必須項目が抜けていればエラーで止めるようにしています。公開後に「説明文が空だった」という事故を防げます。

静的書き出しで気をつける点は?

generateStaticParams が空だとビルドが失敗する

静的書き出しでは、動的ルートの generateStaticParams が空配列を返すとビルドエラーになります。ページ送り(/blog/page/[n])は記事が少ないと対象ページがなくなるため、1ページ目も生成したうえで canonical を /blog に向け、noindex にしました。

目次の id を本文と一致させる

目次は h2・h3 から自動生成しています。見出しの id は rehype-slug が付けるため、目次側も同じ github-slugger で id を作ることで、リンク先が必ず一致します。

このブログで行っているサイトマップとRSSの設定はXMLサイトマップのpriorityは不要?RSSとの使い分けと推奨設定で、AI検索に引用されるための対策はLLMO(AI検索最適化)とは?ChatGPTやAI Overviewsに引用されるための対策で紹介しています。

まとめ

  • output: 'export' のままでも、MDX ブログは十分に作れる
  • Turbopack ではプラグインを文字列で指定する
  • 静的書き出し特有の制約(空の generateStaticParams など)を先に把握しておく

同じ構成でコーポレートサイトやブログの制作を検討している方は、お気軽にご相談ください。

よくある質問

output export でもMDXのブログは作れますか?

作れます。記事はビルド時にすべてHTMLとして書き出されるため、サーバーなしで配信できます。ただし記事を追加するたびに再ビルドが必要です。

Turbopack で rehype-pretty-code は使えますか?

使えます。next.config の rehypePlugins に ['rehype-pretty-code', { theme: 'github-light' }] のように文字列とシリアライズ可能なオプションで指定します。

CMSを使わずにMDXファイルで管理するメリットは?

記事がGitで管理でき、レビューや差分確認がしやすい点です。外部サービスへの依存や月額費用もかかりません。

システム開発のご相談はスエキチシステムへ

要件が固まっていなくても大丈夫です。まずはお気軽にご相談ください。

この記事を書いた会社

スエキチシステム

「企業品質を、個人価格で。」を掲げる福岡のシステム開発会社。HP制作・業務システム開発・LINE予約アプリ・AI導入支援を手がけています。 開発現場で得た知見を発信しています。

IT・システムの仕組みは、YouTubeのショート動画でも解説しています:システムのオタク