シンプルなブログアーキテクチャの作成
この例では、ブログ投稿はアプリケーションのディレクトリ内のローカルマークダウンファイルとして保存されます(外部データソースから取得されません)。そのため、ファイルシステムからデータを読み取る必要があります。
このセクションでは、ファイルシステムからマークダウンデータを読み取るブログを作成する手順を説明します。
マークダウンファイルの作成
まず、ルートフォルダに posts
という新しいトップレベルディレクトリを作成します(これは pages/posts
とは異なります)。posts
ディレクトリ内に、pre-rendering.md
と ssg-ssr.md
という2つのファイルを作成します。
次に、以下のコードを posts/pre-rendering.md
にコピーします:
---
title: 'プリレンダリングの2つの形式'
date: '2020-01-01'
---
Next.jsには、プリレンダリングの2つの形式があります:**静的生成 (Static Generation)** と **サーバーサイドレンダリング (Server-side Rendering)** です。違いは、ページのHTMLを**いつ**生成するかにあります。
- **静的生成**は、**ビルド時**にHTMLを生成するプリレンダリング方法です。プリレンダリングされたHTMLは、各リクエストで_再利用_されます。
- **サーバーサイドレンダリング**は、**各リクエストごと**にHTMLを生成するプリレンダリング方法です。
重要な点として、Next.jsでは各ページに対して使用するプリレンダリング形式を**選択**できます。ほとんどのページに静的生成を使用し、他のページにサーバーサイドレンダリングを使用することで、「ハイブリッド」なNext.jsアプリを作成できます。
次に、以下のコードを posts/ssg-ssr.md
にコピーします:
---
title: '静的生成とサーバーサイドレンダリングの使い分け'
date: '2020-01-02'
---
可能な限り**静的生成**(データあり・なし両方)を使用することをお勧めします。なぜなら、ページは一度ビルドされ、CDNによって配信されるため、サーバーが毎回ページをレンダリングするよりもはるかに高速だからです。
静的生成は、以下のような多くの種類のページに使用できます:
- マーケティングページ
- ブログ投稿
- Eコマース商品リスト
- ヘルプとドキュメント
「ユーザーのリクエストに先立ってこのページをプリレンダリングできるか?」と自問してください。答えが「はい」なら、静的生成を選択すべきです。
一方、ユーザーのリクエストに先立ってページをプリレンダリングできない場合、静的生成は**良いアイデアではありません**。たとえば、ページに頻繁に更新されるデータが表示され、ページの内容がリクエストごとに変更される場合です。
そのような場合は、**サーバーサイドレンダリング**を使用できます。速度は遅くなりますが、プリレンダリングされたページは常に最新の状態になります。または、プリレンダリングをスキップし、クライアントサイドJavaScriptを使用してデータを取得することもできます。
各マークダウンファイルの上部には、
title
とdate
を含むメタデータセクションがあることに気づいたかもしれません。これはYAML Front Matterと呼ばれ、gray-matterというライブラリを使用して解析できます。
gray-matterのインストール
まず、各マークダウンファイルのメタデータを解析するためにgray-matterをインストールします。
npm install gray-matter
ファイルシステムを読み取るユーティリティ関数の作成
次に、ファイルシステムからデータを解析するためのユーティリティ関数を作成します。このユーティリティ関数で実現したいことは:
- 各マークダウンファイルを解析し、
title
、date
、およびファイル名(投稿URLのid
として使用)を取得する。 - 日付でソートされたデータをインデックスページに一覧表示する。
ルートディレクトリにlib
というトップレベルディレクトリを作成します。次に、lib
内にposts.js
というファイルを作成し、以下のコードをコピーして貼り付けます:
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// /posts 配下のファイル名を取得
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// ファイル名から ".md" を削除してidを取得
const id = fileName.replace(/\.md$/, '');
// マークダウンファイルを文字列として読み込む
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// gray-matterを使用して投稿のメタデータセクションを解析
const matterResult = matter(fileContents);
// データとidを結合
return {
id,
...matterResult.data,
};
});
// 投稿を日付でソート
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1;
} else {
return -1;
}
});
}
注:
Next.jsを学ぶ上で、上記のコードが何をしているかを理解する必要はありません。この関数はブログの例を機能させるためのものです。ただし、さらに詳しく知りたい場合:
ブログデータの取得
ブログデータが解析されたので、これをインデックスページ(pages/index.js
)に追加する必要があります。これは、Next.jsのデータ取得メソッドであるgetStaticProps()
を使用して行うことができます。次のセクションでは、getStaticProps()
の実装方法を学びます。
次のページで実装しましょう!