SaaSは死なない?ひとつ死にましたが

Shinji Saito
Shinji Saito

代表取締役社長 / 文部科学省 最高情報セキュリティアドバイザー

シンジです。自社コーポレートサイトのフルリニューアルを、エンジニア2人とClaude Code 、実稼働18日で完成しました。シンジが稼働したのは2日だけです。138ページ、画像2,098枚、Lambda 4関数。総コミット228件のうち99%はAIが書いてます。以前使っていたSaaS ノーコードWeb制作プラットフォーム StudioはFreeプランに変更です。社内からSaaSがひとつ消えました。そしてこの記事も下書きはAIが書いてます。たまにこの記事にシンジが突っ込みを入れてます。どこをシンジが書いた文章なのかも探してみてください。

Studio を捨てたら、全部よくなった

とにかくStudioを捨てたかった。Studioの使い方が分かる人しかWeb制作できないし、そもそもStudioで作ったWebサイトは重すぎる。開くのに時間がかかる。今はFreeプランに変更して年間契約は終了です。

現在は、Astro + SCSS + MDX の静的サイトに置き換えました。SEOスコア 100点です。AEO(AI向けのやつ)にも注力しまくってます。インフラはAWS の Amplify です。Amplify はいいぞ。ポチポチするだけでお手軽にWebインフラ作ってくれるし WAF までついてる優れもの。Github更新されると勝手にWebサイトも更新してくれる。

得られたものは3つです。

パフォーマンスが爆速になった。 メインCSSが1MB から 225KB に縮小して、PageSpeed Insights の Performance スコアが 64 から 85 に回復しています。フォントの @font-face 宣言616ルール(778KB)がレンダリングブロックから外れたのが最大の要因なんですが、これは Studio 時代にはそもそもコントロールできなかった領域です。

Studio の操作を覚えるという無駄が消えた。 Studio は「Figmaからコード生成」という甘い夢を見せてくるわけですが、実際に生成されるコードの品質がいまいち。カスタマイズしようとすると Studio 固有の概念を理解しないといけなくて、「Studio の使い方を覚える」という、本来のゴールとは何の関係もないスキルに時間を吸い取られるわけです。これがゼロになった。代わりに得たのは Astro という汎用フレームワークの知識で、こっちは他のプロジェクトにも転用できます。

コストがアホほど下がった。 Studio は何度か値上げもしてましたし。今は純粋な静的ホスティングと、お問い合わせフォーム用の Lambda だけ。最小構成になりました。インフラ維持にかかる費用は従量課金ですがどう見積もっても月額1ドルです。かかっても2ドル。ほとんどが AWS の無料枠で収まります。会社公式Webサイトのインフラ維持費が300円未満とか笑える。


このプロジェクトの規模感

先に数字を出しておきます。

  • ソースファイル 335個、ソースコード約58,000行
  • MDXコンテンツ 138ファイル(製品36、サービス8、導入事例11、お悩み13、ニュース38、イベント32)
  • Astro コンポーネント 63個、ページテンプレート 22個、SCSS 45ファイル
  • 画像アセット 2,098枚(46MB、全て WebP)
  • Lambda バックエンド 15ファイル / 3,793行(TypeScript)
  • AIへのガイドラインドキュメント 17,047行
  • CLAUDE.md(AIへの設計書)539行
  • 総コミット 228件

技術スタックは、フレームワークが Astro 5.x(SSG)、スタイルが SCSS の FLOCSS 設計で CSS Grid 中心、コンテンツ管理は MDX の Content Collections、ホスティングが AWS Amplify Hosting、バックエンドが AWS Lambda x 4(SAM)、テストに Playwright のビジュアルリグレッション、AI は Claude Code でコーディングとコンテンツ生成、画像生成に GPT Image 1 を MCP 経由で使ってます。


2人でどう分担したか

このプロジェクトのメンバーは、マーケティングのAmeku氏(エンジニア)とシンジの2人です。インフラの初期セットアップだけAkira氏(エンジニア)が4コミット分やってくれてます。

Ameku氏の仕事は、Figma デザインからの初期実装、コンポーネント設計、SCSS、レスポンシブ対応。65コミット。つまりサイトの「見た目」を作る部分です。どんな技術スタックを使うかも決めてくれています。

シンジの仕事は、138ページ分の MDX コンテンツ全量生成、SEO/AEO 最適化、セキュリティ対策、パフォーマンス改善、お問い合わせフォームの Lambda バックエンド開発。157コミット。つまり「中身」と「裏側」の全部です。

157コミットのうち、シンジが手でコードを書いたのはゼロで、全部 Claude Code が書いています。シンジの仕事は「Claude Code に何を書かせるか」を設計して、出てきたものをレビューすることだったわけです。


