ReactViteAWSi18nZustand

URL共有できる動画チェーンプレイヤーをVite + Reactで作った(状態同期 / i18n / AWSデプロイ)

Sloth255
Sloth255
·3 min read·657 words

これは何?

Video Chain Player というWebアプリを作りました。「動画の必要な部分だけをつなぎ合わせて、一つの体験として再生・共有できる」アプリです。

🔗 試してみる: https://video-chain-player.sloth255.com/

  • 開始・終了時間を指定して動画をクリップ
  • 複数のクリップを**チェーン(キュー)**して連続再生
  • チェーンの状態をURLにエンコードして1つのリンクで共有

ワークアウトフロー、講義のハイライト、コンピレーション動画など、「この部分だけ見せたい」という体験にぴったりです。

ユーザーができること

  • クリップ作成: URL/IDと開始・終了時間を入力して動画を追加
  • 並び替え: ドラッグ&ドロップでシーケンスを調整
  • プレビュー: その場で再生してタイミングを確認
  • 共有: URLをコピーして送信(受け取った相手も同じチェーンを開ける)
  • 多言語対応: URLで言語を切り替え(例:?lang=ja

技術スタック

領域 技術 備考
フロントエンド React 18 + TypeScript UIの保守性と型安全性
ビルド/開発サーバー Vite 高速HMR、快適なDX
ルーティング React Router v6 パス + クエリで状態を表現
状態管理 Zustand 軽量、URL同期に適している
ドラッグ&ドロップUI @dnd-kit 並び替えの実装
動画プレイヤー react-youtube(IFrame Player API) 簡単な埋め込み再生
i18n i18next + react-i18next 全UIテキストの翻訳
翻訳ロード i18next-http-backend /public/locales/... からランタイムフェッチ
言語検出 i18next-browser-languagedetector 優先順位:?lang= / localStorage / ブラウザ
アナリティクス GA4(gtag) SPAのpage_view + カスタムイベント
ホスティング S3静的サイト + CloudFront CDN配信
IaC AWS SAMテンプレート S3/CloudFrontをコードで管理
CI/CD GitHub Actions + OIDC 長期キーなしでデプロイ
テスト Vitest + Testing Library コンポーネント/ロジックのテスト
Lint/フォーマット ESLint + Prettier 破壊的変更の防止

アーキテクチャと実装のポイント

1) ZustandのステートをURLに同期して即座に共有

共有の手間を最小化するため、チェーンの必要な情報をURLにエンコードする設計にしました。

  • サーバーサイドのストレージ不要(アカウント不要)
  • 受け取った側はリンクを開くだけで同じ状態を再現できる

URLが肥大化すると共有しにくくなるため、URLにエンコードする情報を最小化しました。

  • 動画の idstart/end 時間のみをエンコード
  • タイトルやサムネイルは後から補完して表示(URLの肥大化を防止)

最小エンコードの例:

// URLには必要最小限の情報(id/start/end)のみエンコード
const minimalSegments = segments.map(({ id, start, end }) => ({ id, start, end }));

また、共有リンクには再生位置(どのクリップを再生中か)を含めないことで、「リンクを開くと最初から再生される」を保証しています。

2) HTTPバックエンドによるランタイムi18nロード(ビルド非依存)

最初はビルド時に翻訳JSONをインポートすることも検討しましたが、静的ホスティングやCIとの互換性を高めるため、/public/locales/{{lng}}/translation.json からHTTPでフェッチする方式を採用しました。

  • 言語ファイルを追加するだけでメンテナンスが容易
  • ビルドプロセスが翻訳のインポートに依存しない

3) URLのバリエーションに幅広く対応(watch / Shorts / embed)

「標準URLのみ対応」では不便なため、入力パターンを拡張しました:

  • 標準のwatch URL
  • Shorts
  • 埋め込みURL

結果として「貼り付けるだけ」で成功する率が上がり、まとめて登録する際もずっと楽になりました。

4) デプロイ:S3 + CloudFront、CI:GitHub Actions(OIDC)

静的サイトなのでデプロイはシンプルです:

  • S3(静的ホスティング)
  • CloudFront(CDN)

CI/CDはGitHub Actionsで自動化:ビルド → S3同期 → CloudFrontキャッシュ無効化。

ポイントはOIDCで、長期キーを保存せずにデプロイできます(Secretsを最小化しながら環境レベルの制御を維持)。

静的サイトでもCloudFrontを前に置くことでキャッシュによる高速ロードが得られます。

まとめ

Video Chain Playerは「クリップ × 連続再生 × URL共有」にフォーカスし、以下を重視しました:

  • URLに状態をエンコードして共有の摩擦を最小化
  • i18n + 言語URLの同期で受け取った側も同じ言語で見られる
  • デプロイやアナリティクスも含めた「本番運用レベル」に仕上げる

技術的には:

  • Viteによる高速な開発
  • ZustandのステートをURLに同期して共有しやすく
  • i18nextのHTTPバックエンドで軽量な翻訳管理
  • OIDCによるセキュアなデプロイ

これらを一気に組み合わせた「フル稼働スタック」を構築できたのが最大の収穫でした。