Next.jsでインタラクティブコンテンツを作る技術スタック
ネタラボの技術基盤を紹介。Next.js App Router、Leaflet、Tailwind CSSを使ったインタラクティブWebコンテンツの開発手法。
ネタラボは「面白いネタを、インタラクティブに」をコンセプトにしたWebサイトです。地図コンテンツ、診断ツール、データ可視化など、多様なインタラクティブコンテンツを提供しています。
この記事では、ネタラボの技術基盤について紹介します。
全体のアーキテクチャ
ネタラボはNext.js(App Router)をベースに構築されています。主要な技術スタックは以下の通りです。
- フレームワーク: Next.js 16(App Router)
- 言語: TypeScript
- スタイリング: Tailwind CSS
- 地図ライブラリ: Leaflet + react-leaflet
- デプロイ: VPS(PM2でプロセス管理)
App Routerの活用
Next.js 13以降のApp Routerを採用しています。Server ComponentとClient Componentの使い分けが、インタラクティブコンテンツとの相性で重要なポイントです。
Server Component
ページのレイアウト、メタデータ生成、静的なコンテンツ部分はServer Componentで処理します。SEO対策として、各コンテンツのメタデータはサーバーサイドで生成しています。
Client Component
地図の操作、フォーム入力、アニメーションなど、ユーザーインタラクションが必要な部分はClient Componentとして実装します。'use client' ディレクティブを適切に配置し、クライアントバンドルのサイズを最小化しています。
地図コンテンツの実装
ネタラボの主力コンテンツである地図系は、Leafletをベースにしています。
なぜLeafletを選んだか
- 軽量: MapboxやGoogle Mapsと比較してバンドルサイズが小さい
- オープンソース: 無料で商用利用可能
- プラグインが豊富: マーカークラスタリング、ヒートマップなど
- 学習コストが低い: APIがシンプルで直感的
SSR対応の注意点
Leafletはブラウザのwindowオブジェクトに依存するため、Server Componentでは動作しません。next/dynamic の ssr: false オプションで動的インポートし、クライアントサイドでのみレンダリングしています。
const MapComponent = dynamic(
() => import('@/components/map/MapView'),
{ ssr: false }
);
データ管理の方針
ネタラボのコンテンツデータは、JSONファイルで管理しています。データベースを使わない理由は以下の通りです。
- デプロイの簡便さ: DBサーバーの管理が不要
- バージョン管理: Gitで変更履歴を追跡可能
- パフォーマンス: ファイル読み込みは十分高速(コンテンツ数が数十件レベル)
ブログ記事のみ、MDXファイルとメタデータJSONの二重管理を採用しています。これはMarkdownの表現力を活かしつつ、一覧表示用のメタデータを効率的に取得するためです。
Tailwind CSSとデザインシステム
CSSカスタムプロパティ(CSS変数)とTailwind CSSを組み合わせて、一貫したデザインシステムを構築しています。
カラーパレットはCSS変数で定義し、Tailwindのカスタムカラーとして登録しています。これにより、テーマの変更が容易で、ダークモード対応もprefers-color-schemeメディアクエリで実現しています。
今後の展望
現在検討中の技術的な改善点は以下の通りです。
- ISR(Incremental Static Regeneration)の活用: 頻繁に更新されないページのビルド時間短縮
- Web Workerの活用: 大量データの処理をメインスレッドから分離
- PWA対応: オフラインでも一部コンテンツを閲覧可能に
技術的な詳細や実装のtipsは、今後のブログ記事でも随時紹介していきます。