時系列で見る

ここからは git のコミットログに基づいて、プロジェクトがどう進んだかを追っていきます。

Phase 1:設計と Figma 実装

astro create で初期プロジェクトを作成。ここが起点です。

ameku氏が Figma デザインからの一括実装をドンと投入してます。コンポーネント、レイアウト、スタイル、アセット、コンテンツ下書き、ガイドラインドキュメント一式。メガメニューとヘッダーのスクロール追従アニメーションもこの日に完成しています。

次にフッターのレスポンシブ対応。この時点で Figma デザインの主要コンポーネントはほぼ実装済みでした。Storybook も一度入れたんですが、Playwright VRT に集中するため後に削除してます。

Phase 2:レスポンシブとコンテンツ構造化

全セクションのレスポンシブ対応とモバイルナビゲーションの実装。フッターアニメーション追加、コンテンツ下書きの削除と SVG アセット最適化。

Figma との往復やデザインの詰めをやっていた時期です。コードに現れない作業というのは確実にあります。

Phase 3:本格始動

プロジェクト最大の転換点です。この1日で何が起きたかというと、プロジェクト構成の整理、サービスページの .md から .mdx への移行、製品ページのコンテンツ更新、Amplify Hosting のセットアップ(Akira担当)、最初のデプロイ成功、そして Claude Code による AEO/SEO 最適化とコンテンツ拡充の開始。要するに、インフラが整って、Claude Code のコミットが爆発的に増え始めた日です。

そして新規7製品ページを一括追加。JSON-LD 構造化データを全ページに組み込み。ここからはもう、AIにコンテンツを生成させては投入、生成させては投入、の繰り返しです。

Phase 4:コンテンツ爆速生成期

ニュース・イベントページのリデザインと導入事例リニューアル。

このあたりはAmeku氏の最後の大きなマージが入った時期で、デザイン改善や新ページ追加、アクセシビリティ修正が入ってます。並行してシンジ側では、全製品フィーチャー画像179枚の AI 生成、全製品ヒーロー画像36枚の再生成、お問い合わせフォームの自前実装(Tally からの移行)、Cloudflare Turnstile の導入、メルマガ登録機能(SendGrid 連携)、資料ダウンロード機能と、怒涛の開発。

仕上げの日は、1日に20コミット以上入ってます。SEO 最適化(metaTitle と metaDescription を全ページ分)、リンク切れ11件の修正、E-E-A-T シグナルの補完、導入事例カルーセルのバグ修正、Node 20 互換性問題の解決、FAQ の実データ投入、イベント画像25件のリンク切れ修正。

Phase 5:品質・セキュリティ・パフォーマンス

AI 生成画像を大量投入。製品ページ36枚、お悩みページ13枚。あとプレースホルダー画像を全廃して、製品ロゴの欠損も修正してます。

セキュリティとパフォーマンスの集中改善。セキュリティヘッダー8種の設定(CSP、HSTS、X-Frame-Options 等)、画像圧縮とキャッシュヘッダー、フォントプリロードの最適化、CSP の段階的強化(Clarity、GTM、Google Ads、Maps に対応)、セキュリティ監査26件の修正。

そしてパフォーマンスチューニングのラストスパート。ここで一番インパクトのあった改善をやりました。フォント CSS をメインバンドルから分離して非同期読み込みに変更。メイン CSS が 1MB から 225KB に縮小。CSS のインライン化も試したんですが、逆にパフォーマンスが悪化したので即 revert してます。こういう「やってみたけどダメだった」が記録に残るのも git のいいところです。

そして最終日。製品ページの文言を事実ベースに修正(FutureVuls、BLACKPANDA、CrowdStrike の3ページ)。社内からのフィードバックを反映しています。AI が書いた文章は放っておくと「何でも即日対応します」みたいな過剰な訴求をしがちなので、事実に基づいた控えめな表現に修正しました。GTM Consent Mode v2 の設定修正と、CLAUDE.md の最終更新もこの日です。


Claude Code に投げたプロンプトの実例

ここが多くの人が気になるところだと思うので、具体的に書きます。

プロンプトは事前に体系化した

プロジェクト開始時に、ページ種別ごとに9種類のコーディングプロンプトを用意しました。AIが。

