はじめに
こんにちは!万年ダイエッターの Wakuqqa(ワクッカ) です。✌️
人生初の個人開発プロジェクトとして「LogEats(ログイーツ)」という AI 食事管理アプリを作っています!
右も左もわからない中、皆さんに使っていただけていて、私のモチベーションも爆上がりしております!🐨✨
(最近 𝕏 (@wakuqqa) でも、開発の裏側をつぶやき始めました!公式アカウント (@EatsLog88161) と合わせて、ぜひフォローしてやってください!🙏)
実は最近、LogEats の公式アカウントを運用するために 𝕏 を始めたばかりなのですが、始めてすぐに気がつきました。
「自分のダイエット成果をアップしようとするたびに、スクショを撮って、数値を手入力して、ハッシュタグを考えて…」ってやるのが、正直めちゃくちゃ面倒だということに!!(個人開発デビューしたての私には、アプリを動かすだけで手一杯なんや…!)
「この手間、ボタン一つにできたら自分も嬉しいし、ユーザーさんも楽しくシェアしてくれて、結果的にアプリをもっとたくさんの人に知ってもらえるんじゃね!?」という、初心者の不便さから生まれた(下心混じりの)純粋な思いつきから今回の開発がスタートしました。
今回は、そんな個人的な「めんどくさい」を解消するために SNS シェア機能を爆速強化したのですが、その裏で Next.js 15 の仕様 に完膚なきまでに叩きのめされた失敗談をお届けします。
もし「ローカル(自分のPC)では動いてるのに、デプロイした途端ビルドが通らなくて泣きそう…!」と震えている方がいたら、この記事を読んで勇気(と解決策)を受け取ってください!🚀
🛠 今回のアップデート内容(やりたかったこと)
「今日何食べたか、もっとオシャレに 𝕏 で自慢したい!」というバイブスに応えるべく、以下の機能を実装しました。
- 𝕏 (Twitter) 専用シェアボタン: ワンタップで、その食事のカロリーやマクロバランスが要約されたツイートを作成。
- 動的 OGP 画像生成: 共有された URL を貼ると、AI が解析した「本日の成果」が画像としてプレビューされます。
- 1日のまとめレポート: 単発の食事だけでなく、一日の合計摂取量と目標達成度を可視化したページを生成。
-
短縮 URL 対応: 𝕏 の文字制限に優しい、スッキリした
/s/xxxx形式のリダイレクト。
バックエンドも daily_shares テーブルを整備して、「あとはデプロイするだけ!完璧!」と確信していました。
絶望の第1ラウンド:params は Promise になったらしい
意気揚々と git push して Vercel のビルドを見守っていた私に、Next.js からの非情な宣告が届きます。
Type error: Route "src/app/s/[shortId]/route.ts" has an invalid "GET" export:
Type "{ params: { shortId: string; }; }" is not a valid type for the function's second argument.
調べてみると、Next.js 15 から params や searchParams は、同期的ではなく「 Promise 」として扱うのがシン・お作法になったとのこと。
// ❌ 修正前(Next.js 14 までのバイブス)
export async function GET(request: Request, { params }: { params: { shortId: string } }) {
const shortId = params.shortId;
// ...
}
// ✅ 修正後(Next.js 15 のシン・お作法)
export async function GET(request: Request, { params }: { params: Promise<{ shortId: string }> }) {
const { shortId } = await params; // ここで await が必要!
// ...
}
「なるほどね、最新の進化に追いついていかなきゃね!」と大人な対応で修正。再度プッシュ!
追跡の第2ラウンド:TypeScript の厳しすぎる愛
「今度こそ通るはず…」とコーヒーを飲んでいたら、またしても赤いログが。
Type error: 'error' is of type 'unknown'.
22 | return NextResponse.json({ error: error.message }, { status: 500 });
^
今度は、デバッグ用に作っておいたチェック用 API の catch ブロックで怒られました。
Next.js 15(というか最近の TS 構成)だと、catch(error) の error はデフォルトで unknown 型。error.message にアクセスするには、ちゃんと型ガードしてあげないといけません。
「もう!デバッグ用のファイルなんだからいいじゃんにゃー!」と叫びながら、そもそも本番には不要なファイルだったので、ディレクトリごと削除してやりました。これが一番のバイブス向上施策です。🗑️
復活の第3ラウンド:OGP 生成も非同期の海へ
これで終わりかと思いきや、動的 OGP 画像を生成している opengraph-image.tsx たちも、同じく params を await するように修正が必要でした。
src/app/share/[id]/opengraph-image.tsxsrc/app/share/daily/[id]/opengraph-image.tsx
これらを全部直して、ようやく…ようやく 「Build Successful」 の文字が!!😭🙌
🎨 できあがった最高のシェア画像は是非Xでチェックしてね
Vercel Postgres からエッジでデータを取得して、next/og で生成した「デイリーレポート」は「背景に実際の食事写真を置き、その上に目標達成率のプログレスバーを重ねる」という、個人開発ならではのこだわりを詰め込みました。
- ワクッカ個人の X: @wakuqqa (開発者の日常とダイエット)
さいごに
Next.js 15 へのアップデートを含めた機能をデプロイする時は、以下の 3 点を心に刻みましょう。
-
paramsはawaitせよ!(型定義もPromiseに!) - TypeScript のエラー型は
unknownだと思え! - 不要なデバッグファイルは即消去!
紆余曲折ありましたが、無事に超オシャレな SNS シェア機能がリリースされました!✌️
皆さんもぜひ、LogEats で自分の食事記録をシェアして「バイブス高めなダイエット生活」を楽しんでください!
参考になったら「LGTM」やフォローをいただけると、クオッカのような笑顔になります!🐨✨
また、最近始めたばかりの𝕏でも、開発の裏側やダイエットの進捗をつぶやいています。ぜひフォローして仲良くしてください!
- ワクッカ個人の X: @wakuqqa (開発者の日常)
- LogEats 公式 X: @EatsLog88161 (最新アプデ情報)

