Building a URL-Shareable Video Chain Player with Vite + React (State Sync / i18n / AWS Deployment)

by Sloth255
ReactViteAWSi18nZustand

Building a URL-Shareable Video Chain Player with Vite + React

What is This?

I built Video Chain Player, a web app that lets you "chain together only the necessary segments of videos and play/share them as a single experience."

🔗 Try it now: https://video-chain-player.sloth255.com/

  • Clip a video by specifying start and end times
  • Chain (queue) multiple clips for continuous playback
  • Encode the chain state into a URL and share with a single link

Perfect for creating "show only this part" experiences like workout flows, lecture highlights, or compilation reels.

What Users Can Do

  • Create clips: Add videos by entering URL/ID and start/end times
  • Reorder: Adjust the sequence with drag & drop
  • Preview: Play on the spot to verify timing
  • Share: Copy the URL and send it (recipients open the same chain)
  • Multilingual: Switch languages via URL (e.g., ?lang=ja)

Tech Stack

Area Technology Notes
Frontend React 18 + TypeScript UI maintainability and type safety
Build/Dev Server Vite Fast HMR, great DX
Routing React Router v6 Express state via path + query
State Management Zustand Lightweight, suitable for URL sync
Drag & Drop UI @dnd-kit Implement reordering
Video Player react-youtube (IFrame Player API) Quick embedded playback
i18n i18next + react-i18next Translate all UI strings
Translation Loading i18next-http-backend Runtime fetch from /public/locales/...
Language Detection i18next-browser-languagedetector Priority: ?lang= / localStorage / browser
Analytics GA4 (gtag) SPA page_view + custom events
Hosting S3 Static Site + CloudFront CDN delivery
IaC AWS SAM Template Manage S3/CloudFront as code
CI/CD GitHub Actions + OIDC Deploy without long-term keys
Testing Vitest + Testing Library Test components/logic
Lint/Format ESLint + Prettier Prevent breaking changes

Architecture and Implementation Highlights

1) Sync Zustand State to URL for Instant Sharing

To minimize sharing friction, I designed the app to encode the chain's essential information into the URL.

  • No server-side storage (no account needed)
  • Recipients can reproduce the same state by just opening the link

To prevent URL bloat (which makes sharing difficult), I minimized the information encoded in the URL.

  • Encode only video id and start/end times
  • Supplement titles and thumbnails later for display (prevents URL bloat)

Example of minimal encoding:

// Encode only essential info (id/start/end) in URL
const minimalSegments = segments.map(({ id, start, end }) => ({ id, start, end }));

Additionally, shared links don't include playback position (which clip is playing), ensuring "opening the link starts from the beginning."

2) Runtime i18n Loading via HTTP Backend (Build-Independent)

Initially, I considered importing translation JSONs at build time, but for better compatibility with static hosting and CI, I opted to fetch via HTTP from /public/locales/{{lng}}/translation.json.

  • Easy to maintain—just add language files
  • Build process doesn't depend on translation imports

3) Language Switching Syncs with URL (?lang=) and Persists When Shared

i18n isn't just in-page switching; it also works via URL query parameter lang.

  • / → Default language (English)
  • /?lang=ja → Japanese

The language selector updates lang (removes lang for English to keep URLs clean).

const params = new URLSearchParams(searchParams);
if (langCode !== 'en') params.set('lang', langCode);
else params.delete('lang');
navigate(params.toString() ? `?${params}` : '/', { replace: true });

4) Handle URL Variations Robustly (watch / Shorts / embed)

Supporting "only standard URLs" would be inconvenient, so I expanded the input patterns:

  • Standard watch URLs
  • Shorts
  • Embed URLs

As a result, "just paste" success rate increased, making batch registration much easier.

5) Deployment: S3 + CloudFront, CI: GitHub Actions (OIDC)

Since it's a static site, deployment is straightforward:

  • S3 (static hosting)
  • CloudFront (CDN)

CI/CD is automated via GitHub Actions: build → S3 sync → CloudFront cache invalidation.

The key point is OIDC, enabling deployment without storing long-term keys (minimizing Secrets while maintaining environment-level control).

Even for static sites, putting CloudFront in front provides:

  • Fast loading via caching
  • Easy SPA routing assistance (e.g., fallback to /)

Summary

Video Chain Player focuses on "clips × continuous playback × URL sharing," with emphasis on:

  • Encoding state in URLs to minimize sharing friction
  • i18n + language URL sync so recipients see the same language
  • Making it "production-ready" including deployment and analytics

Technically, I was able to combine:

  • Rapid development with Vite
  • Syncing Zustand state to URLs for better shareability
  • Lightweight translation management with i18next's HTTP backend
  • Secure deployment with OIDC

Building this "full operational stack" in one go was the highlight.