wandfuldays

Jamstack ブログの作り方|AWS + Next.js で自作し、認証・広告・脱CMSまで実装した5本

2026-08-29

AWS + Next.js で個人ブログを自作するとき、何をどの順で決めるのか。土台・認証・広告・脱CMS の実装記事5本。

こんにちは、wandです!

このブログ「wandfuldays」は、AWS + Next.js の Jamstack 構成で自作したものです。
2025年1月に立ち上げてから、開発環境に認証をかけ、広告を載せ、
2026年8月にはヘッドレスCMSをやめて作り替えました。

この記事を読むと、個人ブログを1つ自作して運用に乗せるまでに、
何を、どの順で決めることになるのかが分かります。
実装記事5本を、土台から順にたどります。

  • ① 土台をつくる … CloudFront + S3 + Route 53 + Lambda@Edge に、Next.js の SSG を載せる
  • ②③ 開発環境に鍵をかける … Lambda@Edge と Cognito で、未公開の下書きを外から読ませない
  • ④ 収益化する … Google AdSense を、React の createPortal で本文の途中に差し込む
  • ⑤ 作り替える … ヘッドレスCMSをやめて Markdown + git へ

①〜④ は microCMS を使っていた時期に書いた記事です (②③ は CMS に依存しません)。
2026年8月に microCMS をやめているので、いまの構成とは違うところがあります。
各記事の紹介に「いまはどうなっているか」を書き添えました。

①〜③ AWS + Next.js で土台をつくり、開発環境に鍵をかける

① AWS + Next.js + microCMS で配信する

最初の1本です。静的ホスティングの構成と、その選定理由を書いています。

AWS + Next.js + microCMS で Jamstack ブログシステムを構築しましたAWS、Next.js、microCMSを活用した Jamstack ブログシステム構築の詳細2025-01-04

配信は CloudFront + S3、ドメインは Route 53、TLS 証明書は ACM
CloudFront には Lambda@Edge を2本置いています。

  • Origin Request: URL を正規化する。①当時は末尾に index.html を付けるだけでしたが、
    いまは末尾スラッシュなしの URL を /…/ へ 301 もします
  • Viewer Request: ステージング環境だけ、Cognito でアクセス制御する (→ ②)

インフラは AWS SAM で管理しています。
Terraform だと Lambda のビルドと zip 化に null_resource が要るのに対し、
SAM は TypeScript の Lambda をそのままビルド・デプロイできるからです。

フロントエンドは Next.js の SSG
microCMS の公式テンプレート
SSR 前提だったので、SSG 用に書き換えて使いました。
検索は SSR が使えないため、Algolia を検討したうえで静的サイト向けの
Pagefind を採用しています。

WAF は当初入れて、後で外しました。月額約 5 USD 〜かかるわりに、
CloudFront + S3 の静的サイトでは攻撃リスクが低く、
ステージングのアクセス制限は次の②の認証で足りていたためです。

② Lambda@Edge と Cognito で開発環境に認証をかける

このブログには本番とステージングの2環境があり、当時のステージングは
未公開記事のプレビューを兼ねていました。誰でも開ける状態だと、下書きが流出します。

Lambda@EdgeとCognitoでJamstackアプリの開発環境に認証を実装するJamstackブログの開発環境に認証を追加した方法を解説。Lambda@EdgeとCognitoを活用し、低コストでセキュリティと利便性を両立。2025-02-02

素直な手は WAF による IP 制限ですが、採りませんでした。
出先の Wi-Fi から入れず家庭用回線の IP も変わるうえ、月額約 5 USD 〜がかかり
「安全な接続元 IP」を全面的に信頼する境界型そのものが、いまの脅威に見合わないためです。

代わりに、CloudFront の viewer-request で Cognito のトークンを検査しています。
判定が入口で終わるので、未認証のリクエストは S3 にもキャッシュにも届きません
セルフサインアップは無効にし、MFA まで通したアカウントだけを入れています。

入口で検査するという形は②から替えていませんが、中身は入れ替えています。
ログインの相手は③で Google に置き換えましたし、
記事が使っている cognito-at-edge も上流ではなく自分のフォークに差し替えました
(refresh token flow で request.querystring が落ちる不具合を直したものです)。

静的配信のコスト最適化を狙った構成です。動的なバックエンドを足すなら WAF との併用を検討してください。

③ 「Google でログイン」で、その鍵を開けやすくする

②で止めると、ログインのたびにユーザー名とパスワードと MFA コードを打つことになります。
そこで Cognito と Google を OIDC で ID フェデレーションしました。

Amazon Cognito と Google 個人アカウントで「Google でログイン」を実装する方法Amazon Cognito × Google でログインを活用し、開発環境のアクセス制御を実現!設定時の落とし穴も解説。2025-03-09

手順は、Cognito と Google がお互いの設定値を要求するため3段構えになります
(Cognito の仮設定 → Google Cloud で OAuth 2.0 クライアント → Cognito の本設定)。
Google 個人アカウントでやるときの落とし穴も書きました。
認可スコープを email / profile / openid だけにすると、テストユーザー以外にも、
Google アカウントを持つ人全員にアプリが開いてしまいます
連携そのものはブログに限らず使えるので、①〜③のなかで一番つぶしが効く1本です。
Cognito と Google の設定は当時のままで、いまも記事のとおり動いています

