Programming Journal

学習したことの整理用です。

newt と Next.jsでHP作成してみる

概要

友達の設計事務所のHP作成をすることになりました。
コンテンツは非エンジニアでも更新できるようにCMSで作成しました。
NewtというヘッドレスCMSを初めて使ったのですが、Vercelでデプロイするまで、簡単に作れたので内容をまとめます

CMSの選定

  • WordPressは使いたくない
  • 無料で使える
  • 簡単に導入できる
  • ヘッドレスCMS(API部分とコンテンツの管理だけが提供される)
  • Next.jsを使いたい

以上から、Newtを選択することにしました!

設計 / Next.jsでフロント部分を実装する

HPでは、Home, About, Works, Contact, Newsのコンテンツがあり、それぞれAPIを叩いてデータを取得するようにしました。

データ取得部分はベタ書きで仮の値を入れて実装しました。
src以下の構成はこんな感じで簡単にしました。
NewsとWorksは一覧を表示するページと、個々の詳細を表示するページがあります。

src
├── components
│   └── WorkCard.tsx
├── layouts
│   └── DefaultLayout.tsx
├── pages
│   ├── _app.tsx
│   ├── _document.tsx
│   ├── about
│   │   └── index.tsx
│   ├── contact
│   │   └── index.tsx
│   ├── index.tsx
│   ├── news
│   │   ├── [slug]
│   │   │   └── index.tsx
│   │   └── index.tsx
│   └── works
│       ├── [slug]
│       │   └── index.tsx
│       └── index.tsx
├── styles
│   └── globals.css
└── types
    └── type.ts

Newt側の設定

スペース作成

新規スペース作成

スペース

スペースとは、チームや個人に関わるあらゆるコンテンツを統合的に管理するためのものです。 スペースには、Appと呼ばれるコンテンツ管理のグループをいくつも作成することができ、ワークスペースのメンバーは必要に応じてこれらのAppに参加することでコンテンツ管理作業を行います。

App作成

App

Appとは、コンテンツやコンテンツの管理者を、その関連度の高さを元にひとまとまりにした「コンテンツ管理のユニット」です。

Appを構成するリソース

私はこのような構成にしました 各Appにそれぞれ、モデル(コンテンツ管理の骨組み。データ構造のこと。 (ex) タイトル、スラッグ、メタ情報・・・)、ビュー(管理画面のUI)が存在します

App名 App UID
works works
about about
contact contact
news news

モデルを追加する

モデルとは、コンテンツ管理の骨組みとなるものです。

モデルは、1つ以上のフィールドによって構成されており、それらの組み合わせによってコンテンツのデータ構造や入稿画面のUIが決定されます。 モデル

フィールドを追加していきます。
右上の保存ボタンを忘れないこと!!これを忘れていて、詰まりました。

モデルの作成

これはメインコンテンツである、Workのモデルです。
worksでは一覧ページと詳細ページが存在するので、スラッグでidを指定して、個別のページを取得できるようになっています。
カバー画像は一枚で、サブ画像は複数設定できます。

ここでJSONのプレビューも確認できます

{
  "_id": "_id",
  "_sys": {
    "createdAt": "2022-01-01T00:00:00.000Z",
    "updatedAt": "2022-01-01T00:00:00.000Z",
    "raw": {
      "createdAt": "2022-01-01T00:00:00.000Z",
      "updatedAt": "2022-01-01T00:00:00.000Z",
      "firstPublishedAt": "2022-01-01T00:00:00.000Z",
      "publishedAt": "2022-01-01T00:00:00.000Z"
    }
  },
  "title": "text",
  "slug": "text",
  "meta": {
    "title": "text",
    "description": "text",
    "ogImage": {
      "_id": "imageId",
      "src": "imageUrl",
      "fileType": "image/png",
      "fileSize": 12345678,
      "fileName": "image.png",
      "width": 600,
      "height": 400
    }
  },
  "body": "<p>Plain text is available using the fmt operator.</p>",
  "coverImage": {
    "_id": "imageId",
    "src": "imageUrl",
    "fileType": "image/png",
    "fileSize": 12345678,
    "fileName": "image.png",
    "width": 600,
    "height": 400
  },
  "subImages": [
    {
      "_id": "imageId",
      "src": "imageUrl",
      "fileType": "image/png",
      "fileSize": 12345678,
      "fileName": "image.png",
      "width": 600,
      "height": 400
    }
  ],
  "member": "<p>Plain text is available using the fmt operator.</p>"
}

表示したいデータを登録していく

モデルを登録したら、表示したいデータを登録していきます。 「Work(モデル名)を追加」ボタンをクリックすると、先に設定したフィールド項目がフォームになっているので、埋めていきます。

Newt CDN API Tokenを生成する

グローバルに分散されたCDNを経由してデータを取得します。キャッシュされたリクエストに対して非常に高速なレスポンスを返すことができます。

また、「Newt CDN API」は公開されたコンテンツのみを取得することができ、下書き状態のコンテンツについては取得できません。

APIキー

スペース設定の「APIキー」画面から作成します

Next.js側の設定

こちらの公式ブログが詳しいです

www.newt.so

Vercelでホスティングする

こちらの公式ブログが詳しいです

GitHubのリポジトリとVercelを接続して、ホスティングする

ローカルでは、.env.localに登録していた環境変数をVercel側に登録するのを忘れていてエラーを出してしまいました、忘れずに。

自動デプロイ設定する

毎回毎回Vercel上で手動デプロイするのは不便なので、Newt側で非エンジニアがコンテンツを更新(公開)したときも自動でデプロイされるようにしたいです。

まず、VercelでProjectのsetting > gitからDeploy Hooksを作成する(hooks名、ブランチ名)。作成したURLはコピーしておく。

続いて、Newt側のスペース設定>Webhook で、VercelのDeploy hooksを登録します。先のURLを貼り付け。

完成!

半日くらいで作成できました!
一度作成してしまえばメンテナンスコスト0で、非エンジニアでも好きなタイミングでコンテンツを更新できるので、作ってよかったです。

また、このHPきっかけで友達の活動が編集者の方の目に止まり建築雑誌に掲載されたりと嬉しい反応もあり、友達も喜んでくれたので嬉しかったです! タテモノトカ