🦎

ヘッドレスCMS「Newt」の簡単な実装例と特徴

  • #newt,
  • #Next.js

今回は、本サイトで使用しているヘッドレスCMSの「Newt」について、 簡単な実装例とともに、特徴を紹介したいと思います。

ヘッドレスCMSとは

まず、ヘッドレスCMSはバックエンドとフロントエンドを分離して運用できる便利なツールです。 一般的なCMSでは、コンテンツの作成や管理と同時に、そのコンテンツを表示するためのデザイン(ビュー)も含まれています。代表的なCMSには、WordPress、はてなブログ、Qiitaなどがあります。 ヘッドレスCMSは、コンテンツの管理のみを提供し、ビュー部分(表示部分)を分離したCMSです。これにより、任意のフロントエンド技術を使用してコンテンツを表示することができます。

Newtとは?

Newtは2021年に創業したスタートアップ企業が開発したヘッドレスCMSです。 「次のWordPressをつくる」をミッションに掲げているようです。

https://www.newt.so/about

現在、世界のWebサイトの43.2%がWordPressで作成されていると言われていますが、WordPressには以下のような課題があります。

  • 脆弱性を狙った攻撃のリスクが高い
  • プラグインやPHPの更新に伴うメンテナンスコスト
  • カスタマイズの制限が多い

Newtはこれらの問題を解決しつつ、直感的で効率的なコンテンツ管理を提供しています。

Newtの主な構成

Newtは、次のように構成されています

  • スペース

一つのアカウントでスペース(プロジェクト)を複数作成できる スペースの中にAppと呼ばれるコンテンツ管理のグループも複数作成できる

  • App

コンテンツ管理ユニット Appはモデル、ビュー、コンテンツで構成される ニュース、社員紹介、インタビュー記事のようなものがここに増えていくイメージ

  • モデル

コンテンツ管理の骨組みとなるもの フィールドタイプ

  • ビュー

管理画面UI 20250128115701.png

Appテンプレート

Newtは、あらかじめセットアップ済みのテンプレートを提供しており、以下の手順で簡単にサイトを立ち上げることも可能なようです。

  1. 管理画面からテンプレートをインストール
  2. GitHubからスターターコードをclone
  3. NewtとスターターをAPIで接続 20250128115741.png

現在公開されているもの

  • ブログ
  • ドキュメント
  • ランディングページ
  • ヘルプセンター
  • アップデートノート
  • コンタクトページ

記事投稿画面をカスタマイズした例

デフォルトの記事投稿画面

20250128115826.png

カスタマイズ後の記事投稿画面

食べ物の商品投稿画面を例に、カスタマイズしてみました。 20250128115903.png

レスポンスJSONは次のようになります

{
  "_id": "_id",
  "_sys": {
    "createdAt": "2023-01-01T00:00:00.000Z",
    "updatedAt": "2023-01-01T00:00:00.000Z",
    "customOrder": 3,
    "raw": {
      "createdAt": "2023-01-01T00:00:00.000Z",
      "updatedAt": "2023-01-01T00:00:00.000Z",
      "firstPublishedAt": "2023-01-01T00:00:00.000Z",
      "publishedAt": "2023-01-01T00:00:00.000Z"
    }
  },
  "itemImage": {
    "_id": "imageId",
    "src": "imageUrl",
    "fileName": "example.png",
    "fileType": "image/png",
    "fileSize": 12345678,
    "width": 600,
    "height": 400,
    "title": "example",
    "altText": "example image",
    "description": "",
    "metadata": {}
  },
  "itemName": "text",
  "price": 1,
  "itemDescription": "<p>Plain text is available using the fmt operator.</p>",
  "slug": "text",
  "Nutritional_Information": {
    "kcal": 1,
    "protein": 1,
    "fat": 1,
    "carbo": 1,
    "salt": 1
  }
}

実装例

では、実際に投稿画面に値を入力して画面に表示するところまでをやってみます。 Newtのチュートリアルが分かりやすいため、詳細な説明は省略します。 興味がある方は、公式のチュートリアルを参考にぜひ試してみてください。

