NewtとGatsbyを利用してブログを作成する

最終更新日:

Table of contents

このチュートリアルでは、Newtと Gatsby を利用して、ブログを作成する手順を紹介します。
具体的には、Newtで管理しているコンテンツの一覧ページと詳細ページを作る手順を紹介します。

記事内で使用している主なソフトウェアのバージョン

  • Gatsby(gatsby): 5.4.2
  • gatsby-source-newt(gatsby-source-newt): 2.0.7

概要

Gatsbyでサイトを作成し、Newtのコンテンツ情報を取得できるようにします。
コンテンツの一覧ページ(パス: /)と詳細ページ(パス: /articles/:slug 。slugがarticle-1の場合は /articles/article-1)を作成し、ローカル環境で表示を行うまでを説明します。
また、ここではビルド時にHTMLを生成する、静的サイト生成(Static Site Generation)の方法を紹介します。

1. Gatsbyのセットアップ

1-1. Node.jsの準備

Gatsby v5でサポートされるNode.jsの最低バージョンは18となります。17以前のバージョンを利用している場合は、あらかじめ18以上のバージョンをインストールしておきましょう。
アップグレードの方法は、Gatsbyの Upgrading Your Node.js Version のドキュメント等を参考にしてください。
すでに18以上のNode.jsを利用している場合は、特に作業は必要ありません。

1-2. サイトの作成

Gatsbyのセットアップを行います。create-gatsby を利用することで、簡単にGatsbyのサイトを作成できます。以下のコマンドを入力します。

npm init gatsby

コマンドを入力すると、以下の質問を聞かれるので、お好きな設定を選びましょう。

  • サイト名(ここでは gatsby-blog としました)
  • サイトを作成するフォルダ名
  • JavaScriptを利用するか、TypeScriptを利用するか(ここでは TypeScript を選択)
  • CMSを利用するか(ここでは No を選択)
  • スタイリングシステムを利用するか(ここでは No を選択)
  • 他のプラグインをインストールするか(ここでは何も選ばずに Done を選択)

質問に答えると、以下のように表示されます。

$ npm init gatsby
create-gatsby version 3.4.0

Welcome to Gatsby!

This command will generate a new Gatsby site for you in /Users/hoge/fuga with the setup you select. Let's answer some questions:

