Portfolio Project

散らばるレシピを、
ひとつのホームへ。

見つけたレシピを、自分の言葉で整理する。
タグ管理やURL保存にも対応した
レシピ管理アプリ。

7
テーブル数
Laravel
フレームワーク
個人開発
開発体制
mogu+ アプリモックアップ

mogu+を作った理由

YouTubeやレシピサイト、TikTok、X(Twitter)など、気になるレシピを見かける場所はいつもバラバラ。「あのレシピ、どこで見たっけ?」が日常茶飯事で、特にXだといいねしても投稿がどんどん埋もれてしまい、後から探し出せないことが何度もありました。

また、レシピ通りに作ってみると「うちの家族には少し味が濃いな」「この材料、いつも買い忘れるんだよな」という気づきが生まれることも多く、レシピと一緒にメモも残せる場所がほしいと感じていました。

家族4人分の晩ご飯を作ることが多いのですが、それぞれ好みがバラバラで毎回の献立決めが一番の悩みのタネ。家族みんなが好きなレシピだけを1か所に集めておけば、迷ったときにその中から選ぶだけでいい。

——そこで、自分だけのレシピノートを作ることにしました。

機能紹介

料理の「見つける・保存する・作る」をシンプルにサポートする機能を揃えました。

レシピの作成・編集・削除

レシピの作成・編集・削除はもちろん、削除時は確認ダイアログで誤操作も防止

CRUD 確認ダイアログ ソフトデリート

URLから自動でタイトル取得

料理サイトやYouTubeのURLを貼るだけで、タイトルとサムネイル画像を自動取得。

OGP取得 自動解析

材料からレシピを検索できます!

「豚」と入れるだけで豚肉・豚バラなど豚を使った全レシピが表示。冷蔵庫の食材から今日の献立が決まります。

材料検索 部分一致

カラフルなタグ設定

自分好みのタグを色付きで作成。タグフィルターで目当てのレシピへ素早くアクセス。

カラータグ フィルター

自分アレンジをメモできます!

「うちは味薄め」「弟はきのこ抜き」など、自分好みのアレンジをメモとして残せます。次回作るときに迷いません。

メモ機能 アレンジ記録

画像でサムネイル一覧表示

URLから取得、または自分でアップロードした画像をサムネイルとして表示。自動リサイズ・フォーマット最適化対応。

画像アップロード Cloudinary 自動リサイズ

Googleアカウントで簡単ログイン

Googleアカウントを使用して、面倒なアカウント登録なしで安全にサインイン。すぐに使い始められます。

Google OAuth 安全認証

こんな使い方もできます

URLだけでコレクション

とりあえずURLと必須項目のタイトルだけを保存しておいて、後で詳細を入力。「どこで見たっけ?」をなくせます。

自由なタグ管理

「お父さんNG」「お母さんの好物」など好きな名前のタグを作って、その日の状況に合わせて素早く検索。

サムネで献立の種に

登録したレシピを画像一覧で眺めるだけで、今日作りたいものが直感的に決まります。「家族みんなが好きなもの」タグでフィルターすれば迷いがゼロに。

食品・外食のメモにも

おいしかったものや外食の写真と、店の名前や買った場所をメモして「外食」「食品」などのタグとともに保存すれば、「あれどこで買ったっけ?」「あのお店また行きたい」をタグで即検索できます。

選ぶことすらしんどい日に

デリバリーや総菜など、よく頼む・買うものを写真とタイトルだけで登録しておけば、「何か買って済ませたいけど何も思いつかない」なんて時も、そこから選ぶだけでOK。
考える・探すストレスを減らすための、即決リストとして使えます。

技術スタック

PHP / Laravel
サーバーサイド
Docker / Sail
開発環境
PostgreSQL
データベース
Google OAuth 2.0
認証
Cloudinary
画像ストレージ
Render
デプロイ・ホスティング
Vite
フロントエンドビルド
GitHub
バージョン管理

苦労したこと・学んだこと

PHPもLaravelもDBもほぼわからない状態でAIに教えてもらいながら開発しました。
エラーと格闘した記録です。

01
Google OAuth / Session

ログインできない…
でも原因がどこかわからない

Googleログインの画面まではいけるのに、戻ってきたら「ログインに失敗しました」と出る問題が発生。デバッグコードを書いて調べてみると、セッションの保存先の設定が原因でした。.envSESSION_DRIVERdatabaseからfileに変えるだけで解決。設定ファイルが多くて、どこで何を指定しているか把握するのが大変でした。

02
HTML Form / JavaScript

Enterキーを押したら
途中で送信されてしまう

レシピ新規追加の入力欄でEnterキーを押すと、まだ入力途中なのにフォームが送信されてしまう問題が発生。<form>タグのデフォルトの動きがそういう仕様だったと初めて知りました。送信を防ぐJavaScriptの処理を追加して解決しましたが、動的に追加した入力欄には効いていなかったりと、何度も修正が必要でした。

03
Database / Migration

タグに色をつけようとしたら
保存できなかった

ワイヤーフレームにはタグの色設定をちゃんと描いていたのに、要件定義に書き忘れ、ER図でもcolorカラムを入れ忘れていたため、DBに色を保存する場所がない状態でコーディングを進めてしまいました。設計のどこかで抜けると後工程でしわ寄せがくる、という当たり前のことを身をもって体験しました。マイグレーションを追加して対応しましたが、「ドキュメント間で整合性をとることの大切さ」を実感した出来事でした。

04
JavaScript / Vite

JSファイルを分離したら
突然動かなくなった

仮で作ったブレードファイルに直接書いていたJavaScriptが長くなってきたので外部ファイルに切り出したところ、ボタンを押しても何も起きなくなりました。HTMLタグに書いていたonclick="関数名()"の書き方では、外部ファイルの関数が見えなくなってしまうのが原因でした。addEventListenerを使う書き方に変えて解決しました。さらにViteを再起動して完全に直りました。

