こんちには! 株式会社iimonでエンジニアをしている保田です。 今回は、ブログやメモなどを自分の見やすいデザインで管理できる場所を作成したいと思い、NewtというヘッドレスCMSを使用してみました。 その簡単な実装例とともに、Newtの特徴を紹介したいと思います。
ヘッドレスCMSとは
まず、ヘッドレスCMSはバックエンドとフロントエンドを分離して運用できる便利なツールです。 一般的なCMSでは、コンテンツの作成や管理と同時に、そのコンテンツを表示するためのデザイン(ビュー)も含まれています。代表的なCMSには、WordPress、はてなブログ、Qiitaなどがあります。 ヘッドレスCMSは、コンテンツの管理のみを提供し、ビュー部分(表示部分)を分離したCMSです。これにより、任意のフロントエンド技術を使用してコンテンツを表示することができます。
Newtとは?
Newtは2021年に創業したスタートアップ企業が開発したヘッドレスCMSです。 「次のWordPressをつくる」をミッションに掲げているようです。 www.newt.so
現在、世界のWebサイトの43.2%がWordPressで作成されていると言われていますが、WordPressには以下のような課題があります。
Newtはこれらの問題を解決しつつ、直感的で効率的なコンテンツ管理を提供しています。
Newtの主な構成
Newtは、次のように構成されています
- スペース
一つのアカウントでスペース(プロジェクト)を複数作成できる スペースの中にAppと呼ばれるコンテンツ管理のグループも複数作成できる
- App
コンテンツ管理ユニット Appはモデル、ビュー、コンテンツで構成される ニュース、社員紹介、インタビュー記事のようなものがここに増えていくイメージ
- モデル
コンテンツ管理の骨組みとなるもの フィールドタイプ
- ビュー
管理画面UI

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

現在公開されているもの
- ブログ
- ドキュメント
- ランディングページ
- ヘルプセンター
- アップデートノート
- コンタクトページ
記事投稿画面をカスタマイズした例
デフォルトの記事投稿画面

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

レスポンス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のチュートリアルが分かりやすいため、詳細な説明は省略します。 興味がある方は、公式のチュートリアルを参考にぜひ試してみてください。 www.newt.so
記事投稿画面
まず、管理画面から記事を投稿する際、以下のように入力します。

記事投稿一覧の取得メソッド
投稿一覧を取得するために次のようなメソッドを使用します。
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の値使用して記事一覧を表示することができました。

投稿詳細取得メソッド
投稿詳細情報を取得するために次のようなメソッドを使用します。
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の値を使用して詳細ページを表示することができました。

ここまでで、簡単な記事一覧と詳細ページを実装することができました。 今回は簡単な投稿を画面に表示するところまでをやってみましたが、カスタマイズ次第では複雑なページを作成することも可能です。
まとめ
この記事では、ヘッドレスCMS「Newt」の基本的な説明と記事投稿画面に入力して、必要なデータをJSON形式でレスポンスとして取得し、フロントエンドに表示するところまでを紹介しました。 Newtは、簡単な設定で、すぐに使い始められる点が魅力だと思いました。 また、Newtのセットアップも簡単で、公式チュートリアルに従うことで、誰でもすぐにサイト構築を始めることができることが分かりました。
最後に
最後になりますが、現在弊社ではエンジニアを募集しています。 この記事を読んで少しでも興味を持ってくださった方は、ぜひカジュアル面談でお話ししましょう!
iimon採用サイト/ Wantedly / Green