What would you like to call your site?
✔ · gatsby-blog
What would you like to name the folder where your site will be created?
✔ fuga/ gatsby-blog
✔ Will you be using JavaScript or TypeScript?
· TypeScript
✔ Will you be using a CMS?
· No (or I'll add it later)
✔ Would you like to install a styling system?
· No (or I'll add it later)
✔ Would you like to install additional features with other plugins?No items were selected

Thanks! Here's what we'll now do:

    🛠  Create a new Gatsby site in the folder gatsby-blog

✔ Shall we do this? (Y/n) · Yes
✔ Created site from template
✔ Installed Gatsby
✔ Installed plugins
✔ Created site in gatsby-blog
🎉  Your new Gatsby site  has been successfully created
at /Users/hoge/fuga/gatsby-blog.

作成したプロジェクトに移動して、開発サーバーを立ち上げます。

$ cd gatsby-blog
$ npm run develop

http://localhost:8000/ にアクセスして、以下のような画面が表示されることを確認します。

gatsby-blog1.png

1-3. パッケージマネージャーの設定(yarnを利用する場合)

yarnをパッケージマネージャーとして利用する場合、Gatsby CLIの設定ファイルを書き換える必要があります。
※ npmをパッケージマネージャーとして使う場合、1-3のステップを飛ばして構いません。

~/.config/gatsby/config.json/Users/{ユーザー名}/.config/gatsby/config.json)を以下のように修正して、packageManageryarn を指定します。
詳細は、Gatsbyの Yarn のドキュメントをご確認ください。

~/.config/gatsby/config.json
1{
2  "cli": {
3    "packageManager": "yarn"
4  }
5}

package-lock.json を削除した後、yarn install を実行して、yarn.lock ファイルが作成されることを確認します。
これで yarn develop で開発サーバーを立ち上げられるようになりました。

2. Newtのセットアップ

次にNewtにコンテンツとAPIトークンを用意し、コンテンツの取得を行うための準備を行います。

2-1. Appを追加する

「Appを追加」をクリックして「テンプレートから追加」を選択します。

Appを追加する

表示されるテンプレートの中から「Blog」を選択して、「このテンプレートを追加」をクリックします。
Appテンプレート

テンプレートが追加されると、「投稿データ」「タグデータ」「著者データ」が追加されます。

quick-start03.jpg

2-2. スペースUID・App UID・モデルUIDを確認する

スペースUIDは「スペース設定」から確認できます。

quick-start0402.jpg
quick-start0503.jpg

上記の例だと、スペースUIDは sample-for-docs となります。
この値は3-1で環境変数として定義します。

また「Blog」テンプレートを追加した場合、App UIDは blog、「投稿データ」モデルUIDは article となります。
これらの値は、3-3でプラグインを追加する際に利用します。

2-3. Newt CDN API Tokenを作成する

続いて、APIリクエストに必要なトークンを発行します。
スペース設定 > APIキー のページからNewt CDN API Tokenを作成します。

quick-start06.jpg

名前と取得対象を決めて「作成」を押します。

quick-start07.jpg

ここで作成したトークンの値は3-1で環境変数として定義します。

3. Newtプラグインの追加

Newtの Gatsbyプラグイン を利用することで、Newtのコンテンツデータをより簡単に取得できます。
ここではプラグインを追加し、GraphiQLを利用してデータが取得されていることを確認します。

3-1. 環境変数の設定

Gatsbyには環境変数のビルトインサポートがあります。
開発環境用に .env.development ファイルを作成し、2-2で確認したスペースUID、2-3で作成したトークンの値を定義します。以下を、実際の値で置き換えて定義してください。

.env.development
1NEWT_SPACE_UID=sample-for-docs
2NEWT_CDN_API_TOKEN==xxxxxxxxxxxxxxx

次に gatsby-config.ts に以下を追加します。
これで開発環境の場合は .env.development を、本番環境の場合は .env.production を参照します。

gatsby-config.ts
1require('dotenv').config({
2  path: `.env.${process.env.NODE_ENV}`,
3})

続いて、.gitignore.env.* を追加します。
これで環境変数がGitにコミットされないようになりました。

.gitignore
node_modules/
.cache/
public
src/gatsby-types.d.ts
.env.*

Gatsbyの環境変数について、詳細はGatsbyの Environment Variables のドキュメントをご確認ください。

3-2. gatsby-source-newtのインストール

次に gatsby-source-newt をインストールします。

npm install gatsby-source-newt
# or
yarn add gatsby-source-newt

3-3. プラグインの追加

Newtのソースプラグインを追加して、Newtで定義した投稿データを取得します。

gatsby-config.tspluginsgatsby-source-newt の記述を追加します。
プラグイン追加の詳細についてはGatsbyの Add a Plugin to Your Site のドキュメントをご確認ください。

gatsby-config.ts
import type { GatsbyConfig } from 'gatsby'

require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`,
})

const config: GatsbyConfig = {
  siteMetadata: {
    title: `gatsby-blog`,
    siteUrl: `https://www.yourdomain.tld`,
  },
  // More easily incorporate content into your pages through automatic TypeScript type generation and better GraphQL IntelliSense.
  // If you use VSCode you can also use the GraphQL plugin
  // Learn more at: https://gatsby.dev/graphql-typegen
  graphqlTypegen: true,
  plugins: [],
  plugins: [
    {
      resolve: 'gatsby-source-newt',
      options: {
        spaceUid: process.env.NEWT_SPACE_UID,
        token: process.env.NEWT_CDN_API_TOKEN,
        appUid: 'blog',
        models: [
          {
            uid: 'article',
          },
        ],
      },
    },
  ],
}