https://www.newt.so/docs/tutorials

記事投稿画面

まず、管理画面から記事を投稿する際、以下のように入力します。 20250128120107.png

記事投稿一覧の取得メソッド

投稿一覧を取得するために次のようなメソッドを使用します。

export const getArticles = cache(async () => {
  const { items } = await client.getContents<ArticleType>({
    appUid: 'Blog',
    modelUid: 'article',
    query: {
      select: [
        '_id',
        'title',
        'slug',
        'body',
        'tags',
        '_sys',
        'bookUrl',
        'emoji',
      ],
      body: {
        fmt: 'text',
      },
    },
  })
  return items
})

レスポンスJSON

記事一覧取得メソッドを使用すると、以下のようなレスポンスが返ってきます。 記事を追加すると配列内のオブジェクトが増えていきます。

[
    {
        "_id": "67983ea3192dd01f4c77bd12",
        "title": "テスト投稿",
        "slug": "test",
        "body": "## 見出し\nテキストテキストテキスト\n\n* テキストテキストテキスト\n* テキストテキストテキスト\n* テキストテキストテキスト",
        "tags": [],
        "_sys": {
            "raw": {
                "createdAt": "2025-01-28T02:19:15.304Z",
                "updatedAt": "2025-01-28T02:19:15.304Z",
                "firstPublishedAt": "2025-01-28T02:19:15.304Z",
                "publishedAt": "2025-01-28T02:19:15.304Z"
            },
            "customOrder": 9,
            "createdAt": "2025-01-28T02:19:15.304Z",
            "updatedAt": "2025-01-28T02:19:15.304Z"
        },
        "emoji": {
            "type": "emoji",
            "value": "🎉"
        }
    },
]

画面表示

取得できたjsonの値使用して記事一覧を表示することができました。 20250128120244.png

投稿詳細取得メソッド

投稿詳細情報を取得するために次のようなメソッドを使用します。

export const getBlogArticleBySlug = cache(async (slug: string) => {
  const article = await client.getFirstContent<ArticleType>({
    appUid: 'Blog',
    modelUid: 'article',
    query: {
      slug,
      select: [
        '_id',
        'title',
        'slug',
        'body',
        'tags',
        '_sys',
        'bookUrl',
        'emoji',
      ],
      body: {
        fmt: 'text',
      },
    },
  })
  return article
})

レスポンスJSON

{
    "_id": "67983ea3192dd01f4c77bd12",
    "title": "テスト投稿",
    "slug": "test",
    "body": "## 見出し\nテキストテキストテキスト\n\n* テキストテキストテキスト\n* テキストテキストテキスト\n* テキストテキストテキスト",
    "tags": [],
    "_sys": {
        "raw": {
            "createdAt": "2025-01-28T02:19:15.304Z",
            "updatedAt": "2025-01-28T02:19:15.304Z",
            "firstPublishedAt": "2025-01-28T02:19:15.304Z",
            "publishedAt": "2025-01-28T02:19:15.304Z"
        },
        "customOrder": 9,
        "createdAt": "2025-01-28T02:19:15.304Z",
        "updatedAt": "2025-01-28T02:19:15.304Z"
    },
    "emoji": {
        "type": "emoji",
        "value": "🎉"
    }
}

取得できたjsonの値を使用して詳細ページを表示することができました。 20250128120400.png

ここまでで、簡単な記事一覧と詳細ページを実装することができました。 今回は簡単な投稿を画面に表示するところまでをやってみましたが、カスタマイズ次第では複雑なページを作成することも可能です。

まとめ

この記事では、ヘッドレスCMS「Newt」の基本的な説明と記事投稿画面に入力して、必要なデータをJSON形式でレスポンスとして取得し、フロントエンドに表示するところまでを紹介しました。 Newtは、簡単な設定で、すぐに使い始められる点が魅力だと思いました。 また、Newtのセットアップも簡単で、公式チュートリアルに従うことで、誰でもすぐにサイト構築を始めることができることが分かりました。