マキモノ
Web開発無料✅ 公式検証済みv1.0.0 / 更新

SSGサイトへ商品を一括投入し、CC0画像を安全に付けて一覧まで反映させる指示書

Next.js App Router + DB の商品カタログにスクリプトで商品をまとめて追加する手順。Openverse CC0画像の実用的な取得・目視選別、透かし/他社ブランドの排除、そして「詳細は200なのに一覧が古い」静的生成の罠と revalidate の正しい発火方法、Layer1/Layer2 の検証まで。

出品者: nishi@orgiast.jp2 DL📖 読込 約2,519トークン (約4円)💰 コスパ 18
トークン節約メーター84%節約
ゼロからAIに作らせた場合5.5万トークン
このMDを読ませた場合9,000トークン

4.6万トークンの節約 (API料金換算で約69円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。

この巻物について

SSGサイトへ商品を一括投入し、CC0画像を安全に付けて一覧まで反映させる指示書」は、Web開発カテゴリのAI指示書(MDファイル)です。Next.js App Router + DB の商品カタログにスクリプトで商品をまとめて追加する手順。Openverse CC0画像の実用的な取得・目視選別、透かし/他社ブランドの排除、そして「詳細は200なのに一覧が古い」静的生成の罠と revalidate の正しい発火方法、Layer1/Layer2 の検証まで。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約4.6万トークン(API料金換算で約69円)・84%のトークンを節約できます。

カテゴリ
Web開発
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約5.5万トークン
この巻物使用時
約9,000トークン
節約量
約4.6万トークン (約69円)
更新日
2026-08-28

使い方 (AIに渡す3つの方法)

いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/ssg-cc0/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

SSG(静的生成)ECサイトへ商品を一括投入し、フリー素材画像を安全に付けて「一覧まで」反映させる指示書

対象: Next.js App Router + Supabase(または任意のDB) で作られた商品カタログ/EC。 スクリプトからDBへ商品をまとめて追加し、画像をフリー素材で補い、公開ページに確実に出た状態で終わらせるまでの手順。

0. この指示書が防ぐ3つの事故

  1. 「詳細ページが200だから反映OK」の誤判定 — 一覧ページが古いまま=来訪者には存在しない商品になる。
  2. フリー素材の透かし・他社ブランド混入 — 商用サイトに載せてから気づくと差し替えコストが高い。
  3. キーワードが英語圏の古典画像に吸われる — CC0検索は美術館アーカイブに偏り、「それっぽいが業務内容と無関係」な画像を掴む。

1. 事前確認(着手前に必ず)

# 既存の slug 一覧・カテゴリ/シーンの enum・sort_order の最大値を先に取る
# 「似た商品が既にある」ケースが最も多い失敗。名前が違っても内容が重複していれば統合か差別化を決める。
  • 追加予定の slug が既存と内容重複していないかを人が読んで判定する。重複していたら 「別カテゴリの別形態(例: 制作 vs レンタル)」として差別化するか、追加しない。
  • カテゴリキー・シーンキーは型定義ファイルの enum を実際に読む(記憶で書くと表示から漏れる)。
  • sort_order は既存の最大値を見て、今回の追加分を連番で確保する。

2. フリー素材画像(CC0/PDM)の取得

Openverse API は CC0/パブリックドメインだけを絞って取れる(帰属不要・商用可)。

https://api.openverse.org/v1/images/?q=<1〜2語>&license=cc0,pdm&size=large&page_size=12&mature=false

実務上の落とし穴と対処:

症状原因対処
0件になる多語ANDで絞られるクエリは1〜2語にする
骨董広告・浮世絵・古い版画ばかりCC0は美術館/PDアーカイブに偏るクエリを現代の物体名に寄せる(例: 「brochure」より「graphic design」「printing machine」)
現地語の固有名詞が0件英語タグしか付いていない一般名詞に置換(例: 屋台→street foodtakoyaki のような世界的に通る単語は生きる)
ダウンロードが失敗するランタイムのfetchが弾かれる/シェルのクォート崩れexecFileSync('curl.exe', [配列引数]) で叩く(& を含むURLは文字列連結で壊れる)

1slugに複数クエリのフォールバックを持たせるのが要点。1巡目で全滅する前提で組む。

const Q = { "<slug>": ["<第1候補>", "<第2候補>", "<第3候補>", "<第4候補>"] };
// 各slugについて、必要枚数に達するまでクエリを順に試す
// 700px未満は捨てる / 1600px内側リサイズ + jpeg quality 85 で保存

3. 画像の目視検査(省略禁止・2段)

  1. モンタージュ: 取得した全候補を slug × 候補 のグリッド1枚に合成して1回の閲覧で全件見る。 ラベルと連番を焼き込むと、そのまま採用リストが書ける。
  2. 下部cropの拡大: 採用候補だけ、画像の下25%を切り出して拡大した1枚を作り透かしを確認する。 素材サイトの中には作品自体にwordmarkを入れている配布元がある。

不採用にする基準(機械では判定できないので人/AIが見る):

  • 透かし・配布元のwordmarkが写っている
  • 識別可能な他社ブランド(車・製品ロゴ・店名)が主題になっている
  • 政治的な題材、特定の実在人物が主題
  • 業務内容と無関係(キーワードの語義違いで来たもの)

最良の代替は「自社資産の流用」: 自社で撮った既存商品の写真があるなら、 ストレージ内コピー(例: Supabase Storage の copy(from, to))で新商品に流用する。 ライセンス問題がゼロで、内容も正確になる。人物ストック写真より優先する

出典は必ずファイルに残すlicense / source URL / title)。後から問い合わせが来たときの唯一の根拠になる。

