このウェブサイト — 私が自分で構築し、運営しているバイリンガルの旅行ブログ
この記事は英語で書かれ、翻訳されています。
友人や家族と、英語と日本語の両方で自分の旅の体験を共有できる場所が欲しかったし、採用担当者に自分が実際に作り上げたものを提示したかったのです。そこで、ブログプラットフォームを利用する代わりに、このサイトをゼロから設計・構築し、現在は日本に住みながら、米国にいる友人の自宅にあるLinuxサーバーで運営しています。 このプロジェクトを始めたのは2024年3月のことでした。当時、私は日本での留学を始めたばかりで、Instagramの10枚限定の投稿に留めるのではなく、もっと自由に自分の体験を共有したいと思っていたからです。 大学で一連のウェブ開発の授業を終えたばかりだったので、卒業制作や授業で学んだことを糧に、思い切って自分のウェブサイトを構築することにしたのです。長い間開発から離れていたものの、ようやく再びやる気を取り戻し、プロジェクトを完成させ、当初目指していた機能を実装することができました。 パフォーマンスとセキュリティを確保するため、より優れた技術を用いて、プロジェクトをゼロから完全に作り直しました。

ブロックベースのエディタです。投稿は、ヒーローカバー、ワイドバナー、画像とテキストの分割、3枚のスマホ写真の列、リッチテキスト、動画といったブロックを組み合わせて作成します。ブロックの順序を変更したり、アップロード前に各写真をスロットに合わせてトリミングしたり、下書きを保存したり、公開前にプレビューを確認したりできます。
一度書けば、2つの言語で読めます。英語か日本語のいずれかで執筆し、DeepL APIを通じてワンクリックで翻訳します。公開前に翻訳内容を確認します。システムは各翻訳がどの原文から生成されたかを記憶しているため、後で再翻訳を行う際も、私が変更した部分のみが対象となり、自分で修正した部分は上書きされることはありません。

家族専用のプライベートスペースです。家族は招待制で参加し、メールで送られてくるリンクからログインします(パスワードは不要です)。家族のみが閲覧できるスレッド形式のコメントを残すことができます。招待リンクは1つのメールアドレスに対して1回のみ有効で、このルールは2か所で適用されるため、招待なしでの登録は不可能です。
使用技術:Next.js 16 および React 19(TypeScript)、Tailwind CSS、Prisma を使用した PostgreSQL、Better Auth、Tiptap、sharp および ffmpeg(メディア処理用)、DeepL、メール送信用の Resend。Cloudflare Tunnel の背後にあるホームサーバー上の Docker で動作しています。 GitHub Actionsが変更のたびに自動的にテストとビルドを実行します。
学んだこと
古いデータや非公開データを配信することなくキャッシュを行う。公開ページは事前に生成・キャッシュされますが、個人情報は訪問者ごとにその都度新たに生成され、公開するとキャッシュは即座にクリアされます。
プライバシーは重要な機能です。スマートフォンで撮影した写真や動画にはGPS座標が含まれています。アップロードされるすべてのデータからメタデータが削除されます。これは、位置情報を含むテストファイルを使って確認済みです。
手が届かないサーバーの運用。サーバーは別の大陸にあります。SSH(鍵認証のみ、パスワードログインは無効)経由でデプロイし、毎晩バックアップを取り、アウトバウンドトンネルを介してサイトを公開しているため、開いているポートはなく、自宅のIPアドレスが変わってもサイトは正常に動作し続けます。
再現可能なビルド。最初のCI実行では、私のマシンでしか動作しない問題により失敗しました。それらを修正する過程で、ビルドパイプラインを製品の一部として扱うべきだと学びました。