export default config

上記の指定を行うと、Newtから取得した投稿データは newtArticleallNewtArticle というタイプでアクセスできるようになります。

このタイプは uid から決定されるため、例えば uidauthor の場合は newtAuthorallNewtAuthor となります。

models: [
  {
    uid: 'author',
  },
],

uidから決定するのではなく、自身で定義したい場合は、type パラメータを指定してください。例えば typepost の場合は newtPostallNewtPost となります。

models: [
  {
    uid: 'article',
    type: 'post',
  },
],

それでは、開発サーバーを再度立ち上げて、http://localhost:8000/___graphql にアクセスして、GraphiQL を開いてみましょう。

以下のようにクエリを入力・実行して、データが返却されることを確認します。

1query MyQuery {
2  allNewtArticle {
3    edges {
4      node {
5        _id
6        title
7        slug
8      }
9    }
10  }
11}

gatsby-blog2.png

4. 一覧ページの作成

4-1. 言語の設定をする

gatsby-ssr.tsx を作成し、lang 属性を設定します。ここでは日本語 ja を指定します。
gatsby-ssr.tsx の詳細については、Gatsbyの Gatsby Server Rendering APIs をご確認ください。

gatsby-ssr.tsx
1exports.onRenderBody = ({ setHtmlAttributes }) => {
2  setHtmlAttributes({ lang: 'ja' })
3}

4-2. 投稿一覧を取得する

Gatsbyでは src/pages ディレクトリの配下にファイルを作成すると、自動的にルートとして利用できるようになります。
例えば、以下のようにルーティングされます。

  • src/pages/blog/index.tsx/blog
  • src/pages/blog/first-post.tsx/blog/first-post

※ ルーティングの詳細については、Gatsbyの Routing のドキュメントをご確認ください。

ここではトップページ(パス: /)で投稿一覧を表示したいので、src/pages/index.tsx ファイルを修正します。
まず、以下の query を追加しましょう。

src/pages/index.tsx
1import { graphql } from 'gatsby'
2
3// (中略)
4
5export const query = graphql`
6  query IndexPage {
7    allNewtArticle {
8      edges {
9        node {
10          _id
11          title
12          slug
13        }
14      }
15    }
16  }
17`

Gatsbyでは graphql タグを使用することで、ページコンポーネントがデータを利用できます。ここでは、投稿一覧の表示で利用する _idtitleslug 情報を取得しています。
また、オペレーション名IndexPage と指定しています。

ページ内でのデータの取得について、詳細はGatsbyの Querying Data in Pages with GraphQL のドキュメントをご確認ください。

4-3. 投稿一覧を表示する

次に、取得した投稿一覧を表示します。
src/pages/index.tsx は以下のようになります。

src/pages/index.tsx
1import * as React from 'react'
2import { graphql, Link } from 'gatsby'
3import type { HeadFC, PageProps } from 'gatsby'
4
5const IndexPage = ({ data }: PageProps<Queries.IndexPageQuery>) => {
6  return (
7    <main>
8      <ul>
9        {data.allNewtArticle.edges.map((edge) => (
10          <li key={edge.node._id}>
11            <Link to={`/articles/${edge.node.slug}`}>{edge.node.title}</Link>
12          </li>
13        ))}
14      </ul>
15    </main>
16  )
17}
18
19export default IndexPage
20
21export const Head: HeadFC = () => (
22  <>
23    <title>Newt・Gatsbyブログ</title>
24    <meta name="description" content="NewtとGatsbyを利用したブログです" />
25  </>
26)
27
28export const query = graphql`
29  query IndexPage {
30    allNewtArticle {
31      edges {
32        node {
33          _id
34          title
35          slug
36        }
37      }
38    }
39  }
40`