4. 投入スクリプト

// 1) --dry を必ず実装する(名前・価格・カテゴリ・シーン・枚数を目で確認してから本番投入)
// 2) upsert 相当にする(slug で既存を引いて update / なければ insert)=再実行で重複を作らない
// 3) 画像はリサイズしてからアップロードし、公開URLを配列で持たせる
// 4) 説明文の末尾に共通の注記(見積の但し書き等)を機械的に付ける=書き忘れが起きない

商品説明は書き下ろす。素材サイトの説明文や他社サイトの文章を流用しない。

5. 反映(ここが最大の罠)

App Router の静的生成では、ページ種別で再生成のタイミングが違う

ページDB直接投入した直後の挙動
詳細 /products/[category]/[slug]dynamicParams の既定でon-demand生成され200を返す(=反映されたように見える)
一覧 / カテゴリ / シーン別 / トップビルド時の内容のまま。新商品が出ない

来訪者は一覧から辿るので、一覧に出ていなければ実質未公開

発火のさせ方(デプロイ権限が無くても可):

  • A. アプリ本来の書き込み経路を1回通す — 管理画面で商品を1件保存すると Server Action 内の revalidatePath("/", "layout") が走り、全ページが再生成される。 公開面を汚さないため「非公開フラグのダミー商品」を保存し、あとで削除する。 ブラウザ自動化(Playwright 等)でログイン→保存まで自動化できる。
  • B. 恒久策: トークン認証付きの revalidate エンドポイントを用意する
// app/api/revalidate/route.ts
import { NextRequest, NextResponse } from "next/server";
import { revalidatePath } from "next/cache";
export const dynamic = "force-dynamic";
function authorized(req: NextRequest) {
  const expected = process.env.<既存の管理用パスワード等>;   // 新しい秘密情報を増やさない
  if (!expected) return false;
  const given = req.headers.get("x-admin-password") ?? new URL(req.url).searchParams.get("token") ?? "";
  return given.length === expected.length && given === expected;
}
async function handle(req: NextRequest) {
  if (!authorized(req)) return NextResponse.json({ ok: false }, { status: 401 });
  revalidatePath("/", "layout");
  return NextResponse.json({ ok: true, at: new Date().toISOString() });
}
export const GET = handle; export const POST = handle;

投入スクリプトの最後にこのエンドポイントを叩かせる(新しい環境変数を増やさず既存の認証情報を使うのがコツ)。 エンドポイントが未デプロイの間は A で代替できる、と自分でログに出すところまで書いておく。

6. 検証(2段。どちらか欠けたら未完了)

Layer 1(ロジック層 / Node スクリプト)

  • DB: 投入件数・総件数・published・カテゴリ・シーンが既知キーのみ・価格>0・説明文の最低文字数
  • 画像: 全公開URLに HTTP 200
  • 本番HTML: 詳細ページに商品名・価格の表示形式(桁区切り)・画像ファイル名が含まれる
  • 一覧ページのHTMLに /products/<category>/<slug> へのリンクがある ← これを必ず入れる

Layer 2(ブラウザ層 / Playwright)

  • 管理画面ログイン → 非公開ダミー保存で revalidate 発火
  • カテゴリ一覧に新商品リンクが出るまでリトライ(再生成に数秒のラグがある。キャッシュバスターのクエリを付ける)
  • 各詳細ページで h1 の文言・価格テキスト・img の src を assert
  • シーン別・タグ別など別の導線ページも1つは確認する
  • 後片付け: ダミー商品を削除

7. 完了報告のテンプレ

- 追加: N点(slug/価格/カテゴリの表)
- 画像: 出典と枚数、不採用にした理由
- typecheck: PASS
- Layer 1: <script> → PASS(一覧掲載の assert を含む)
- Layer 2: <script> → PASS(実描画)
- 反映: revalidate 発火済み(方式Aか B かを明記)

「ハードリロードして確認してください」「次のデプロイで出ます」は未完了。一覧に出たことを自分で確認して初めて完了。

よくある質問

「SSGサイトへ商品を一括投入し、CC0画像を安全に付けて一覧まで反映させる指示書」とは何ですか?

Next.js App Router + DB の商品カタログにスクリプトで商品をまとめて追加する手順。Openverse CC0画像の実用的な取得・目視選別、透かし/他社ブランドの排除、そして「詳細は200なのに一覧が古い」静的生成の罠と revalidate の正しい発火方法、Layer1/Layer2 の検証まで。

どれくらいトークン(費用)を節約できますか?

ゼロから開発すると約5.5万トークンかかりますが、この巻物を使えば約9,000トークンで済みます。差し引き約4.6万トークン(API料金換算で約69円)・84%の節約です。

どうやって使いますか?

無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。

どのAIツールに対応していますか?

claude-code、cursor、codex-cli に対応しています。

商用利用できますか?

ライセンスは「商用利用可 (再販不可)」です。

🤝 自分でAIを動かすのは、まだ不安…という方へ

この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア