ReactViteAWSi18nZustand

URL 공유 가능한 비디오 체인 플레이어 — Vite + React로 구축 (상태 동기화 / i18n / AWS 배포)

Sloth255
Sloth255
·1 min read·124 words

무엇을 만들었나요?

Video Chain Player를 만들었습니다. 비디오의 필요한 구간만 연결해 하나의 경험으로 재생/공유할 수 있는 웹 앱입니다.

🔗 지금 써보기: https://video-chain-player.sloth255.com/

  • 시작/종료 시간을 지정해 비디오를 클립 처리
  • 여러 클립을 체인(큐) 으로 연결해 연속 재생
  • 체인 상태를 URL로 인코딩해 링크 하나로 공유

워크아웃 플로우, 강의 하이라이트, 컴필레이션 릴 같이 "이 부분만 보여주기" 경험을 만들기에 딱입니다.

사용자가 할 수 있는 것

  • 클립 만들기: 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 Template S3/CloudFront를 코드로 관리
CI/CD GitHub Actions + OIDC 장기 키 없이 배포
테스트 Vitest + Testing Library 컴포넌트/로직 테스트
Lint/Format 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를 두면:

  • 캐싱으로 빠른 로딩
  • SPA 라우팅 지원(/로 폴백 등)이 쉬워집니다

정리

Video Chain Player는 "클립 × 연속 재생 × URL 공유"에 집중하며, 다음을 중시했습니다:

  • URL에 상태를 인코딩해 공유 마찰 최소화
  • i18n + 언어 URL 동기화로 수신자도 같은 언어로 보임
  • 배포와 분석을 포함한 "프로덕션 레디"로 만들기

기술적으로는 다음을 조합할 수 있었습니다:

  • Vite로 빠른 개발
  • Zustand 상태의 URL 동기화로 공유성 향상
  • i18next의 HTTP 백엔드로 경량 번역 관리
  • OIDC로 안전한 배포

이 "전체 운영 스택"을 한 번에 구축하는 것이 하이라이트였습니다.