docs/prompts/
├── 00_BASE_CODING_PROMPT.md     — 全ページ共通の技術仕様
├── 01_PRODUCT_PAGE_PROMPT.md    — 製品ページ(36ページ分)
├── 02_CONCERN_PAGE_PROMPT.md    — お悩みページ(13ページ分)
├── 03_SERVICE_PAGE_PROMPT.md    — サービスページ(8ページ分)
├── 04_CASE_STUDY_PROMPT.md      — 導入事例ページ
├── 05_NEWS_EVENT_PROMPT.md      — ニュース・イベント
├── 06_CONTACT_DOWNLOAD_PROMPT.md — お問い合わせ・資料DL
├── 07_LEGAL_PROMPT.md           — 法務ページ
├── 08_COMPANY_PROMPT.md         — 会社概要
└── visual-inspection-prompt-v3.md — ビジュアルQA用

ベースプロンプトにはカラーパレット、タイポグラフィ、ブレイクポイント、セマンティック HTML のルールなど、Figma から抽出したデザイントークンが全部入ってます。各ページプロンプトにはセクション構成、レイアウト指示、BEM クラス名の命名規則まで書いてある。合計17,047行。

なぜここまでやったかというと、AIに「いい感じに作って」と投げると、毎回違うスタイルの出力が返ってくるからです。138ページの品質を揃えるには、プロンプトの標準化が必須だったわけです。

と、AIがおっしゃっております。

実際に投げたプロンプト

製品ページの MDX は Content Collections の Zod スキーマに沿った frontmatter が必要で、手書きは非現実的でした。こういう指示で1ページずつ生成してます。

Okta の製品ページを作成してください。

- src/content/products/okta.mdx に配置
- frontmatter は config.ts のスキーマに準拠
- challenges は3つ、features は4つ、benefits は3つ
- FAQ は5問
- categorySlug は "identity"
- 公式サイトの情報に基づき、正確な製品説明を記載
- 「導入支援企業」ではなく「製品のお取り扱い紹介」のトーンで

最後の行がミソで、これを入れないと AI は「弊社はOktaの導入支援のプロフェッショナルとして即日対応します」みたいな嘘を平気で書きます。実際即日対応しててもWebでそれを言うと保証してるみたいになるしさすがにきついで?

SEO の一括最適化はこんな感じです。

全製品ページと全サービスページの metaTitle と metaDescription を
SEO最適化してください。各ページの内容を読み、検索意図に合った
タイトルと説明文に書き換えてください。

これだけで44ページ分の meta タグが書き換わります。人間がやったら丸一日かかる作業が、数分で終わるわけです。

セキュリティ監査も Claude Code にやらせました。基本的には /secrurity-review で終わらせるのですが、ここはWeb版の Claude にこう投げます

出てきた結果を Claude Code にコピペして終了です。インフラの詳細とか入力してあげるともっと精度あがるんですけど、まぁOKです。

1回で26件の問題が見つかって、全部その場で修正されてます。CSP のディレクティブ追加、Consent Mode の設定ミス、XSS エスケープ漏れ、Slack 署名検証の不備。

パフォーマンスの改善指示はこう。一般的なSEOとAIが読みに来るときに効いてくるAEOの2つの観点を重視してます。このテストは数回繰り返しました。

PageSpeed Insights でモバイルスコアが67点です。
Lighthouse の指摘事項を確認し、改善できるものを全て修正してください。
特にレンダリングブロックリソースとCLSに注目。

CLAUDE.md という「AIへの設計書」

このプロジェクトで最も重要だったファイルは、プロダクトのコードでもデザインでもなく、CLAUDE.md という539行のテキストファイルです。

これは Claude Code がプロジェクトを理解するための「取扱説明書」で、以下が書いてあります。

  • ルーティング構造とページ一覧
  • 製品カテゴリの全マッピング(14カテゴリ、36製品)
  • 新製品追加時の6箇所のチェックリスト
  • メガメニュー・TOPページ・製品一覧の3箇所同期ルール
  • コンテンツのトーンガイド(「導入支援企業」と書くな、等)
  • 会社エンティティ情報(代表者の漢字、肩書きの正式表記、誤記パターン)
  • CSS ルール(Grid 必須、Flexbox 原則禁止)
  • 画像規約(WebP 統一、img 属性の必須指定)
  • セキュリティヘッダーの管理方法と CSP 更新ルール
  • Amplify のデプロイフローとブランチ戦略

ポイントは、このファイルが開発中に28回更新されていることです。AI が作業するたびに新しい知見が生まれて、それを CLAUDE.md にフィードバックする。すると次の作業で AI の精度が上がる。

たとえば最初、AI は製品の categorySlug を間違えてリンク切れを量産しました。そこで CLAUDE.md に全 categorySlug の一覧表を追加した。すると以降のリンク切れはゼロになった。CLAUDE.md は「AIの失敗をプロジェクトの知識にフィードバックする装置」なんですね。

