<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>個人開発日誌 on モリサキブログ</title><link>https://www.morisakiblog.com/categories/%E5%80%8B%E4%BA%BA%E9%96%8B%E7%99%BA%E6%97%A5%E8%AA%8C/</link><description>Recent content in 個人開発日誌 on モリサキブログ</description><generator>Hugo</generator><language>ja</language><lastBuildDate>Wed, 08 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.morisakiblog.com/categories/%E5%80%8B%E4%BA%BA%E9%96%8B%E7%99%BA%E6%97%A5%E8%AA%8C/index.xml" rel="self" type="application/rss+xml"/><item><title>Hugo移行後のデザイン調整地獄｜CSS1400行・Figma導入・スマホ対応の全記録</title><link>https://www.morisakiblog.com/hugo-design-customization-hell/</link><pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.morisakiblog.com/hugo-design-customization-hell/</guid><description>&lt;p&gt;前回の記事では、WordPressからHugoへの移行を2日で完了させた話を書いた。&lt;/p&gt;&#10;&lt;a href="https://www.morisakiblog.com/wordpress-to-hugo-migration-real-story/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;WordPressからHugoに移行した全記録｜90記事を2日で移行した方法と想定外の落とし穴&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;WordPressからHugoへの移行を実際にやってみた全記録。テーマ選定、デザインカスタマイズ、90記事の自動変換、画像移行、SEO対策まで。Claude Codeと二人三脚で進めた移行作業のリアルな記録です。&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;p&gt;90記事のMarkdown変換、画像ダウンロード、URL一致確認、GitHub Pagesへのデプロイ。技術的な移行作業は確かに2日で終わった。&lt;/p&gt;&#10;&lt;p&gt;だが、本当の地獄はここからだった。&lt;/p&gt;&#10;&lt;h2 id="テーマのcssカスタマイズが終わらない"&gt;テーマのCSSカスタマイズが終わらない&lt;/h2&gt;&#10;&lt;p&gt;Hugoのテーマ「Mainroad」を選んだ。シンプルで2カラム対応、ブログ向きの構成。だがデフォルトのデザインは正直そっけない。WordPress時代に使っていたCocoonの見た目に慣れていた自分にとって、「なんか違う」の連続だった。&lt;/p&gt;&#10;&lt;p&gt;色を変える。余白を調整する。カードのデザインを変える。ヘッダーを全幅にする。フッターにリンクを並べる。1つ直すと別の場所が気になる。custom.cssに1行追加するたびに、「あ、ここも直さなきゃ」が発生する。&lt;/p&gt;&#10;&lt;p&gt;最終的にcustom.cssは&lt;strong&gt;1400行を超えた&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;h3 id="テーマのclearfixが-webkit-line-clampを殺す"&gt;テーマのclearfixが-webkit-line-clampを殺す&lt;/h3&gt;&#10;&lt;p&gt;一番ハマったのがこれ。リンクカードの説明文を3行で切って三点リーダー（&amp;hellip;）を表示したかった。CSSの&lt;code&gt;-webkit-line-clamp&lt;/code&gt;を使えば簡単なはず。&lt;/p&gt;&#10;&lt;p&gt;ところが何をやっても効かない。&lt;code&gt;!important&lt;/code&gt;をつけても、セレクタの詳細度を上げても、インラインスタイルで直接指定しても。DevToolsで確認すると&lt;code&gt;display: -webkit-box&lt;/code&gt;を指定しているのに、Computed Styleでは&lt;code&gt;flow-root&lt;/code&gt;になっている。&lt;/p&gt;&#10;&lt;p&gt;原因を探るのに丸1日かかった。結論から言うと、&lt;strong&gt;Chromeが&lt;code&gt;-webkit-box&lt;/code&gt;を内部的に&lt;code&gt;flow-root&lt;/code&gt;として報告しているだけで、実は動いていた&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;DevToolsのConsoleで新しいdiv要素を作って&lt;code&gt;display: -webkit-box&lt;/code&gt;を設定し、&lt;code&gt;getComputedStyle&lt;/code&gt;で確認しても&lt;code&gt;flow-root&lt;/code&gt;が返ってくる。clearfixとは無関係だった。&lt;/p&gt;&#10;&lt;p&gt;つまり「動いてないと思い込んで別の方法（max-height）に変えた」のが間違いで、最初から動いていた。CSSデバッグの教訓：&lt;strong&gt;推測でCSSを書くと沼る。DevToolsで実測値を見てからピンポイントで直す&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;h3 id="テーマを使う意味とは何か"&gt;テーマを使う意味とは何か&lt;/h3&gt;&#10;&lt;p&gt;custom.cssが1400行。テンプレートの上書きファイルも10個以上。ここまでカスタマイズすると「テーマ使ってる意味ある？」という疑問が湧く。&lt;/p&gt;&#10;&lt;p&gt;結論としては、まだある。テーマが担ってくれている部分:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;カテゴリ・タグ一覧ページの生成&lt;/li&gt;&#10;&lt;li&gt;ページネーション&lt;/li&gt;&#10;&lt;li&gt;ハンバーガーメニューのJS&lt;/li&gt;&#10;&lt;li&gt;OGP・meta周りのテンプレート&lt;/li&gt;&#10;&lt;li&gt;レスポンシブの基本設計&lt;/li&gt;&#10;&lt;li&gt;CSSのベーススタイル（フォント、テーブル、コードブロック等）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;これを全部自分で書くとなると相当な量になる。テーマの価値は「HTML構造とJSの土台を自分で書かなくていい」こと。見た目はCSSでいくらでも変えられる。&lt;/p&gt;&#10;&lt;h2 id="figma導入でなんとなくcss調整から脱却"&gt;Figma導入で「なんとなくCSS調整」から脱却&lt;/h2&gt;&#10;&lt;p&gt;CSSが終わらない根本原因に気づいた。&lt;strong&gt;デザインのゴールがない&lt;/strong&gt;のだ。&lt;/p&gt;&#10;&lt;p&gt;「なんか違う」→「ここを直そう」→「あ、こっちも気になる」の無限ループ。ゴールがないからいつまでも終わらない。&lt;/p&gt;&#10;&lt;p&gt;そこでFigmaを導入した。PC・タブレット・スマホの3ブレイクポイントで完成形のデザインを先に作る。コンポーネント化してバリアント（device=PC/Mobile）で管理する。テキストスタイルでフォントサイズを一元管理する。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Figmaで決めてからCSSに落とす&lt;/strong&gt;。この流れに変えたら、CSSの調整が驚くほど速くなった。「この要素は何px？」が明確だから迷わない。&lt;/p&gt;&#10;&lt;h3 id="figmaもclaude-codeに作らせた"&gt;FigmaもClaude Codeに作らせた&lt;/h3&gt;&#10;&lt;p&gt;「わざわざブログのデザインにFigmaを使うのか」と思われそうだが、&lt;strong&gt;自分でFigmaをポチポチ操作したわけではない&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;FigmaのMCPが編集に対応したので、Claude Codeに元サイトのURLを渡して「このデザインをFigmaに起こして」と指示した。各レスポンシブのページデザインが自動で生成される。そこからプロンプトで「ここの余白を24pxに」「この文字を15pxに」と微調整を繰り返した。&lt;/p&gt;&#10;&lt;p&gt;コンポーネント化、バリアント作成、テキストスタイル登録もClaude Code経由。Figmaの操作を覚える必要がなかった。&lt;/p&gt;&#10;&lt;p&gt;Figmaの達人でも何でもない。&lt;strong&gt;Claude Codeが達人&lt;/strong&gt;なだけだ。&lt;/p&gt;&#10;&lt;h3 id="figmaデザインファイルを公開します"&gt;Figmaデザインファイルを公開します&lt;/h3&gt;&#10;&lt;p&gt;今回作ったFigmaのデザインファイルを公開する。Hugo + Mainroadテーマのカスタマイズを考えている人の参考になれば。&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.figma.com/design/B1q2U6D8EkuW9d3ZxZW4Xp/%E3%83%A2%E3%83%AA%E3%82%B5%E3%82%AD%E3%83%96%E3%83%AD%E3%82%B0"&gt;Figmaデザインファイルはこちら&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="スマホ表示の改善が一番効果があった"&gt;スマホ表示の改善が一番効果があった&lt;/h2&gt;&#10;&lt;p&gt;デザイン調整の中で、最もインパクトが大きかったのがスマホ表示の改善だ。&lt;/p&gt;&#10;&lt;h3 id="横並びカード--縦型カードで劇的に見やすく"&gt;横並びカード → 縦型カードで劇的に見やすく&lt;/h3&gt;&#10;&lt;p&gt;最初のスマホ表示は、PCと同じ横並びカード（アイキャッチ左・テキスト右）を縮小しただけだった。85×48pxの小さいサムネイルに、11pxの文字。読めなくはないが、何の記事かパッと見でわかりにくい。&lt;/p&gt;&#10;&lt;p&gt;Figmaでスマホ専用の縦型カードをデザインした。アイキャッチ画像が上部に大きく表示され、その下にタイトル。これだけで印象が全然違う。&lt;/p&gt;&#10;&lt;h3 id="文字サイズ13px--15pxで読みやすさが激変"&gt;文字サイズ13px → 15pxで読みやすさが激変&lt;/h3&gt;&#10;&lt;p&gt;最初はFigmaのデザインに忠実に13pxにしていた。だが実機で見ると小さすぎる。h2が16px、h3が14pxだと本文との差がほとんどない。&lt;/p&gt;&#10;&lt;p&gt;最終的にh3と本文を同じ15pxにした。見出しは装飾（背景色や左ボーダー）で十分区別できるので、サイズで差をつける必要がなかった。たった2pxの違いだが、スマホでの読みやすさが劇的に変わった。&lt;/p&gt;&#10;&lt;h3 id="ハンバーガーメニューをヘッダー画像にオーバーレイ"&gt;ハンバーガーメニューをヘッダー画像にオーバーレイ&lt;/h3&gt;&#10;&lt;p&gt;最初はカテゴリメニューをスマホでもそのまま折り返し表示していた。5カテゴリ程度なら収まるが、ヘッダーの下に別のバーとして領域を取るのがスマートじゃない。&lt;/p&gt;&#10;&lt;p&gt;Figmaでデザインした通り、ハンバーガーメニューをヘッダー画像の右上にオーバーレイ配置した。HTMLの構造上、メニューはヘッダー画像の外にあったので、&lt;code&gt;header-wrapper&lt;/code&gt;で包んで&lt;code&gt;position: absolute&lt;/code&gt;で重ねる形にした。&lt;/p&gt;&#10;&lt;h3 id="前後ナビをスマホでは非表示に"&gt;前後ナビをスマホでは非表示に&lt;/h3&gt;&#10;&lt;p&gt;「前の投稿」「次の投稿」のナビゲーション。一般的にクリック率は1-3%と言われている。PCなら記事の最下部にあっても邪魔にならないが、スマホだとサイドバーの前に挟まって導線が切れる。関連記事があれば十分なので、タブレット・スマホでは非表示にした。&lt;/p&gt;&#10;&lt;h2 id="ロゴ画像をテキストsvgフィルターに置き換えた"&gt;ロゴ画像をテキスト+SVGフィルターに置き換えた&lt;/h2&gt;&#10;&lt;p&gt;ヘッダーのブログ名は、以前はネットのロゴ作成サイトで作った画像を使っていた。だが画像だとサイズ変更のたびに作り直しが必要で、レスポンシブ対応が面倒。&lt;/p&gt;&#10;&lt;p&gt;テキスト+CSSで再現できないか試した。&lt;/p&gt;&#10;&lt;h3 id="cssのtext-shadowでは角がきれいに縁取りできない"&gt;CSSのtext-shadowでは角がきれいに縁取りできない&lt;/h3&gt;&#10;&lt;p&gt;最初は&lt;code&gt;text-shadow&lt;/code&gt;で4方向に影を重ねて縁取りを再現しようとした。だが文字の角や曲線部分に隙間ができる。&lt;code&gt;-webkit-text-stroke&lt;/code&gt;は文字の内側にも線が入るので白が痩せる。&lt;/p&gt;</description></item><item><title>WordPressからHugoに移行した全記録｜90記事を2日で移行した方法と想定外の落とし穴</title><link>https://www.morisakiblog.com/wordpress-to-hugo-migration-real-story/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://www.morisakiblog.com/wordpress-to-hugo-migration-real-story/</guid><description>&lt;p&gt;この記事は以下の記事の続編です。前回はWordPressでの運用の限界と、次の技術スタックとしてHugoを選んだ経緯を書きました。今回はその&lt;strong&gt;実際の移行作業&lt;/strong&gt;の全記録です。&lt;/p&gt;&#10;&lt;a href="https://www.morisakiblog.com/claude-code-wordpress-limitation-hugo/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;img src="https://img.morisakiblog.com/posts/claude-code-wordpress-limitation-hugo/featured-image-1845-78aebc02b460a0afd3d460241b63a9eb.png" alt="Claude CodeでWordPressブログを運用してわかった限界と、次に選ぶ技術スタック" loading="lazy"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;Claude CodeでWordPressブログを運用してわかった限界と、次に選ぶ技術スタック&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;このブログはWordPressで運営しています。そしてここ数週間、Claude Code（Anthropicが提供するAIコーディングツール）を使って、記事の作成・編集・SEO設定・品質監査まで、ブログ運用のほぼ全てをAIと一緒にやってきま...&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;h2 id="なぜwordpressをやめたのか"&gt;なぜWordPressをやめたのか&lt;/h2&gt;&#10;&lt;p&gt;結論から言うと、&lt;strong&gt;WordPressの管理画面を一切開かなくなった&lt;/strong&gt;からだ。&lt;/p&gt;&#10;&lt;p&gt;Claude Codeで記事を書き、REST APIで投稿し、SEO設定もAPIで済ませる。管理画面にログインする理由がない。なのにWordPressは毎月サーバー代を請求してくる。プラグインの更新通知が来る。セキュリティパッチを当てろと言ってくる。&lt;/p&gt;&#10;&lt;p&gt;使わない管理画面のために、管理コストだけ払っている状態。これが移行を決めた最大の理由だ。&lt;/p&gt;&#10;&lt;h2 id="テーマ選び4つ試して全部微妙だった話"&gt;テーマ選び：4つ試して全部微妙だった話&lt;/h2&gt;&#10;&lt;p&gt;Hugoのテーマ選びは正直かなり苦労した。WordPressのCocoonが「インストールしたらそのまま使える」レベルだったのに対して、Hugoのテーマは&lt;strong&gt;「カスタマイズのベースにするもの」&lt;/strong&gt;という思想の違いがある。&lt;/p&gt;&#10;&lt;p&gt;実際に試したテーマ:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Stack&lt;/strong&gt; — 左サイドバーのモダンなデザイン。悪くないが、サイドバーがスマホで完全に消える仕様がCocoonと違いすぎた&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Blowfish&lt;/strong&gt; — 評判が良かったが、サイドバーがそもそもない。1カラムのミニマルデザインで、ブログとしてはちょっと物足りない&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Congo&lt;/strong&gt; — インストールしかけたが、Blowfishと似た方向性だったので途中でやめた&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Mainroad&lt;/strong&gt; — 最終的にこれに落ち着いた。Cocoonに近い2カラム構成で、サイドバーがスマホで下に回る伝統的なブログレイアウト&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;結局「モダンなデザイン」と「ブログとしての使いやすさ」は別物だった。見た目がおしゃれでも、読者が記事を読む導線が悪ければ意味がない。&lt;/p&gt;&#10;&lt;h2 id="cssカスタマイズここが一番時間かかった"&gt;CSSカスタマイズ：ここが一番時間かかった&lt;/h2&gt;&#10;&lt;p&gt;テーマを選んだ後が本番だった。Mainroadのデフォルトデザインからcocoonの見た目に近づけるために、&lt;strong&gt;custom.cssが1100行を超えた&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;やったこと:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ヘッダー画像の全幅表示&lt;/li&gt;&#10;&lt;li&gt;ナビバーのデザイン変更（紺背景→白背景+ホバーエフェクト）&lt;/li&gt;&#10;&lt;li&gt;記事カードのレイアウト（アイキャッチ+タイトル+説明文+メタ情報）&lt;/li&gt;&#10;&lt;li&gt;サイドバーのウィジェットデザイン&lt;/li&gt;&#10;&lt;li&gt;テーブルのスタイリング（Cocoon準拠の縞模様）&lt;/li&gt;&#10;&lt;li&gt;ページネーションの丸ボタン化&lt;/li&gt;&#10;&lt;li&gt;目次のデザイン&lt;/li&gt;&#10;&lt;li&gt;h2/h3の見出しスタイル&lt;/li&gt;&#10;&lt;li&gt;レスポンシブ対応&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;一つ一つは大した作業じゃないが、&lt;strong&gt;「ちょっと違う」の積み重ねが膨大&lt;/strong&gt;だった。色が微妙に違う、余白が多い、ホバーが効かない、スマホで崩れる。毎回CSSを書いて、リロードして、「あ、ここも直さなきゃ」の繰り返し。&lt;/p&gt;&#10;&lt;p&gt;ただ、Hugoの良いところは&lt;strong&gt;テーマのファイルを直接いじらない&lt;/strong&gt;こと。&lt;code&gt;layouts/&lt;/code&gt; に同名ファイルを置けば上書きされるし、CSSも &lt;code&gt;custom.css&lt;/code&gt; で追記するだけ。テーマのアップデートに影響されない設計は素直に良いと思った。&lt;/p&gt;&#10;&lt;h2 id="90記事の移行スクリプト一発とはいかなかった"&gt;90記事の移行：スクリプト一発…とはいかなかった&lt;/h2&gt;&#10;&lt;p&gt;WordPress REST APIから全記事を取得して、HTMLをMarkdownに変換するスクリプトを書いた。これ自体は30分で完成。実行も1分で90記事が変換された。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;問題はここからだった。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h3 id="cocoonのseoメタデータが取れない"&gt;CocoonのSEOメタデータが取れない&lt;/h3&gt;&#10;&lt;p&gt;CocoonのSEOタイトルとメタディスクリプションは、REST APIのmetaフィールドに露出しない。Cocoon独自のカスタムフィールドで、UIの &lt;code&gt;$_POST&lt;/code&gt; 経由でしか保存されない設計だった。&lt;/p&gt;&#10;&lt;p&gt;結局、全90ページをスクレイピングしてHTMLの &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; タグと &lt;code&gt;og:description&lt;/code&gt; から取得した。REST APIがあるのにスクレイピングするという本末転倒な解決策。&lt;/p&gt;&#10;&lt;h3 id="テーブルが全滅"&gt;テーブルが全滅&lt;/h3&gt;&#10;&lt;p&gt;WordPressのHTMLテーブルをMarkdownに変換する際、ヘッダー行の区切り（&lt;code&gt;| --- | --- |&lt;/code&gt;）が正しく生成されないケースが大量に発生。28記事のテーブルが壊れていた。&lt;/p&gt;&#10;&lt;p&gt;Markdownのテーブルは厳密で、ヘッダーの次の行に必ず &lt;code&gt;---&lt;/code&gt; が必要。HTMLからの自動変換では列数の検出やネストの処理が不完全で、手動修正が必要だった。&lt;/p&gt;&#10;&lt;h3 id="dalleファイル名のエンコーディング問題"&gt;DALL·Eファイル名のエンコーディング問題&lt;/h3&gt;&#10;&lt;p&gt;WordPressの画像ファイル名に &lt;code&gt;DALL·E&lt;/code&gt; の中黒（&lt;code&gt;·&lt;/code&gt;）が含まれているものが10件あり、Pythonの &lt;code&gt;urllib&lt;/code&gt; がASCIIエンコードエラーで落ちた。URLエンコーディングを正しく処理するように修正して解決。&lt;/p&gt;</description></item><item><title>気力ゼロから1ヶ月でApp Storeリリース｜AI×個人開発の全記録</title><link>https://www.morisakiblog.com/ai-indie-dev-appstore-1month-full-record/</link><pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate><guid>https://www.morisakiblog.com/ai-indie-dev-appstore-1month-full-record/</guid><description>&lt;p&gt;「個人開発やりたい。でも気力がない。」&lt;/p&gt;&#10;&lt;p&gt;これが正直な出発点だった。フリーランスエンジニアとして働く中で、会社の非効率なやり方、無駄な会議、気まぐれな要件変更、聞こえの良いだけのビジョンを掲げて、中身のない退屈な仕事。そういうものに飽きていた。もっと自分で責任を取って、自分で考えて、収益に天井がない代わりにリスクも大きい仕事がしたかった。&lt;/p&gt;&#10;&lt;p&gt;でも、いざ自分でアプリを作ろうとすると、やることが多すぎる。コーディングだけじゃない。デザイン、要件定義、インフラ構築、バックエンド実装。一つずつやれば形にできる自信はあったけど、&lt;strong&gt;それをやる気力がなかった&lt;/strong&gt;。大きなことを言うくせに何もしない人間になりかけていた。&lt;/p&gt;&#10;&lt;p&gt;そんな時にAIが来た。Claude Code、Figma Make、Notion MCP。コーディングは一瞬で終わるし、自分で書くより速い。インフラやバックエンドの知識もAIに聞けばすぐ分かる。&lt;strong&gt;これなら気力のない自分でも、個人開発ができるかもしれない。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;同時に懸念もあった。AIで簡単に作れるなら、他の人間も同じことができる。差別化できるのか？正直、AI開発はもう先行者たちが市場を取っていて、今から始めても手遅れだと思っていた。でもSNSを見ると、AIに対する文句記事がバズっている現状があった。「AIが書いたコードのレビューが大変」「リファクタリングさせられて迷惑」。こういう記事がバズるということは、&lt;strong&gt;まだまだAIに対する偏見や誤解が多い&lt;/strong&gt;。今のうちに使いこなす側に回れば、&lt;strong&gt;先行者利益はまだ十分取れる&lt;/strong&gt;。やるなら今しかないと思った。&lt;/p&gt;&#10;&lt;p&gt;この記事では、AIをフル活用して約1ヶ月でクイズSNSアプリ「QuizBuzz」をApp Storeにリリースするまでの全工程を振り返る。各フェーズの詳細は別記事で深掘りする予定なので、ここでは全体像と、理想と現実のギャップを正直に書く。&lt;/p&gt;&#10;&lt;h2 id="なぜクイズsnsアプリなのか"&gt;なぜクイズSNSアプリなのか&lt;/h2&gt;&#10;&lt;p&gt;正直に言うと、大した理由はない。&lt;/p&gt;&#10;&lt;p&gt;以前Firebaseで作ったAndroidのクイズアプリがあったが、放置していたらストアからリジェクトされていた。じゃあそれをベースにAWSに載せ替えて、Figma Makeでデザインをちゃんと作り直せばいいだろう、という軽い動機だ。&lt;/p&gt;&#10;&lt;p&gt;俺にとって重要だったのは&lt;strong&gt;「何を作るか」ではなく「AIでどう作るか」&lt;/strong&gt;だった。将来的には複数プロダクトをAIで回す予定で、そうしないと周りもAIで開発している以上、差別化できない。だからまず&lt;strong&gt;AIで開発を進めること自体に慣れる&lt;/strong&gt;必要があった。アイデアにこだわるより、開発プロセスの確立が先だった。&lt;/p&gt;&#10;&lt;h2 id="技術選定全部aiとの相性で決めた"&gt;技術選定：全部AIとの相性で決めた&lt;/h2&gt;&#10;&lt;h3 id="バックエンドfirebase--aws"&gt;バックエンド：Firebase → AWS&lt;/h3&gt;&#10;&lt;p&gt;元々Firebase + Algoliaで開発していたが、インフラ管理が手動寄りで面倒だった。AWSならCDK（Cloud Development Kit）で完全にコード管理できるし、どうせAIが書くならコードベースの方がAIとの親和性が高い。詳しい経緯は以前の記事で書いている。&lt;/p&gt;&#10;&lt;a href="https://www.morisakiblog.com/firebase-algolia-to-aws-migration/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;img src="https://img.morisakiblog.com/posts/firebase-algolia-to-aws-migration/7137fa46-8cf2-4d9b-b1a1-d1678766662f.jpg" alt="Firebase &amp;#43; Algoliaの限界：個人開発でAWS移行した2理由と体験談" loading="lazy"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;Firebase &amp;#43; Algoliaの限界：個人開発でAWS移行した2理由と体験談&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;Firebase &amp;#43; Algoliaの限界を実体験で解説！複雑検索の制約と運用コスト増でAWS RDS移行した2理由。個人開発の適材適所とハマりポイントも。&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;p&gt;ちなみにAWSに移行したらしたで地獄があった。&lt;/p&gt;&#10;&lt;a href="https://www.morisakiblog.com/dynamodb-gsi-trap-firebase-aws-migration-reality/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;img src="https://img.morisakiblog.com/posts/dynamodb-gsi-trap-firebase-aws-migration-reality/featured-image-1853-5b2a52ac3e335566a7f52b86acc98db3.png" alt="DynamoDBは地雷原だった｜Firebase→AWS移行の理想と現実" loading="lazy"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;DynamoDBは地雷原だった｜Firebase→AWS移行の理想と現実&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;Firebase→AWS移行でDynamoDBを選んだ個人開発者の体験談。GSI変更は1回1デプロイ制約で10回デプロイ、FilterExpressionはlimit後に動く罠、シングルテーブル設計の落とし穴を正直に書きます。&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;h3 id="フロントエンドflutter"&gt;フロントエンド：Flutter&lt;/h3&gt;&#10;&lt;p&gt;元のAndroidアプリがFlutterで開発されていて、クリーンアーキテクチャを採用していた。設計原則をAIに説明すればいい感じにコーディングしてくれそうだった。元モバイルエンジニアとして、Flutter自体の知識はあるから、AIとの協業がしやすいと判断した。&lt;/p&gt;&#10;&lt;h3 id="デザインfigma-make"&gt;デザイン：Figma Make&lt;/h3&gt;&#10;&lt;p&gt;デザインはそれなりに勉強したし、Figmaの使い方もある程度は分かる。でも頑張る気力が続かなかった。Figma MakeでAIがデザインを生成してくれると知って試したら、いい感じだった。デザインは完全にAIに任せようと決めた。&lt;/p&gt;&#10;&lt;h3 id="使ったaiツール一覧"&gt;使ったAIツール一覧&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Grok&lt;/strong&gt;：最初の壁打ち。寝転がってスマホでアイデアを話しながら要件を詰めた&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Claude（チャット）&lt;/strong&gt;：Grokとの会話をまとめて要件定義書に整理&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Notion MCP&lt;/strong&gt;：Claude Codeから直接Notionに要件定義書を書かせた&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Figma Make&lt;/strong&gt;：UIデザインの生成&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Claude Code&lt;/strong&gt;：CDK実装、Flutter実装、テスト、CI構築&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="各フェーズの所要時間と感想"&gt;各フェーズの所要時間と感想&lt;/h2&gt;&#10;&lt;h3 id="phase-1要件定義ai壁打ち--notion-約12時間"&gt;Phase 1：要件定義（AI壁打ち × Notion）— 約1〜2時間&lt;/h3&gt;&#10;&lt;p&gt;正直、最初は「作る」と思っていなかった。寝転がりながらGrokに「こんなアプリ作ろうと思ってるんだけど」と話しかけて、遊びで要件を詰めていった。&lt;/p&gt;&#10;&lt;p&gt;でもこの「遊び」が想像以上に生産的だった。DBの設計をどうするか、AWSの認証はCognitoでいいのか、バックエンドはAppSyncかLambdaか、テーブル構造は、Web APIのリクエスト・レスポンスの形は、各機能のUIを文章にするとどうなるか。めちゃくちゃGrokと話し合った。&lt;/p&gt;&#10;&lt;p&gt;ある程度固まったらClaudeにGrokとの会話を渡してまとめさせ、Notion MCPで直接Notionに要件定義書を書かせた。最初はClaudeのチャットで管理していたが、「間違って削除したら怖いな」と思ってNotionに移行した。&lt;/p&gt;&#10;&lt;p&gt;結果、ざっくりとした全体の仕様は&lt;strong&gt;1〜2時間&lt;/strong&gt;で固まった。細かい仕様はデザインやCDKの実装中に不備に気づくたびにアップデートしていった。&lt;/p&gt;&#10;&lt;h3 id="phase-2デザインfigma-make-生成23時間沼34日"&gt;Phase 2：デザイン（Figma Make）— 生成2〜3時間、沼3〜4日&lt;/h3&gt;&#10;&lt;p&gt;Figma Makeに要件定義書の各機能の説明文を貼り付けて、「Material Design 3で作って」と指示。ホーム画面から順にガンガン生成させた。ダークモードも対応させた。&lt;/p&gt;</description></item><item><title>DynamoDBは地雷原だった｜Firebase→AWS移行の理想と現実</title><link>https://www.morisakiblog.com/dynamodb-gsi-trap-firebase-aws-migration-reality/</link><pubDate>Fri, 20 Mar 2026 00:00:00 +0000</pubDate><guid>https://www.morisakiblog.com/dynamodb-gsi-trap-firebase-aws-migration-reality/</guid><description>&lt;p&gt;以前、こんな記事を書きました。&lt;/p&gt;&#10;&lt;a href="https://www.morisakiblog.com/firebase-algolia-to-aws-migration/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;img src="https://img.morisakiblog.com/posts/firebase-algolia-to-aws-migration/7137fa46-8cf2-4d9b-b1a1-d1678766662f.jpg" alt="Firebase &amp;#43; Algoliaの限界：個人開発でAWS移行した2理由と体験談" loading="lazy"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;Firebase &amp;#43; Algoliaの限界：個人開発でAWS移行した2理由と体験談&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;Firebase &amp;#43; Algoliaの限界を実体験で解説！複雑検索の制約と運用コスト増でAWS RDS移行した2理由。個人開発の適材適所とハマりポイントも。&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;p&gt;「Firebase + Algoliaは限界！AWSに移行すればCDKでインフラをコード管理できて快適！」と意気揚々と書いた人間です。&lt;/p&gt;&#10;&lt;p&gt;あれから実際にAWS（DynamoDB + CDK + AppSync）でクイズSNSアプリのバックエンドを開発してきました。その結果どうなったか。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;DynamoDBは地雷原でした。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;今回は、DynamoDBのシングルテーブル設計で実際にハマった罠と、「正直Firebaseで良かったんじゃないか」という気持ちが再浮上してきた話を正直に書きます。&lt;/p&gt;&#10;&lt;h2 id="nosqlはポストrdbだと思っていた"&gt;NoSQLは「ポストRDB」だと思っていた&lt;/h2&gt;&#10;&lt;p&gt;DynamoDBを選んだ時、僕はNoSQLをこう理解していました。&lt;/p&gt;&#10;&lt;p&gt;「RDBは堅牢だけど堅い。NoSQLはその堅牢さを柔軟性で和らげた、進化系のデータベースだ」と。&lt;/p&gt;&#10;&lt;p&gt;完全に間違っていました。&lt;/p&gt;&#10;&lt;p&gt;DynamoDBは確かに柔軟です。スキーマレスで、とりあえずデータを突っ込める。でも&lt;strong&gt;「開発しやすい土壌」がない&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;ここで言う土壌とは、テーブル結合（JOIN）、複合クエリ、「WHEREで絞ってからLIMITする」みたいな当たり前の動作のことです。RDBなら何も考えずにできることが、DynamoDBでは「そもそもできない」か「やり方を根本から変える必要がある」。&lt;/p&gt;&#10;&lt;p&gt;RDBは厳しいけどレールがある。DynamoDBは自由だけど荒野。自由って聞こえはいいけど、道がないだけでした。&lt;/p&gt;&#10;&lt;h2 id="dynamodb-gsi変更の地獄"&gt;DynamoDB GSI変更の地獄&lt;/h2&gt;&#10;&lt;p&gt;前の記事で「CDKでインデックスをコード管理できる！Firestoreみたいにコンソールで手動作成しなくていい！」って書きました。&lt;/p&gt;&#10;&lt;p&gt;それは事実です。コードで管理できます。&lt;strong&gt;ただし、デプロイが地獄です。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h3 id="1回のデプロイでgsi変更は1つだけ制約"&gt;「1回のデプロイでGSI変更は1つだけ」制約&lt;/h3&gt;&#10;&lt;p&gt;DynamoDBには「1回のUpdateTableでGSIの追加・削除は1つだけ」というサービスレベルの制約があります。追加1つと削除1つを同時にやることすらできません。&lt;/p&gt;&#10;&lt;p&gt;つまり、GSIを1つ作り替えるだけでこうなります。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;新GSIを追加してデプロイ（1回目）&lt;/li&gt;&#10;&lt;li&gt;アプリ側のクエリを新GSIに切り替えてデプロイ&lt;/li&gt;&#10;&lt;li&gt;旧GSIを削除してデプロイ（2回目）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;不要なGSIを3つ消したい時は？3回に分けてデプロイです。&lt;/p&gt;&#10;&lt;p&gt;実際に僕がやらかしたのは、PRを2つ同時にマージしてデプロイ失敗。コンフリクト解消のミスで削除したはずのGSIが復活。dev環境とprod環境でGSIの状態がズレる。結局、&lt;strong&gt;合計約10回のデプロイ&lt;/strong&gt;を実行して復旧しました。&lt;/p&gt;&#10;&lt;h3 id="対策ciでgsi変更数をブロックする"&gt;対策：CIでGSI変更数をブロックする&lt;/h3&gt;&#10;&lt;p&gt;この経験から、GitHub Actionsで&lt;code&gt;cdk diff&lt;/code&gt;を実行して、GSIの追加・削除が2つ以上含まれていたらマージをブロックするCIの導入を予定しています。dev環境はローカルから&lt;code&gt;cdk deploy&lt;/code&gt;で復旧できるからまだいいけど、prod環境で同じ事故が起きたら目も当てられません。&lt;/p&gt;&#10;&lt;p&gt;DynamoDBを使うなら、「1回1GSI」を人間が覚えておくのではなく、仕組みで防ぐ必要があります。&lt;/p&gt;&#10;&lt;h3 id="firestoreのインデックスにはこんな制約なかった"&gt;Firestoreのインデックスにはこんな制約なかった&lt;/h3&gt;&#10;&lt;p&gt;ここで思い出してほしいんですが、Firestoreの複合インデックスは個別に追加・削除できます。「1回に1つだけ」なんて制約はありません。単一フィールドインデックスに至っては自動作成です。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;「Firestoreのインデックス管理が面倒でAWSに来たのに、DynamoDBのGSI管理の方がよっぽど地獄だった」&lt;/strong&gt;という、見事なオチがつきました。&lt;/p&gt;&#10;&lt;h2 id="filterexpressionとlimitの罠"&gt;FilterExpressionとlimitの罠&lt;/h2&gt;&#10;&lt;p&gt;App Storeの審査提出直後に発見したバグです。言語指定でフィードを取得すると、8件あるはずの投稿が2件しか表示されない。&lt;/p&gt;&#10;&lt;h3 id="原因filterexpressionはlimitの後に動く"&gt;原因：FilterExpressionはlimitの「後」に動く&lt;/h3&gt;&#10;&lt;p&gt;DynamoDBのGSI（LanguageIndex）のパーティションキーが&lt;code&gt;language&lt;/code&gt;だけだったため、&lt;code&gt;language=&amp;quot;ja&amp;quot;&lt;/code&gt;で検索するとUSER・QUIZ・FEED・ROUNDなど全種類のレコードが返ってきます。シングルテーブル設計なので当然です。&lt;/p&gt;&#10;&lt;p&gt;FEEDだけ欲しいので、&lt;code&gt;FilterExpression&lt;/code&gt;で&lt;code&gt;begins_with(PK, &amp;quot;FEED#&amp;quot;)&lt;/code&gt;を指定していました。ここに罠があります。&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;// DynamoDBの動作&#10;limit: 20で20件取得 → その中にFEEDレコードが2件しかない → 結果2件&#10;&#10;// RDB（SQL）なら当然こう&#10;WHERE type = &amp;#39;FEED&amp;#39; AND language = &amp;#39;ja&amp;#39; LIMIT 20 → FEEDが20件返る&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;DynamoDBのFilterExpressionは、limitで取得した後にフィルタする。&lt;/strong&gt;RDBの&lt;code&gt;WHERE&lt;/code&gt;句とは根本的に動作が違います。&lt;/p&gt;</description></item><item><title>Claude CodeでWordPressブログを運用してわかった限界と、次に選ぶ技術スタック</title><link>https://www.morisakiblog.com/claude-code-wordpress-limitation-hugo/</link><pubDate>Wed, 18 Mar 2026 00:00:00 +0000</pubDate><guid>https://www.morisakiblog.com/claude-code-wordpress-limitation-hugo/</guid><description>&lt;p&gt;このブログはWordPressで運営しています。そしてここ数週間、Claude Code（Anthropicが提供するAIコーディングツール）を使って、記事の作成・編集・SEO設定・品質監査まで、ブログ運用のほぼ全てをAIと一緒にやってきました。&lt;/p&gt;&#10;&lt;p&gt;結論から言うと、「できることは多い。でも限界もはっきり見えた」。&lt;/p&gt;&#10;&lt;p&gt;この記事では、Claude Code × WordPressで実際にやったこと、ぶつかった壁、そして次に専門ブログを立てるなら何を選ぶかを、全て体験ベースでお話しします。&lt;/p&gt;&#10;&lt;h2 id="claude-code--wordpressでできたこと"&gt;Claude Code × WordPressでできたこと&lt;/h2&gt;&#10;&lt;p&gt;WordPress REST APIを使えば、Claude Codeから記事の作成・編集・公開が直接できます。実際にやったことを挙げると：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;記事のCRUD操作&lt;/strong&gt;：新規作成、本文の編集、ステータス変更（下書き→公開）、カテゴリ・タグの変更まで全てAPIで完結&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;80記事の品質監査&lt;/strong&gt;：全記事をAPIで取得して、文字数・構造・内容を分析。AdSense審査に不利になりそうな低品質記事を特定し、約10記事にnoindexを設定&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;SEOメタ情報の設定&lt;/strong&gt;：CocoonテーマのカスタムフィールドにREST API経由でSEOタイトル・メタディスクリプションを書き込み&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;カテゴリの一括整理&lt;/strong&gt;：「フリーランス」カテゴリを廃止して、該当記事を「ビジネス考察」に移行&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;GSC・GA4のデータ分析&lt;/strong&gt;：検索パフォーマンスを確認しながら、タイトル変更やリライトの判断をAIと壁打ち&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;WordPress REST APIでの記事自動化について、詳しくはこちらの記事でも書いています。&lt;/p&gt;&#10;&lt;a href="https://www.morisakiblog.com/claude-code-wordpress-rest-api-automation/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;img src="https://img.morisakiblog.com/posts/claude-code-wordpress-rest-api-automation/featured-image-1564-2049b5492b0eee308e71423d7871d58c.png" alt="Claude Code × WordPress REST APIで記事の投稿・編集を自動化してみた" loading="lazy"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;Claude Code × WordPress REST APIで記事の投稿・編集を自動化してみた&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;Claude CodeからWordPress REST APIを使って記事の投稿・編集を自動化する方法を解説。Application Passwordsのセットアップ手順、公開記事の編集ワークフロー、SiteGuardとの相性問題、セキュリティ対策まで実体験ベースでまとめました。&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;p&gt;率直に言って、かなりのことができます。Claude Codeにブログの運用方針やルールをメモリファイルとして渡しておけば、文脈を理解した上で記事の執筆・編集をしてくれます。「この記事のSEOタイトル設定して」「この記事公開して」と言えば数秒で完了です。&lt;/p&gt;&#10;&lt;p&gt;GSC・GA4との連携についてはこちらも参考にどうぞ。&lt;/p&gt;&#10;&lt;a href="https://www.morisakiblog.com/claude-code-gsc-ga4-seo-keyword-discovery/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;img src="https://img.morisakiblog.com/posts/claude-code-gsc-ga4-seo-keyword-discovery/featured-image-1570-273850756379478419c0f4bcee01238d.png" alt="Claude Code × GSC × GA4でSEO改善｜「芽キーワード」発掘から記事リライトまでの全手順" loading="lazy"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;Claude Code × GSC × GA4でSEO改善｜「芽キーワード」発掘から記事リライトまでの全手順&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;Claude CodeにGSCとGA4のMCPを接続し、表示されているのにクリックされない「芽キーワード」を発掘。キーワードクラスタ分析から記事リライト、効果検証まで、AIとデータで回すSEO改善ワークフローの全手順を実データで解説します。&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;a href="https://www.morisakiblog.com/claude-code-mcp-google-analytics-setup/" class="linkcard" &gt;&#10; &lt;div class="linkcard__main"&gt;&#10; &lt;div class="linkcard__image-wrap"&gt;&#10; &lt;img src="https://img.morisakiblog.com/posts/claude-code-mcp-google-analytics-setup/featured-image-1550-6c7eecb9a742b4c754c3d3156751785c.png" alt="Google Analyticsが使いづらい？Claude Code × MCPで全部解決した話" loading="lazy"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__content"&gt;&#10; &lt;div class="linkcard__title"&gt;Google Analyticsが使いづらい？Claude Code × MCPで全部解決した話&lt;/div&gt;&#10; &lt;div class="linkcard__description"&gt;GA4のUIが使いづらい？Claude CodeにGA4・Search ConsoleのMCPサーバーを接続すれば、PVや検索キーワードを自然言語で取得できます。セットアップ手順と活用例を解説。&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="linkcard__domain"&gt;&#10; &lt;img src="https://www.google.com/s2/favicons?domain=morisakiblog.com&amp;sz=16" alt="" class="linkcard__favicon"&gt;&#10; &lt;span&gt;morisakiblog.com&lt;/span&gt;&#10; &lt;/div&gt;&#10;&lt;/a&gt;&#10;&#10;&lt;h2 id="ここが限界だった"&gt;ここが限界だった&lt;/h2&gt;&#10;&lt;p&gt;しかし、使い込むほどに「WordPressとAIの相性の悪さ」が見えてきました。&lt;/p&gt;&#10;&lt;h3 id="cocoonのカスタムフィールドがapiで完全制御できない"&gt;CocoonのカスタムフィールドがAPIで完全制御できない&lt;/h3&gt;&#10;&lt;p&gt;一番痛かったのがこれです。Cocoonテーマには「noindex設定」「SEOタイトル」「メタディスクリプション」などのカスタムフィールドがあります。REST APIから値を書き込むことはできるのですが、&lt;strong&gt;削除が効かない&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>Firebase + Algoliaの限界：個人開発でAWS移行した2理由と体験談</title><link>https://www.morisakiblog.com/firebase-algolia-to-aws-migration/</link><pubDate>Mon, 22 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.morisakiblog.com/firebase-algolia-to-aws-migration/</guid><description>&lt;p&gt;クイズ共有アプリを個人開発してGoogle Playでリリースしている者です。最初はFirebase + Algoliaの組み合わせで快適に開発していましたが、機能を拡張していく中で「なんか辛いな…」と感じることが増えてきました。&lt;/p&gt;&#10;&lt;p&gt;今回は実際に感じた問題点と、AWS移行を決断した理由について、実体験を交えて書いてみます。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;📱 対象アプリ&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/morisakisan/share_quiz"&gt;GitHub: share_quiz&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="最初は快適だったfirebase"&gt;最初は快適だったFirebase&lt;/h2&gt;&#10;&lt;p&gt;個人開発を始めた当初、Firebaseは本当に素晴らしいサービスでした。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 認証も簡単&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; FirebaseAuth.instance.signInWithGoogle();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// データベースも直感的&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; FirebaseFirestore.instance&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .collection(&lt;span style="color:#e6db74"&gt;&amp;#39;quiz&amp;#39;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .add(quizData);&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;セットアップが簡単で、インフラを意識せずに開発に集中できる。個人開発者にとって理想的な環境でした。&lt;/p&gt;&#10;&lt;p&gt;特に以下の機能は本当に素晴らしく、開発初期は「Firebase最高！」と思っていました。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;リアルタイム更新&lt;/strong&gt;: 他のユーザーの投稿が即座に反映&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;簡単な認証&lt;/strong&gt;: Google/Apple/メール認証が数行で実装&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;自動スケーリング&lt;/strong&gt;: インフラ管理不要&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;豊富なSDK&lt;/strong&gt;: Flutter/React/iOS/Android対応&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// リアルタイムでデータが同期される&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FirebaseFirestore.instance&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .collection(&lt;span style="color:#e6db74"&gt;&amp;#39;quiz&amp;#39;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .snapshots()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .listen((snapshot) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 他のユーザーが投稿したクイズが即座に反映&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; updateUI(snapshot.docs);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このリアルタイム機能により、ユーザー同士のインタラクションが活発になり、アプリの魅力が大幅に向上しました。&lt;/p&gt;&#10;&lt;h2 id="問題1-firestoreの限界に直面"&gt;問題1: Firestoreの限界に直面&lt;/h2&gt;&#10;&lt;p&gt;アプリの機能を拡張していく中で、Firestoreの制約が徐々に見えてきました。&lt;/p&gt;&#10;&lt;h3 id="複雑な検索ができない"&gt;複雑な検索ができない&lt;/h3&gt;&#10;&lt;p&gt;ユーザーから「タイトルに”歴史”を含み、難易度が中級以上で、作成日が1週間以内のクイズを検索したい」という要望が来ました。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// やりたいこと（SQLなら簡単）&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SELECT &lt;span style="color:#f92672"&gt;*&lt;/span&gt; FROM quiz &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WHERE title LIKE &lt;span style="color:#e6db74"&gt;&amp;#39;%歴史%&amp;#39;&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AND difficulty &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;intermediate&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AND created_at &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; DATE_SUB(NOW(), INTERVAL &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; WEEK);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Firestoreでは...無理！&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 複数の不等号条件は使えない&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// LIKE検索もできない&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;結果的に、複数のクエリに分割してアプリ側で結合する必要がありました。&lt;/p&gt;</description></item></channel></rss>