generating-weaverse-project-json について
設計仕様や既存のエクスポートなどを基に、Weaverse プロジェクトの JSON を生成するスキルです。インポート前にスキーマに沿った構成と検証を行います。
主な機能
- 01インポート用プロジェクト JSON の生成
- 02設計仕様や既存エクスポートへの対応
- 03登録済みセクションとブロックの確認
- 04付属スクリプトによる構造検証
活用シーン
- 01ストアの説明から Weaverse プロジェクトを作成
- 02Studio に取り込むページデータを準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ weaverse/ shopify-hydrogen-skills --skill generating-weaverse-project-jsonインストール後、Claude Code で/generating-weaverse-project-jsonを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/demo.jsonproject-json-schema.mdscripts/validate.py詳細
Weaverse プロジェクト JSON の生成
有効で、インポート可能な Weaverse プロジェクトのエクスポート JSON ファイルを生成します。
概要
このスキルは、Weaverse のインポート仕様に準拠した JSON ファイルを生成します。単独で使用でき、サイト移行、デザイン仕様書、口頭での説明など、ページやセクションに必要な要素を記述したあらゆる入力を利用できます。
出力は、references/project-json-schema.md のスキーマに準拠した単一の JSON ファイルです。実例は references/demo.json にあります。
入力
このスキルでは、次のいずれかを入力として受け付けます。
- セクションマッピング:
cloning-websites-to-weaverseからの入力(Web サイト移行のフロー) - セクションマッピングとトークンテーブル:
figma-to-weaverseからの入力(Figma デザインのフロー) - デザイン仕様書:ページ、セクション、コンテンツを記述したもの
- 口頭での説明:ストアフロントの外観についての説明
- 既存のエクスポート:変更または拡張するもの
唯一の必須条件は、使用するセクションタイプを把握していることです。登録済みのセクションとブロックの一覧を確認するには、app/weaverse/components.ts を読みます。
納品
このスキルは、プロジェクトの構造(ページ、セクション、初期コンテンツ)を定義する インポート用 JSON を生成します。この JSON を Weaverse Studio エディターに一度インポートして、プロジェクトを作成します。
構造の作成後、コンテンツの継続的な編集(テキスト、画像、ローカライズ、一括更新)には再インポートではなく、weaverse-content-api スキルを使用してください。後続のパッチが同じ項目を対象にできるよう、両方で項目 ID を維持します。
プロジェクトがすでに存在する場合(公開中のストアにページを追加する場合は通常こちら)、インポートは不要です。POST /projects/:projectId/pages でページを作成し、JSON の項目を 1 回の PATCH で送信します(weaverse-content-api の「新規または空のページにデータを設定する」を参照)。プッシュした内容の記録として JSON ファイルをリポジトリに保存し、その後ライブページを変更した場合は、ファイルにも変更を反映してください。
生成手順
- リファレンスを読む — 仕様を確認するため
references/project-json-schema.mdを読み、実際の完全な例を確認するためreferences/demo.jsonを読みます - 登録済みのタイプを確認する — 使用可能なセクションタイプとブロックタイプを確認するため、
app/weaverse/components.tsを読みます - セクションのソースコードを読む — 使用する各セクションタイプについて、
app/sections/またはapp/components/にあるソースを読み、有効なスキーマフィールド、列挙値、デフォルト値を確認します - JSON を作成する — 以下の構造に従って作成します
- バリデーターを実行する —
python3 scripts/validate.py <output-file>(Python 3.8 以降で動作)を実行して、構造上のエラーを検出します - 問題を修正する — バリデーターが報告した問題を修正し、エラーがなくなるまで再実行します
JSON 構造
トップレベル
{
"version": "1.0.0",
"exportedAt": "<ISO timestamp>",
"project": { "name": "<name>", "config": {} },
"pages": [],
"pageAssignments": []
}
project.config
テーマ設定、ロケール、色を含みます。使用できるキーは次のとおりです。
| キー | 型 | 用途 |
|---|---|---|
previewHost | string | 開発サーバーの URL。通常は http://localhost:3456 です |
theme | object | ストア全体のデザイントークン(色、タイポグラフィ、レイアウト) |
defaultLocale | object | { label, language, country, currency, pathPrefix } |
recentColors | string[] | エディターのカラーピッカーで最近使用した色 |
theme の有効なキーの全一覧については、references/demo.json → project.config.theme を参照してください。キーの分類は次のとおりです。
- 色:
colorPrimary、colorText、colorBackground、colorLine、colorTextSubtle、colorLineSubtle、colorTextInverse、colorForeground - タイポグラフィ:
bodyBaseSize、bodyBaseLineHeight、bodyBaseSpacing、h1BaseSize、headingBaseLineHeight、headingBaseSpacing - レイアウト:
pageWidth、footerWidth、headerWidth、navHeightDesktop、navHeightTablet、navHeightMobile - ヘッダー/フッター:
headerBgColor、headerText、footerBgColor、footerText、topbarBgColor、topbarTextColor、topbarHeight - ボタン:
buttonPrimaryBg、buttonPrimaryColor、buttonSecondaryBg、buttonSecondaryColor、btnCornerRadius - 商品カード:
pcardAlignment、pcardImageRatio、pcardBorderRadius、pcardShowVendor、pcardShowReviews、pcardShowSalePriceなど - バッジ:
newBadgeText、newBadgeColor、saleBadgeText、saleBadgeColor、soldOutBadgeText、soldOutBadgeColor、bestSellerBadgeText、bestSellerBadgeColor - ソーシャル:
socialFacebook、socialInstagram、socialLinkedIn、socialX - ニュースレター:
newsletterTitle、newsletterDescription、newsletterButtonText、newsletterPlaceholder、newsletterPopupEnabledなど
理解しており、設定する意図のあるテーマキーのみを含めてください。デモのテーマ全体をそのままコピーしないでください。
ページ
各ページには id、name、rootId、フラットな items 配列があります。
{
"id": "b98mnnqmv3tmce7wmw3l7vw4",
"name": "Homepage",
"rootId": "019b917a-f48f-72d4-aee7-3b1eae6b7dca",
"items": [
{ "id": "019b917a-f48f-72d4-aee7-3b1eae6b7dca", "type": "main", "data": {}, "children": [{ "id": "019b917a-f48f-72d4-aee7-3b1f5ca586c1" }] },
{ "id": "019b917a-f48f-72d4-aee7-3b1f5ca586c1", "type": "hero-image", "data": { "height": "small" }, "children": [{ "id": "019b917a-f48f-72d4-aee7-3b22cd55e21b" }] },
{ "id": "019b917a-f48f-72d4-aee7-3b22cd55e21b", "type": "heading", "data": { "content": "Welcome" }, "children": [] }
]
}
主なルール:
- フラットな items — すべてのアイテムは
items配列に格納され、階層はchildrenの ID 参照で表現されます - ページごとにルートの
mainアイテムを 1 つ — その ID はrootIdと一致している必要があります - すべてのアイテムで
childrenが必須 — 葉アイテムには[]、親アイテムには[{ "id": "<item-id>" }]を使用します - すべてのアイテムで
dataが必須 — デフォルト以外の値が不要な場合は{}を使用します typeはapp/weaverse/components.tsに登録されたセクションまたはブロックの型である必要があります
重要: Weaverse インポーターでは、すべてのアイテムに data と children の両方が必要です。どちらかを省略すると、インポートがエラーなしで失敗し、ページが空で表示されます。空の場合も、必ず "data": {} と "children": [] を含めてください。
ページの割り当て
ページをルートに対応付けます。
{ "pageId": "b98mnnqmv3tmce7wmw3l7vw4", "type": "INDEX", "handle": "", "locale": "en-us" }
一般的な型:INDEX、PRODUCT、COLLECTION、ALL_PRODUCTS、COLLECTION_LIST、PAGE、BLOG、ARTICLE、CUSTOM。
CUSTOM ページでは、handle にルートのスラッグ(例:"reseller")を設定します。標準テンプレートページでは、通常 handle は空の "" にします。
テンプレートページのスタブ
カスタマイズしない標準ページ(商品、コレクション、ブログ、記事)は、空のスタブにしてください。
{
"id": "qa8xa47ou35atbo1ik4w7v6y",
"name": "Default product",
"rootId": "019b917a-f490-794d-95d0-82a578d7cdfc",
"items": [{ "id": "019b917a-f490-794d-95d0-82a578d7cdfc", "type": "main", "data": {}, "children": [] }]
}
データ値のルール
検証済みの列挙値のみを使用する
select、toggle-group、または position の値を記述する前に、セクションのソースコードを確認してください。よくある誤りは次のとおりです。
| 誤り | 正しい値 | フィールド |
|---|---|---|
"custom" | "small"、"medium"、"large"、"full" | height |
"stretch" | "full"、"fixed" | width |
"right" / "left" | "start"、"end" | desktopMediaPosition |
"white" / "black" | "light"、"dark" | arrowsColor |
デフォルト値以外のみを含める
フィールドがスキーマのデフォルト値と一致する場合は、省略してください。Weaverse エディターは保存時にデフォルト値を取り除きます。含めると不要な情報が増えます。
スキーマのプリセットはデフォルト値ではありません。セクションのpresetsによって有効になる値(例:enableOverlay: true)は、マーチャントがStudioでセクションを追加したときにのみ適用され、インポート時やContent APIへの書き込み時には適用されません。入力のdefaultValueと比較し、実際に使いたいプリセット値は明示的に設定してください。
Shopify エンティティの参照
コレクションと商品には、単純な文字列ではなくオブジェクト形式を使用します。
// Collections
"collections": [{ "id": 456905851102, "handle": "covers" }]
// Products
"product": { "id": 123456789, "handle": "my-product" }
実際のShopify IDが不明な場合は、フィールドを省略するか、[]を使用してください。架空のIDを作らないでください。
画像フィールド
外部画像には、URL文字列をそのまま使用します。Shopifyにホストされた画像には、メディアオブジェクトを使用します。
// External
"backgroundImage": "https://example.com/image.jpg"
// Shopify media
"backgroundImage": {
"id": "gid://shopify/MediaImage/12345",
"url": "https://cdn.shopify.com/...",
"width": 1920, "height": 1080, "altText": "Description"
}
公開するものには、Shopifyのメディアを使用してください。Figma MCPのアセットURL(figma.com/api/mcp/asset/...)は約7日で期限切れになり、一部のストアフロントの画像変換ではブロックされます。まずファイルをShopifyにアップロードし(weaverse-content-api → upload)、返されたオブジェクトを使用してください。SVGは汎用ファイルとしてアップロードされ、プレーンなCDN URL文字列として返されます。
ID形式のルール
ページIDとアイテムIDでは、形式が異なります。
| エンティティ | 形式 | 例 |
|---|---|---|
ページのid | CUID(英数字25文字) | b98mnnqmv3tmce7wmw3l7vw4 |
アイテムのid(およびrootId) | UUID v7(ハイフン区切り) | 019b917a-f48f-72d4-aee7-3b1eae6b7dca |
整合性のルール:
- エクスポート全体で、すべてのページの
idは一意でなければなりません - エクスポート全体で、すべてのアイテムの
idは一意でなければなりません rootIdは、ルートのmainアイテムのidと完全に一致する必要があります- すべての子参照は、同じページ内に存在するアイテムを指していなければなりません
- ページIDはCUIDです。CUIDジェネレーターを使用するか、25文字の小文字英数字の文字列を生成してください
- アイテムIDはUUIDです。UUID v7形式(タイムスタンプ順に並べ替え可能なハイフン区切り)を使用してください
- 1つのリポジトリに複数のエクスポート(ページごとに1つ)がある場合は、ページごとに異なるID範囲を割り当ててください(例:ホームページには
019b9400-…、次のページには019b9500-…)。こうすることで、同じプロジェクトにページをプッシュしたときにアイテムが重複しません
検証
JSONを生成した後、同梱のバリデーターを実行してください。
python3 scripts/validate.py <path-to-output.json>
バリデーターは次の項目をチェックします:
- JSON構造が有効であること
- 必須のトップレベルフィールドが存在すること
- すべてのページに
id、name、rootId、itemsがあること - すべての
rootIdが、type: "main"を持つアイテムに解決されること - すべてのアイテムに
dataフィールドとchildrenフィールドの両方があること(どちらも必須) - アイテムIDが重複していないこと
- すべての子参照が、同じページ内にある既存のアイテムに解決されること
- すべての
pageAssignment.pageIdの値が、既存のページに解決されること
報告されたエラーを修正し、エラーがなくなるまで再実行してください。検証に失敗するJSONは納品しないでください。
よくある間違い
| 間違い | 修正方法 |
|---|---|
アイテムにdataまたはchildrenがない | どちらもすべてのアイテムで必須です。空の場合も"data": {}と"children": []を使用してください |
children内にアイテム全体をネストしている | { "id": "..." }の参照のみを使用してください |
rootIdがどのアイテムにも一致しない | ルートのmainアイテムのidがrootIdと等しいことを確認してください |
| 登録されていないセクションタイプを使用している | まずapp/weaverse/components.tsを読んでください |
| IDが重複している | ページIDはCUID、アイテムIDはUUIDです。すべてのIDが一意でなければなりません |
dataにデフォルト値を含めている | スキーマのデフォルト値と一致するフィールドは省略してください |
| 列挙型の値を推測している | 有効な値について、セクションのソースを読んでください |
| デモテーマ全体をそのままコピーしている | 理解していて、使う意図のあるキーのみを含めてください |
pageAssignmentsがない | すべてのページにルート割り当てが必要です |
| 架空のShopify IDを使用している | 不明なIDは省略し、エディターでユーザーに選択してもらってください |
| 公開用エクスポートにFigmaアセットURLを残している | Shopifyにアップロードし、メディアオブジェクトを使用してください。FigmaのアセットURLは期限切れになります |
| プリセット値に依存している | インポート時やAPIへの書き込み時にはプリセットは適用されません。該当する値を明示的に設定してください |