社内コンテンツを読ませる

何のインプットもなしにAIにWeb作ってって言っても、なんとなくそれっぽいのが出てくるだけなので、以前のWebサイトのコンテンツ、社内にある資料などを一通りソースとして読ませて生成してもらってます。


お問い合わせフォーム:AI で問い合わせを自動分類する

お問い合わせフォームのバックエンドです。フローはこうなってます。

フォーム送信
  → Cloudflare Turnstile 検証
  → Notion に仮保存(分類なし)
  → Claude AI が問い合わせ内容を分類(LEAD / REVIEW / SPAM)
  → Notion の分類を更新 + 確認メール送信 + Asana タスク作成 + Salesforce リード登録
  → Slack に通知(修正ボタン・担当者ドロップダウン付き)

Lambda 4関数構成で、お問い合わせ、資料ダウンロード、メルマガ登録、Slack フィードバックの4つを処理しています。AI の分類には Few-shot 学習を使っていて、過去の分類データを Notion から取得して Claude に渡すことで精度を上げてます。

Slack の通知には「分類修正ボタン」がついていて、AI の判定が間違っていたら人間がワンクリックで直せる。さらにドロップダウンメニューから担当者を選ぶと Asana タスクが自動でアサインされる仕組みです。

もともと Tally(外部フォームサービス)を使う想定をAmeku氏がしていましたが、シンジが Lambda (自前)に切り替えたことで Notion、Asana、Salesforce、Slack の連携を完全にコントロールできるようになりました。

ちなみに Lambda で一番ハマったのは、fire-and-forget パターンが動かない問題です。`void (async () => {...})()` で非同期処理をバックグラウンドに投げるやつ。Lambda は handler が return した瞬間に実行環境をフリーズさせるので、await していない Promise は実行されない。全部 `Promise.allSettled` で並列化して `await` してから返す設計にしてます。Lambda を使ったことがある人なら分かると思いますが、これは知らないと確実にハマるやつです。

↑って AI が書いてますが何言ってんのかさっぱり分かりません。

この問い合わせ機能、スパム判定されたら社内に連絡すら来ないので、だいぶストレスフリーです。この機能自体は前のWebの時から入れていて、過去数年の問い合わせ傾向を学習させてあります。


パフォーマンス改善の詳細

フォント CSS 分離:これが一番効いた

`@fontsource` でフォントをセルフホストしているんですが、普通に import すると @font-face 宣言が616ルール、778KB 分メインの CSS にバンドルされます。これがレンダリングブロックの主犯でした。

解決策として、フォント CSS を `?url` インポートで別ファイルに分離して、`media="print" onload="this.media='all'"` というパターンで非同期読み込みに変更しました。これは古典的なテクニックなんですが、効果は絶大です。クリティカルなフォント(IBM Plex Sans JP の 500/600 ウェイトと Noto Sans JP)だけ `<link rel="preload">` で優先取得する構成にしてます。

結果、メイン CSS が 1MB から 225KB に縮小。PSI Performance スコアが 64 から 85 に回復しました。

ちなみに「CSS をインライン化すればもっと速くなるのでは」と思って試したら、逆にスコアが悪化したので即 revert してます。パフォーマンス改善は理論通りにいかないことがあるので、必ず計測してから判断すべきです。

画像の最適化

画像は全て WebP に統一して、PNG と JPG は全廃しました。AI 生成画像はデフォルトのファイルサイズがやたらデカいので、`cwebp -q 85` での圧縮は必須です。

`loading="lazy"` と `decoding="async"` をベースにして、ファーストビューの画像だけ `loading="eager"` と `fetchpriority="high"` を指定。全ての `<img>` に `width` と `height` 属性を入れて CLS を防止してます。地味だけど、これをやらないと Lighthouse に怒られ続けるわけです。

キャッシュ戦略

Astro がビルド時に生成する CSS/JS/フォントはファイル名にコンテンツハッシュが入るので、`max-age=31536000, immutable`(1年キャッシュ)で問題ない。画像は `max-age=86400`(1日)、HTML は `no-cache`。Amplify のカスタムヘッダー設定でパターン別に制御してます。


セキュリティ:CSP との終わりなき戦い

Amplify のカスタムヘッダーで8種のセキュリティヘッダーを全ページに適用しています。Strict-Transport-Security(preload 付き HSTS)、Content-Security-Policy、X-Content-Type-Options、X-Frame-Options、Referrer-Policy、Permissions-Policy、Cross-Origin-Opener-Policy、Cross-Origin-Resource-Policy。