05
SVG / CSS

アイコンのサイズが
どうしても変わらない

LucideというアイコンライブラリのアイコンにCSSでサイズを指定しているのに、まったく変化しませんでした。font-sizewidthを何度変えても効かず、他のやり方を色々と試行錯誤。原因はアイコンがSVGとして出力されていること。SVGには通常のCSSが効かず、SVGに直接widthheightを当てる必要がありました。Lucideは表示時にHTMLタグをSVGに自動変換する仕組みになっていて、そのためにCSSの当て方が変わってくるということを初めて知りました。

06
Cloudinary / Laravel

画像のアップロードは成功しているのに表示されない

Cloudinaryというクラウドサービスに画像を保存する機能を実装したとき、データベースには保存できているのに画面に画像が出ませんでした。原因は表示のコードが古いままだったこと。ローカルのファイル用の書き方(asset('storage/...'))のままになっていて、Cloudinaryが返す外部URLをそのまま使えばよかっただけでした。保存と表示は別で考えないといけないと学びました。

07
Docker / HTTPS

Dockerfileって何?というところから本番公開の壁にぶつかった

Renderにデプロイしようとしたら「Dockerfileがない」と言われ、そもそもDockerfileが何かわからない状態からスタート。PHP・Nginx・起動スクリプトを組み合わせた設定ファイルをAIに教えてもらいながら作成しました。さらにデプロイ後は「HTTPSのページなのにHTTPのファイルを読もうとしている」というエラーも発生。本番環境ならではの設定が必要だということを身をもって学びました。

08
Deploy / Vite Build

デプロイしたらページが真っ白・500エラーになった

ローカルでは普通に動いているのに、Renderにデプロイしたら500エラーになりました。デバッグ設定をONにして調べると「Viteのビルドファイルがない」というエラーでした。ローカルでは開発サーバーが自動的にファイルを用意してくれていたけど、本番環境では自分でビルドしておく必要があると初めて知り、Dockerfileにビルドの処理を追加して解決しました。

09
Blade Template

コードのコメントが
バグの原因になっていた

デプロイ後にレシピ追加ボタンを押すとエラーになる問題が発生。ローカルでも同じエラーが再現したため、デプロイとは無関係とわかりキャッシュ系の確認などを一通り試しました。最終的に原因は、ファイルの1行目に書いていたコメントの中の「@includeして使う」という説明文でした。Laravelがコメントの中の@includeを命令として読んでしまっていたのが原因です。実はこのバグ、ローカルではデプロイ前からずっと存在していたのに、古いキャッシュが残っていたおかげでエラーにならずに動き続けていたとのこと。デプロイによってキャッシュがリセットされて初めて表面化したバグでした。まさか自分のメモがバグを生むとは思っておらず、かなり焦りました。

10
File Upload / Frontend

画像を何枚か登録したら
「413エラー」が出た

無事に公開できた!と喜びながら本番環境でレシピに写真をたくさん登録しているとき、突然「413 Request Entity Too Large」というエラーが表示されました。送信するデータが大きすぎてサーバーに弾かれていたのが原因。JavaScriptで画像を送信前に圧縮する処理をフロントエンド側に追加することで解決しました。ローカルでは出なかったエラーなので勉強になりました。

今後やりたいこと

使っていく中で「あったらいいな」と感じた機能を、実装に向けて温めています。

01
実装予定

入力途中のデータを自動保存する下書き機能

今は保存に失敗すると入力した内容がほぼ全部消えてしまうのが一番の痛点。ブラウザの localStorage を使って入力内容をこまめに保存しておき、万が一エラーになっても「続きから書ける」状態にしたいと考えています。

localStorage 下書き保存 入力復元
02
実装予定

よく作るレシピのお気に入り登録機能

ハートボタンを押すだけでお気に入り登録でき、一覧画面でお気に入りだけを絞り込んで表示できるようにしたいと考えています。レシピが増えてきたときに「また作りたいレシピ」をすぐ見つけられる仕組みです。

お気に入り登録 絞り込み表示
03
実装予定

献立カレンダー機能

「今週どれ作ろう?」をカレンダーに書き込んで、月ごとに何を作ったか振り返れるようにしたいと考えています。FullCalendarというライブラリを使えば実装できそうなので、近いうちに挑戦したいです。

FullCalendar 献立管理 月次振り返り
04
あったらいいな

キャプション・説明文から材料と手順を自動入力

URLからタイトルと画像は自動取得できるようになったので、その先も自動化したいと考えています。レシピサイトの説明文やYouTubeのキャプションからAIが材料・手順を読み取って入力フォームに反映できたら、入力の手間がぐっと減りそうです。難易度は高めなのでまだ構想段階ですが、いつか実現させたい機能です。

AI連携 テキスト解析 自動入力
05
あったらいいな

編集権限を付与して複数人で使えるように

今は自分専用のアプリですが、家族など信頼できる人に編集権限を渡して一緒に使えるようにしたいと考えています。「お母さんと私でレシピを共同管理する」というのが最終的なイメージです。権限管理など仕組みが複雑になるので、まずは他の機能から実装していく予定です。

権限管理 共同編集
06
別アプリとして構想中

日用品・食材のストック管理アプリ

日用品や食材のストックを管理するアプリを別途作りたいと考えています。mogu+で「今日何を作るか」を決めたら、ストック管理アプリと連動して「何を買い足せばいいか」がわかるような使い方を想定しています。mogu+の次の個人開発として挑戦予定です。

在庫管理 買い物リスト 次期開発

実際に
触ってみてください

Googleアカウントがあればすぐに使えます