はじめに
Contentfulで多言語サイトを構築中、運用担当者から「新規ページを作成してもPublishボタンがアクティブにならない」という報告を受けました。既存ページの更新は問題なくできるのに、新規作成だけができないという状況です。
本記事では、原因の特定プロセスと解決方法を紹介します。
環境
- Contentful(ヘッドレスCMS)
- ロケール: 日本語(ja、デフォルト)+ 英語(en)
- Next.js + Contentful Delivery API でフロントエンドを構築
症状
- 新規にPageエントリーを作成し、必要な情報をすべて入力しても Publishボタンがグレーアウト してクリックできない
- 既存ページの更新(タイトルや本文の変更)は問題なくPublishできる
- Draft保存は正常に動作する
原因の切り分け
1. コンテンツタイプのバリデーションを確認
まず、pageコンテンツタイプのフィールド定義を確認しました。
title: Symbol, required: true, localized: true
slug: Symbol, required: true, localized: false
body: RichText, required: false, localized: true
bodyMarkdown: Text, required: false, localized: true
titleとslugが必須ですが、どちらも入力済み。slugのバリデーション(^[a-z0-9]+(?:-[a-z0-9]+)*$)にも違反していませんでした。
2. ユーザー権限を確認
Management APIでスペースメンバーシップを確認しました。
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.contentful.com/spaces/$SPACE_ID/space_memberships"
報告者はAdmin権限を持っており、権限の問題ではありませんでした。
3. APIから直接Publishを試行 — 原因特定
UIでは原因がわからなかったため、Management APIから直接Publishを試みました。 これが決め手になりました。
curl -s -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "X-Contentful-Version: 13" \
"https://api.contentful.com/spaces/$SPACE_ID/environments/master/entries/$ENTRY_ID/published"
レスポンス:
{
"sys": { "type": "Error", "id": "InvalidEntry" },
"message": "Validation error",
"details": {
"errors": [
{
"name": "required",
"path": ["fields", "title", "en"],
"details": "The property \"en\" is required here"
}
]
}
}
英語ロケールのtitleが未入力であることがバリデーションエラーの原因でした。
根本原因
ロケール設定を確認すると、以下の状態でした。
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.contentful.com/spaces/$SPACE_ID/environments/master/locales"
| ロケール | デフォルト | optional | fallbackCode |
|---|---|---|---|
| ja (日本語) | Yes | false | なし |
| en (英語) | No | false | なし |
問題は2点です。
optional: false— 英語の入力が必須。ローカライズされた必須フィールド(title)は、すべてのロケールで値が必要になるfallbackCode: null— フォールバックが未設定。英語の値がない場合に日本語の値を代用する仕組みがない
運用担当者は日本語でのみコンテンツを入力しており、英語のtitleを入力していなかったため、バリデーションに引っかかっていました。
なぜ既存ページは更新できたのか?
既存ページは開発時に日英両方のtitleを入力してPublish済みでした。更新時は既存の英語titleがそのまま残っているため、バリデーションを通過できていたのです。
解決方法
英語ロケールの設定を変更しました。
curl -s -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/vnd.contentful.management.v1+json" \
-H "X-Contentful-Version: $VERSION" \
"https://api.contentful.com/spaces/$SPACE_ID/environments/master/locales/$EN_LOCALE_ID" \
-d '{
"name": "English",
"code": "en",
"fallbackCode": "ja",
"optional": true
}'
変更内容:
| 設定 | 変更前 | 変更後 | 効果 |
|---|---|---|---|
optional | false | true | 英語の入力が任意になる |
fallbackCode | null | “ja” | 英語が未入力の場合、日本語の値にフォールバック |
この変更により、運用担当者は日本語のみ入力すればPublishできるようになり、英語の値が必要な場合は日本語の値が自動的に使用されます。
UIでは気づきにくい理由
ContentfulのWeb UIは、Publishボタンがグレーアウトしている理由を必ずしも明確に表示しません。特に多言語設定では、現在表示中のロケール(日本語)ではすべてのフィールドが正しく入力されているように見えても、別のロケール(英語)側でバリデーションエラーが発生しているケースがあります。
UIのサイドバーにエラー表示が出ることもありますが、ロケールを切り替えないと具体的な原因が見えない場合があります。
教訓
- 多言語サイトでは、ロケールの
optionalとfallbackCodeを最初に設定する — 特にデフォルト以外のロケールはoptional: true+フォールバック設定をしておくと、運用時のトラブルを防げる - UIで原因不明の場合はManagement APIを使う — APIからの操作はエラーメッセージが明確で、原因特定が速い
- 開発者と運用者の操作パターンの違いに注意 — 開発者は全ロケールを入力するが、運用者はデフォルトロケールのみで作業することが多い
まとめ
ContentfulでPublishできない問題の多くは、バリデーションエラーに起因します。特に多言語設定では、ロケールごとの必須/任意設定とフォールバックの有無が重要です。UIだけで原因を特定できない場合は、Management APIを活用することで、具体的なエラーメッセージを取得できます。