107
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Next.js + microCMS + NetlifyでJAMstackな世界に入門する

追記:

Next.js v9.3以降SSGに関するAPIの変更や、環境変数の扱い方が変わったので、対応した記事に書き換えました。

はじめに

この記事はJAMstack Advent Calendar 2019 7日目の記事です。

こんにちはかみむらです。最近は、Twitter上でJAMstackアーキテクチャーについての情報をシェアしています。

先日、個人のポートフォリオをJAMstackアーキテクチャーな構成で立ち上げました。このサイトの技術スタックはNext.js(静的サイト) + microCMSでホスティングサービスにNetlifyを利用しています。

JAMstackは静的なJavaScript、独立したAPI、ビルド済みのマークアップを総称したアーキテクチャーで、今回作成したウェブサイトはこれらの要件を満たしていることになります。もしJAMstackアーキテクチャーをもっと詳しく知りたい場合は、こちらの公式サイトをご参照ください。
https://jamstack.org/

そして、Googleが公式で開発しているウェブサービスの品質を測定できるツール「Lighthouse」でポートフォリオの数値を測定した結果がこちらです。環境で多少の誤差はありますが、非常にハイパフォーマンスな数値が出ています。

Screenshot from 2019-12-06 12-16-57.png

JAMstackアーキテクチャーでウェブを構成する利点の一つに、JavaScript(フロントエンド)に重点を置けることがあります。ヘッドレスCMSのmicroCMSやNetlifyの登場で、今までサーバーにかけていた工数が大幅に減るので、その分パフォーマンスチューニングUX向上に時間をかけることが出来ます。そして、フロントエンドに注力できることはフロントエンドの開発者にとってDXを高めることに繋がります。

デモ

こちらにNext.js + microCMSのデモコードがあります。
https://github.com/hiro08gh/next-microcms-ssg

今回作るJAMstackなサイトの全体像

上記で説明した技術スタックを使っていきます。フロントエンドはNext.jsで構成して、apiをmicroCMSでコンテンツ管理をします。microCMSとは日本製のヘッドレスCMSで、リクエストヘッダーにapiキーを含めて送ることで、データを取得することができます。そして、Next.jsで生成する静的なファイルをNetlifyでホスティングします。

microCMSのコンテンツモデル作成

スクリーンショット 2019-12-05 17.43.10.png

まずはmicroCMSでコンテンツモデルを作成します。下記のリンクからアカウント作成を行ってください。
https://microcms.io/

作成するコンテンツモデルは簡易的なブログを想定しています。

blogsというモデルに対して、tagsというモデルがリレーションされています。そして、blogstagsを複数持つことが出来ます。それでは早速作っていきましょう。

アカウント作成後、サービス名サービスIDを入力します。サービスIDはエンドポイントのドメインになるので、関連するワードにしたほうがいいかもしれません。

スクリーンショット 2019-12-04 21.11.52.png

ステップ2のサービス画像は後から設定できるのでスキップでも大丈夫です。

それではコンテンツを作成していきます。まずはタグのコンテンツモデルから作成します。APIの名前とエンドポイントを入力します。ここではタグtagsを入力しました。

スクリーンショット 2019-12-04 21.19.01.png

そしてapiの型を設定します。こちらはリスト形式にします。

スクリーンショット 2019-12-05 21.03.10.png

APIスキーマを定義します。タグはnameのスキーマを一つ持っています。

スクリーンショット 2019-12-05 21.05.50.png

続いてブログのコンテンツモデルを作成します。API名はブログでエンドポイントはblogsにしました。

スクリーンショット 2019-12-05 21.06.45.png

こちらも続いてリスト形式にします。
スクリーンショット 2019-12-05 21.03.10.png

ブログのコンテンツモデルはこちらです。タグのスキーマを複数コンテンツ参照にします。これでブログタグのリレーションを作ることができました。

スクリーンショット 2019-12-07 7.37.54.png

