はじめに
個人的に、ヘッドレスCMS選びで最初に検討すべきはStrapiだと思っています。
GitHubで70,600スター以上、10年の歴史があって、1,040人以上のコントリビューターがいる。オープンソースのヘッドレスCMSとしては、もう定番中の定番ですね。
正直なところ、最初は「WordPressでいいじゃん」と思っていたんですよ。でも、フロントエンドをReactやNext.jsで自由に作りたくなったときに、WordPressのテーマ制約がどうしても邪魔になる。そこでヘッドレスCMSを探し始めて、Strapiに辿り着いたという話です。
30代になって思うのは、「自分でコントロールできる」ことの大切さ。SaaSに依存しすぎると、料金改定や仕様変更で振り回される。Strapiはセルフホストできるので、その点で安心感があります。
Strapiとは
Strapiは、オープンソースのヘッドレスCMSです。「ヘッドレス」というのは、コンテンツ管理(バックエンド)とフロントエンドが分離しているという意味。
従来のCMSはテーマやテンプレートでフロントエンドが決まっていましたが、ヘッドレスCMSはAPIでコンテンツを提供するだけ。フロントエンドは好きな技術で作れる。
Strapiの場合、管理画面でコンテンツタイプを定義すると、REST APIとGraphQL APIが自動生成される。これがかなり便利なんですよ。
特徴・メリット
1. 100% JavaScript/TypeScript
Node.js製なので、フロントエンドエンジニアには馴染みやすい。TypeScriptもしっかりサポートしているので、型安全にコンテンツタイプを定義できます。
「PHPはちょっと...」という人でも安心して使える。
2. 自由度の高いコンテンツモデリング
Content-Type Builderで、管理画面からポチポチとフィールドを追加できる。
- テキスト、リッチテキスト、数値、真偽値
- メディア(画像、動画、ファイル)
- リレーション(1対1、1対多、多対多)
- コンポーネント(再利用可能なフィールドグループ)
- ダイナミックゾーン(可変のコンポーネント配置)
これ、意外と他のヘッドレスCMSだとダイナミックゾーンがなかったりするんですよね。
3. REST & GraphQL両対応
REST APIが標準で、GraphQLはプラグインで追加。どちらか好きな方を選べる。
個人的にはRESTで十分な場合が多いですが、複雑なリレーションを一発で取得したいときはGraphQLが便利。
4. ロールベースのアクセス制御
ユーザーごとに細かく権限を設定できる。「編集者は記事の編集だけ」「管理者はすべての操作可能」みたいな使い分けができます。
5. プラグインエコシステム
公式・コミュニティ製のプラグインが豊富。SEO、サイトマップ、メール送信、Cloudinaryなど、よく使う機能は大体ある。
6. セルフホスト可能
これが一番のメリットかもしれない。VPSやクラウドに自分でデプロイできる。データの所有権が自分にある安心感。もちろんStrapi Cloudというマネージドサービスもあります。
インストール方法
プロジェクトの作成
npx create-strapi@latest my-project
# または
yarn create strapi my-project
対話形式でいくつか質問されるので、答えていくだけ。
? What would you like to name your project? my-project
? Choose your installation type: Quickstart (recommended)
? Please log in or sign up (optional): Skip
Quickstartを選ぶとSQLiteがデフォルトで使われる。本番環境ではPostgreSQLかMySQLを推奨。
開発サーバーの起動
cd my-project
npm run develop
# または
yarn develop
これで http://localhost:1337/admin にアクセスすると管理画面が開く。初回は管理者アカウントの作成を求められます。
データベースの設定(PostgreSQL)
本番用にPostgreSQLを使う場合は、config/database.tsを編集:
export default ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: env('DATABASE_HOST', 'localhost'),
port: env.int('DATABASE_PORT', 5432),
database: env('DATABASE_NAME', 'strapi'),
user: env('DATABASE_USERNAME', 'strapi'),
password: env('DATABASE_PASSWORD', 'password'),
ssl: env.bool('DATABASE_SSL', false),
},
},
});
基本的な使い方
コンテンツタイプの作成
管理画面の「Content-Type Builder」から新しいコンテンツタイプを作成。
例えば「Article(記事)」を作る場合:
- 「Create new collection type」をクリック
- 名前を「Article」に設定
- フィールドを追加:
- title(Text)
- content(Rich Text)
- slug(UID、titleから自動生成)
- publishedAt(Datetime)
- coverImage(Media)
- category(Relation、Categoryと紐付け)
保存するとサーバーが再起動して、APIエンドポイントが自動生成される。
APIの権限設定
デフォルトではAPIは非公開。Settings > Users & Permissions > Rolesで公開設定を行う。
「Public」ロールを選んで、Articleの「find」と「findOne」にチェックを入れると、認証なしで記事一覧と詳細が取得できるようになる。
REST APIでの取得
# 記事一覧
curl http://localhost:1337/api/articles
# 記事詳細
curl http://localhost:1337/api/articles/1
# リレーションを含めて取得
curl "http://localhost:1337/api/articles?populate=*"
# フィルタリング
curl "http://localhost:1337/api/articles?filters[title][$contains]=Strapi"
Next.jsからの取得
// lib/strapi.ts
const STRAPI_URL = process.env.STRAPI_URL || 'http://localhost:1337';
export async function getArticles() {
const res = await fetch(`${STRAPI_URL}/api/articles?populate=*`, {
next: { revalidate: 60 }, // 60秒キャッシュ
});
if (!res.ok) {
throw new Error('Failed to fetch articles');
}
const data = await res.json();
return data.data;
}
export async function getArticleBySlug(slug: string) {
const res = await fetch(
`${STRAPI_URL}/api/articles?filters[slug][$eq]=${slug}&populate=*`
);
if (!res.ok) {
throw new Error('Failed to fetch article');
}
const data = await res.json();
return data.data[0] || null;
}
// app/blog/page.tsx
import { getArticles } from '@/lib/strapi';
export default async function BlogPage() {
const articles = await getArticles();
return (
<div>
<h1>ブログ</h1>
<ul>
{articles.map((article: any) => (
<li key={article.id}>
<a href={`/blog/${article.attributes.slug}`}>
{article.attributes.title}
</a>
</li>
))}
</ul>
</div>
);
}
GraphQLでの取得
まずGraphQLプラグインをインストール:
npm install @strapi/plugin-graphql
# または
yarn add @strapi/plugin-graphql
サーバーを再起動すると、http://localhost:1337/graphqlでGraphQL Playgroundが使えるようになる。
query GetArticles {
articles {
data {
id
attributes {
title
content
slug
publishedAt
coverImage {
data {
attributes {
url
}
}
}
}
}
}
}
実践的なユースケース
1. 企業サイトのCMS
会社概要、ニュース、製品情報などをStrapiで管理。フロントエンドはNext.jsでSSGして、高速な静的サイトを構築。更新頻度が低いコンテンツに最適。
2. ブログプラットフォーム
記事、カテゴリ、タグ、著者をStrapiで管理。リッチテキストエディタでMarkdownやWYSIWYGで執筆できる。
3. ECサイトの商品管理
商品情報、カテゴリ、在庫をStrapiで管理。決済機能はStripeなど別サービスと連携。
4. モバイルアプリのバックエンド
REST APIをそのままモバイルアプリから叩く。認証機能も標準装備なので、ユーザー管理も任せられる。
カスタムコントローラーの作成
標準のCRUDでは足りない場合、カスタムコントローラーを追加できる:
// src/api/article/controllers/article.ts
import { factories } from '@strapi/strapi';
export default factories.createCoreController(
'api::article.article',
({ strapi }) => ({
// カスタムアクション
async findPopular(ctx) {
const entries = await strapi.db.query('api::article.article').findMany({
orderBy: { viewCount: 'desc' },
limit: 10,
populate: ['coverImage', 'category'],
});
return entries;
},
})
);
ルートを追加:
// src/api/article/routes/custom-article.ts
export default {
routes: [
{
method: 'GET',
path: '/articles/popular',
handler: 'article.findPopular',
},
],
};
Webhookの設定
コンテンツが更新されたときに外部サービスに通知できる。Settings > Webhooksから設定。
Next.jsのISR(Incremental Static Regeneration)と組み合わせると、記事更新時に自動で再ビルドできる。
デプロイ
本番環境の設定
// config/env/production/server.ts
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: env('PUBLIC_URL', 'https://your-domain.com'),
app: {
keys: env.array('APP_KEYS'),
},
});
Dockerでのデプロイ
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 1337
CMD ["npm", "start"]
主要なホスティング先
- Railway: 簡単にデプロイできる。PostgreSQLも一緒に
- Render: 無料プランあり
- DigitalOcean App Platform: 安定感がある
- AWS/GCP/Azure: 本格的な運用向け
- Strapi Cloud: 公式のマネージドサービス
まとめ
Strapiを使ってみて感じた変化:
- セットアップ: 15分で管理画面とAPIが動く
- 学習コスト: 管理画面が直感的で、非エンジニアでも使える
- 開発速度: APIを自分で書く必要がない
- 柔軟性: フロントエンドは好きな技術で作れる
- コスト: セルフホストなら無料で始められる
正直なところ、「とりあえずCMSが必要」という場面ではStrapi一択ですね。ContentfulやSanityなどのSaaS型も良いですが、月額費用やベンダーロックインが気になる人にはStrapiが合っている。
特に「Node.jsに慣れている」「自分でサーバー管理できる」「カスタマイズしたい」という人には最適。ヘッドレスCMSの導入を検討しているなら、まずStrapiから試してみてください。
管理画面のUIも洗練されていて、クライアントへの引き渡しもスムーズにいくはずです。