4-2で作成した query の結果は data という引数から利用できます。
型として指定されている PageProps<Queries.IndexPageQuery> ですが、PagePropsQueries.IndexPageQuery というジェネリクスを渡すことで、query の実行結果の型を指定してます。
この Queries.IndexPageQuery ですが、Gatsbyの GraphQL Typegen によって自動で生成される型となります。オペレーション名を IndexPage としなかった場合は、適切な名称に置き換えてください。
また、Gatsby Head API を利用して、タイトルとディスクリプションを設定しています。

http://localhost:8000/ にアクセスして、以下のように投稿一覧が表示されれば成功です。

gatsby-blog3.png

5. 詳細ページの作成

5-1. 投稿詳細を取得する

Gatsbyでは {Product.name} のようにページ名に波括弧を使うことで動的なルーティングを作成できます。例えば、以下のようにルーティングされます。

  • src/pages/products/{Product.name}.tsx/products/burger

ここでは、/articles/:slug/articles/article-1 など)のパスで投稿の詳細を表示したいので、src/pages/articles/{NewtArticle.slug}.tsx のファイルを作成します。

この場合、各コンテンツのslug情報が props.params.slug として利用できます。また、slugと対応する各nodeのid情報(各コンテンツの _id ではないのでご注意ください)が props.pageContext.id として利用できます。
※ 詳細についてはGatsbyの File System Route API のドキュメントをご確認ください。

src/pages/articles/{NewtArticle.slug}.tsx に、以下の query を追加します。

src/pages/articles/{NewtArticle.slug}.tsx
1import { graphql } from 'gatsby'
2
3export const query = graphql`
4  query ArticlePage($id: String) {
5    newtArticle(id: { eq: $id }) {
6      title
7      body
8    }
9  }
10`

このクエリは pageContextid を利用して、スラッグに該当する1件の投稿データを取得しています。
ここでは、投稿詳細の表示で利用する titlebody 情報を取得しています。

5-2. 投稿詳細を表示する

最後に、取得した投稿詳細を表示します。
src/pages/articles/{NewtArticle.slug}.tsx は以下のようになります。

src/pages/articles/{NewtArticle.slug}.tsx
1import * as React from 'react'
2import { graphql } from 'gatsby'
3import type { HeadFC, PageProps } from 'gatsby'
4
5const ArticlePage = ({ data }: PageProps<Queries.ArticlePageQuery>) => {
6  return (
7    <main>
8      <h2>{data.newtArticle?.title}</h2>
9      <div dangerouslySetInnerHTML={{ __html: data.newtArticle?.body + '' }} />
10    </main>
11  )
12}
13
14export default ArticlePage
15
16export const Head: HeadFC<Queries.ArticlePageQuery> = ({ data }) => (
17  <>
18    <title>{data.newtArticle?.title}</title>
19    <meta name="description" content="投稿詳細ページです" />
20  </>
21)
22
23export const query = graphql`
24  query ArticlePage($id: String) {
25    newtArticle(id: { eq: $id }) {
26      title
27      body
28    }
29  }
30`

4-3と同様に、Gatsbyの GraphQL Typegen によって自動で生成される Queries.ArticlePageQuery を利用します。オペレーション名を ArticlePage としなかった場合は、適切な名称に置き換えてください。

※ bodyの表示で利用されている dangerouslySetInnerHTML はXSSの危険性があるため、利用には注意が必要です。ここでは、Newtで管理している投稿情報を表示するものであり、不特定多数のユーザーが入力できるものを表示するわけではないため、安全なものとして利用しています。

これで、投稿詳細についての設定も完了です。
http://localhost:8000/articles/article-3/ にアクセスして、以下のように投稿詳細が表示されれば成功です。

gatsby-blog4.png

次のステップ

このチュートリアルを行うことで、Gatsbyのサイトを作成し、開発環境でコンテンツの取得・表示を行う方法を学習しました。
更に深く学習したい方は、以下のチュートリアルもおすすめです。

ホスティングを行いたい方

その他にも様々なチュートリアルを用意しているので、ぜひ チュートリアル のページもご確認ください。

NewtMade in Newt