シンプルなブログアーキテクチャの作成

この例では、ブログ投稿はアプリケーションのディレクトリ内のローカルマークダウンファイルとして保存されます(外部データソースから取得されません)。そのため、ファイルシステムからデータを読み取る必要があります。

このセクションでは、ファイルシステムからマークダウンデータを読み取るブログを作成する手順を説明します。

マークダウンファイルの作成

まず、ルートフォルダに posts という新しいトップレベルディレクトリを作成します(これは pages/posts とは異なります)。posts ディレクトリ内に、pre-rendering.mdssg-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を使用してデータを取得することもできます。

各マークダウンファイルの上部には、titledate を含むメタデータセクションがあることに気づいたかもしれません。これはYAML Front Matterと呼ばれ、gray-matterというライブラリを使用して解析できます。

gray-matterのインストール

まず、各マークダウンファイルのメタデータを解析するためにgray-matterをインストールします。

npm install gray-matter

ファイルシステムを読み取るユーティリティ関数の作成

次に、ファイルシステムからデータを解析するためのユーティリティ関数を作成します。このユーティリティ関数で実現したいことは:

  • 各マークダウンファイルを解析し、titledate、およびファイル名(投稿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を学ぶ上で、上記のコードが何をしているかを理解する必要はありません。この関数はブログの例を機能させるためのものです。ただし、さらに詳しく知りたい場合:

  • fs は、ファイルシステムからファイルを読み取るNode.jsモジュールです。
  • path は、ファイルパスを操作するNode.jsモジュールです。
  • matter は、各マークダウンファイルのメタデータを解析するライブラリです。
  • Next.jsでは、libフォルダはpagesフォルダのように決まった名前がありません。そのため、任意の名前を付けることができます。通常はlibまたはutilsという名前が使われます。

ブログデータの取得

ブログデータが解析されたので、これをインデックスページ(pages/index.js)に追加する必要があります。これは、Next.jsのデータ取得メソッドであるgetStaticProps()を使用して行うことができます。次のセクションでは、getStaticProps()の実装方法を学びます。

インデックスページ

次のページで実装しましょう!

On this page