④ 収益化する|Next.js のページ遷移と、本文中の広告

土台ができたので、AdSense を載せます。
ここで Next.js + microCMS 製のブログならではの問題が2つ出ました。

Next.js + microCMS 製ブログに Google AdSense 広告を実装する方法Next.js のページ遷移時の広告再表示と、microCMS の記事本文中への広告埋め込みについて解説します。2025-02-27

1つは、Next.js の <Link> によるページ遷移が SPA 的に動くため、
スクリプトを貼っただけでは広告が再描画されないこと。
手動広告を使い、遷移のたびにスクリプトを再実行することで解決しています。
(自動広告を正しく再描画する方法は、④の時点では見つけられていません。)

もう1つは、記事本文の途中に広告を差し込む方法です。
本文は CMS から来る HTML なので、React のコンポーネントを直接は置けません。
そこで本文中に目印の要素を作り、React の createPortal でそこへ描画しています。
当時はその目印を microCMS のリッチテキストの「カスタム class」(ad-portal) で作っていました。

いまは目印を Markdown の独自記法 (::ads) で書いています。
目印の作り方という中身は替えましたが、
createPortal で差し込むという形は同じです
この記事のここまでに2つ広告が出ていたら、それがまさにその仕組みです。

⑤ 作り替える|microCMS をやめて Markdown + git へ

1年半使った CMS をやめた理由は2つです。
1つは書く場所が管理画面から手元に移ったこと。
原稿が手元にあって公開が静的ビルドなら、CMS は経由地が1つ増えるだけです。
もう1つは無料枠の上限。記事も画像も CMS から配信していて、
Hobby プランの 20GB/月 を超えると API が止まります。

microCMSをやめてMarkdown+gitへ移行|47記事の脱CMSを安全に進めるヘッドレスCMSからMarkdownへ。配信中の本番HTMLと突き合わせ、URL・広告位置・アフィリエイトを保ったまま移行した記録です。2026-08-28

2026年8月に、47記事と画像431枚をまるごと Markdown + git に移しました。

移行でいちばん時間をかけたのは、変換ではなく確かめ方でした。
比べる相手を、CMS からダンプしたデータではなく
いま配信されている本番の HTMLにしています。

見たもの本番 (移行前)移行後
広告の差込先8585 (直前の見出し id も一致)
Amazon のユニーク URL4747
本文画像 (img 要素)411411
見出し id493欠落0

公開 URL も広告の位置もアフィリエイトリンクも、1つも変えずに切り替わりました。

よくある質問

Q. いまから真似するなら、microCMS は使わないほうがいいですか?

そうは言いません。⑤でやめたのは、入稿する人が私1人で、原稿が手元にあったからです。
書く人が複数いるなら、管理画面のある構成のほうが噛み合います。
選び方の材料は①(選定理由) と⑤(やめた理由) の両方に書いてあります。

Q. 開発環境の認証は、Jamstack でなくても使えますか?

②③は CloudFront の入口 (viewer-request) で認証する話なので、
オリジンが S3 でなくても、静的サイトでなくても成り立つはずです。
ただし私は S3 オリジンでしか試していません。

まとめ

1つのブログを立ち上げて作り替えるまでを、5本に分けて書いてきました。

記事ここで決まること
AWS + Next.js + microCMS で構築配信の形と、記事の置き場所
Lambda@Edge + Cognito で認証未公開の下書きを誰に見せるか
Cognito + 「Google でログイン」その鍵をどれだけ気軽に開けられるか
Google AdSense を実装広告をどこに、どう差し込むか
microCMS をやめて Markdown + git へ記事の置き場所を、後から替えられるか

1年半のあいだに、記事の置き場所は microCMS から git へ、ログインの相手は
Cognito のユーザーから Google へ替わりました。Lambda@Edge の中身も入れ替わっています。
配信の形も、入口で認証する形も、createPortal で広告を差し込む形も①②④のままです。
ただ、そのどれもが替えようと思えば替えられるもので、替えられないのは公開 URL だけでした。

URL は、検索エンジンにも、他所から張られたリンクにも、読者のブックマークにも残ります。
⑤で記事の置き場所を丸ごと載せ替えたときに、いちばん気を遣ったのもそこでした。

これから作るなら、①から順に読んで、まず URL の形だけ決めてしまうのがおすすめです。
CMS も認証も広告も、後から替えられます。替えにくいのは、一度外に出した URL のほうです。


wand

「wand」は魔法の杖を意味します。魔法のようにさまざまなものを自分の手で生み出せるようになりたい、そんな思いを込めました。 ハンドメイド、家庭菜園、DIY、プログラミング等、「つくる」をテーマに色々なことをしていきたいと思っています。 Amazonのアソシエイトとして、wand は適格販売により収入を得ています。 GitHub: https://github.com/wand2016