CSP が一番厄介でした。GTM を入れると GTM が読み込むスクリプトのドメインを全部 CSP に追加しないといけない。Clarity を入れれば `scripts.clarity.ms` と `c.bing.com`(トラッキングピクセル)を追加。Google Maps の iframe を埋め込めば `maps.google.com` だけでなくリダイレクト先の `www.google.com` も `frame-src` に追加。Google Ads のコンバージョンタグが動けば `pagead2.googlesyndication.com` を追加。

結局、CSP の更新ルールを CLAUDE.md に書いて、「新しい外部サービスを追加したら CSP も更新しろ」と AI に指示する運用に落ち着きました。これなら外部サービスを追加するたびに人間が CSP を手動で直す必要がない。


総稼働時間

git のコミット日時から逆算した実稼働の記録です。当然、Web以外の仕事もしてるので、日程は細切れです。

  • 12/18〜12/26(4日間):初期実装、コンポーネント設計
  • 1/6〜1/12(3日間):レスポンシブ対応、構造化
  • 2/5〜2/6(2日間):インフラセットアップ、デプロイ、コンテンツ生成開始
  • 2/10(1日):ニュース、イベント、導入事例
  • 2/17〜2/21(5日間):デザイン統合、フォーム実装、画像生成
  • 2/24〜2/28(5日間):SEO、セキュリティ、パフォーマンス改善

実稼働日数は約20日。2.5ヶ月のカレンダー期間のうち、実際にコミットがあった日は18日です。

138ページ、コンポーネント63個、Lambda 4関数、画像2,098枚を含むフルリニューアルの工数として、どうですか。工数少ないですよね。

Claude Code のコミットが157件で全体の99%という数字を見ると、AI が実作業の大部分を担ったことがはっきり分かります。ただし「AI がやった」のではなく、「AI にやらせるための設計を人間がやった」のが正確な表現です。CLAUDE.md の539行と、プロンプト体系の17,047行。この「仕込み」がなければ、AI はただのランダムなコード生成機にしかならなかったはずです。


Studio をFreeプランにして何が変わったか

Figma で作ったデザインを Studio に食わせると、一応コードが出てくる。でもそのコードがいまいち。意味不明なクラス名、冗長な構造、といってもこれは Studio に限った話ではなく、ノーコードでWebサイト作らせるサービスは大体こんな感じなので諦めポイントでもあります。

当然ですが、Studio の UI も独特で、覚えないと何もできない。この学習コストが曲者で、学んだとしてもその知識は Studio でしか使えない。汎用性ゼロのスキルに投資しているという状態です。俺は Studio の使い方なんて覚えたくないのでござる。

要するに、Studio を使っている間は「コードを書かない代わりに、Studio の制約と戦う」という別の労力が発生していたわけです。

兎にも角にも、Studioで生成したWebサイトは重すぎる。

読み込みにかかる時間が長すぎるんじゃー。今はどうなったか。Figma のデザインを人間が Astro コンポーネントに変換して、中身のコンテンツは Claude Code が生成する。Astro は広く使われているフレームワークなので学んだ知識は他でも使える。静的ホスティングだけで動くのでインフラコストは最小限。設計の自由度は100%。

Webサイトが軽量になった上に、自然言語でWeb更新できるようになってすんごく便利になったぜーーー。
「新しい事例記事できたから追加しといて」こんな感じよ。最高だぜ。


まとめ

プロンプト体系は事前に設計。 9種類のページプロンプトを用意したことで、138ページのコンテンツ品質が標準化された。「いい感じに書いて」では品質はバラつく。AI にもスタイルガイドが必要なわけです。でもこれもAIが作ったんですけどね。

ローコードツールと AI コーディングは競合する。 AI がコードを書ける時代に、「コードを書かずに済む」というバリューは薄れました。しかもローコードツールは独自の制約を持ち込む。AI は制約を持ち込まない。この差はデカい。

少人数で会社公式サイトは作れる。 ただし AI を「チームメンバー」として運用する設計が必要です。AIが全部やるは正しい表現ですが、人間がアーキテクト兼プロダクトマネージャーとして100%ディレクションしているというのが実体です。

細かい修正はこれから手でやる。いまいちなデザインの画像とかは手動で作り直して置き換えたり。細かい修正はちまちまやっていきます。

Claude Code の全てに言えることですが、出してきたものを人間がテストして問題点をAIにフィードバック、この繰り返しを何度もひたすらやることです。

こうして社内からSaaSがひとつ消えましたとさ

https://cloudnative.co.jp/

3/1 23時追記

おかしん氏に言われた PageSpeed Insights API を使ってAIに5サイクルくらいやって早くしてって言ったら爆速サイトになりましたとさ

この記事をシェア