microCMSのコンテンツモデルができました。フロント側で取得するために、いくつかコンテンツを作成してみましょう。

サイドバーにあるタグをクリックして、追加をクリックします。

スクリーンショット 2019-12-05 21.14.05.png

タグ名を入力します。入力値はなんでも大丈夫です。そして公開します。
スクリーンショット 2019-12-05 21.14.14.png

ブログのコンテンツも作成します。
スクリーンショット 2019-12-07 7.32.34.png

これでリレーションを含むコンテンツを作成出来てしまいました。microCMSは導入障壁が非常に低いので、最高ですね。

Next.jsプロジェクトの作成

次にJAMstackのJ(JavaScript)部分を構築していきます。create-next-appという便利なCLIライブラリがあるので、これでプロジェクトの雛形を作っていきます。

$ npx create-next-app my-app

Default Starter appを選択してプロジェクトを作成してください。

スクリーンショット 2020-05-19 10.00.32.png

microCMSではリクエストヘッダーにapiキーを含めてリクエストを送ります。セキュリティー確保のため、apiキーは.envファイルに保存する必要があります。

そして.env.development.localファイルを作成して、microCMSのAPIキーを追加します。XXXXXXの部分を置き換えてください。APIキーはmicroCMSの設定から取得することが出来ます。

スクリーンショット 2019-12-05 21.22.54.png

.env.development.local
API_KEY=XXXXXXXXXXXXXXXX

これでプロジェクトのセットアップは完了です。

microCMSからデータを取ってくる処理

microCMSのコンテンツデータを取得します。フロントエンド側で取得するため、isomorphic-unfetchをインストールします。

$ yarn add isomorphic-unfetch

追記: isomorphic-unfetchは必要なくなりました。データ取得はfetch apiですることができます。

そして、pagesフォルダにあるindex.jsの内容を書き換えます。https://your.microcms.io/api/v1/blogs/には先ほど作成したmicroCMSのURLを入れます。

index.js
import fetch from 'isomorphic-unfetch';
import Link from 'next/link';

const Home = ({blogs}) => {
  return (
    <div>
      <h2>最新の記事</h2>
      <div>
        {blogs.map(blog => (
          <React.Fragment key={blog.id}>
            <Link href="/blogs/[id]" as={`blogs/${blog.id}`}>
              <a>
                <h2>{blog.title}</h2>
              </a>
            </Link>
            {blog.tags.map(tag => (
              <React.Fragment key={tag.id}>
                <span>{tag.name}</span>
              </React.Fragment>
            ))}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
};

export const getStaticProps = async () => {
  const key = {
    headers: {'X-API-KEY': process.env.API_KEY},
  };
  const res = await fetch(
    `https://your.microcms.io/api/v1/blogs/`,
    key,
  );
  const data = await res.json();

  return {
    props: {
      blogs: data.contents,
    }
  }
};

export default Home;

ここではgetStaticPropsという静的なメソッドを使って、ページを読み込む前にデータを取得してます。なので、取得したデータを元に静的なHTMLを生成することできます。

そしてLinkのhrefでルートの遷移先をしていします。blogsが持っているidを元にします。ダイナミックルーティングをする場合、Linkにasを指定する必要があります。これは、ブラウザのURLバーに表示されるパスです。

個別ページの作成

記事のリストページができました。次に記事の個別ページを作成していきます。microCMSでapiのプレビューをすることが出来ます。
Screenshot from 2019-12-06 19-37-35.png

pagesフォルダの中にblogsフォルダを作成してその中に[id].jsを作成します。
/blogs/[id].js

[id].js
import fetch from 'isomorphic-unfetch';

const BlogId = ({blog}) => {
  return (
    <div>
      <h1>{blog.title}</h1>
      <div>
        {blog.tags.map(tag => (
          <React.Fragment key={tag.id}>
            <span>{tag.name}</span>
          </React.Fragment>
        ))}
      </div>
      <div dangerouslySetInnerHTML={{__html: `${blog.body}`}}></div>
    </div>
  );
};

export const getStaticPaths = async () => {
  const key = {
    headers: {'X-API-KEY': process.env.API_KEY},
  };

  const res = await fetch('https://your.microcms.io/api/v1/blogs', key);
  const repos = await res.json();

  const paths = repos.contents.map(repo => `/blogs/${repo.id}`); 
    return {paths, fallback: false};
  };

export const getStaticProps = async context => {
  const id = context.params.id;

  const key = {
    headers: {'X-API-KEY': process.env.API_KEY},
  };

  const res = await fetch(
    `https://your.microcms.io/api/v1/blogs/${id}`,
    key,
  );
  const blog = await res.json();

  return {
    props : {
      blog: blog,
    }
  };
};

export default BlogId;

先ほどとは違って、getStaticPathsが登場しました。これは、Dynamic Routeの際にページ毎に静的なHTMLを生成するAPIです。ここでは、microCMSの個別ブログのデータを取得して静的なHTMLを生成しています。

ここではcontext.queryでid情報を取得しています。取得したid情報を元に、microCMSから個々のデータを取り出します。

一度これを実行してみましょう。

$ yarn dev

スクリーンショット 2019-12-06 20.28.53.png

そして個別ページも取得することができました。

スクリーンショット 2019-12-06 20.29.08.png

microCMSで作成したデータのリストと個別のデータを取得することができました。スタイルを整えればブログになりますね。

Next.jsのビルド設定

簡易的ではありますが、microCMSでコンテンツを管理できるブログが作成できました。

Next.jsでは静的なHTMLをexportするためのコマンドnext exportがあります。これを実行すると、outというフォルダが生成されます。package.jsonに追加しましょう。

package.json
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    //追記
    "export": "yarn run build && next export" 
  },

これで一通りできました。ちゃんとできるか試しにローカルでビルドしてみましょう。まずは、ローカルでビルドするためのenvファイルを作成します。内容は先ほどと同じです。

.env.local

API_KEY=XXXXXXXXXXXXXXXX
$ yarn export

すると、フォルダ内にoutが作成されました。
Screenshot from 2019-12-05 20-06-01.png

ここからはNetlifyとGitHubを連携する必要があるので、レポジトリを作って、ソースコードをプッシュしてください。

Netlifyにビルドする

スクリーンショット 2019-12-05 20.41.34.png

ビルドするための設定します。
アカウントを認証後、ダッシュボードのNew site from Gitをクリックします。
スクリーンショット 2019-12-05 20.46.37.png

今回はGitHub上にソースコードをあげたので、GitHubを選択します。すると、認証を求められます。
スクリーンショット 2019-12-05 20.47.37.png

認証に成功すると、自分のレポジトリからどのレポジトリをホスティングするか選択する必要があります。自分がプッシュしたプロジェクトを選択しましょう。

スクリーンショット 2019-12-05 20.49.09.png

静的ファイルをビルドするコマンドとディレクトリーを指定します。これは先ほど確認したものです。

Screenshot from 2019-12-04 22-53-36.png

Netlifyで環境変数を設定する

Advanced build settingsから環境変数を設定します。ここでは.envファイルに入れた、microCMSのapiキーを指定します。これでDeploy siteをしてみましょう。

Screenshot from 2019-12-04 22-50-01.png

無事ビルドが完了して、デプロイされるとURLが発行されます。
スクリーンショット 2019-12-06 20.36.12.png

ローカルで確認して内容が確認できます。これでJAMstackなサイトを作る第一歩として一連の流れが終わりました。

スクリーンショット 2019-12-06 20.37.01.png

最後に

今回はJAMstackアーキテクチャーの導入部分として、簡易的なブログを作成しました。microCMSは無料枠の範囲が非常に広いので、試しに使ってみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
107
Help us understand the problem. What are the problem?