Skip to content

feat(sandbox): add i18n demos and e2e coverage#1593

Open
sampotts wants to merge 38 commits into
feat/i18n-reactfrom
feat/i18n-sandbox
Open

feat(sandbox): add i18n demos and e2e coverage#1593
sampotts wants to merge 38 commits into
feat/i18n-reactfrom
feat/i18n-sandbox

Conversation

@sampotts

@sampotts sampotts commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Refs #222
Closes #1594

Summary

Adds locale switching to all sandbox presets (HTML, React, CDN) with shared helpers and e2e tests verifying translated control labels.

Changes

  • Language picker with shipped + browser-only locales; dev-mode model download logging
  • Shared sandbox i18n helpers for HTML, React, and CDN templates
  • E2e specs for HTML sandbox, CDN sandbox, and CDN bundle with locale=es
Stack info

PR 5 of 5 — stacks on React i18n PR. Final PR in the i18n stack.

Testing

pnpm -F @videojs/html build:cdn
pnpm build:sandbox
pnpm test:e2e:vite --grep i18n

Note

Low Risk
Changes are confined to the sandbox app, dev Vite plugins, and e2e tests—not production player bundles or auth.

Overview
Adds locale switching across the sandbox shell and every HTML, React, and CDN preset, plus Playwright coverage that Spanish (locale=es) shows Reproducir on the play control (direct tab and shell iframe).

The shell gains a Language control in Player settings, keeps locale in the URL, and broadcasts locale-change via postMessage (CDN preview reloads the iframe when locale changes). Shared helpers load built-in packs or Chrome Translator–only tags, with separate paths for source @videojs/html/i18n vs CDN @videojs/html/cdn/i18n (generated locale loaders, media-i18n-provider wrapping, and a Vite plugin that pins a single CDN registry and blocks mixing source i18n in the CDN sandbox).

Template mirroring now overwrites src/ when it diverges from templates/ (documented in README); setup also regenerates CDN locale loader maps.

Reviewed by Cursor Bugbot for commit 879d941. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented May 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Jun 19, 2026 3:57am

Request Review

Comment thread apps/sandbox/app/shell/preview.tsx Outdated
Comment thread apps/sandbox/app/shared/html/i18n.ts
Comment thread apps/sandbox/templates/cdn/index.html Outdated
Comment thread apps/e2e/tests/cdn-i18n.spec.ts Outdated
Comment thread apps/sandbox/app/shell/preview.tsx
sampotts and others added 30 commits June 19, 2026 13:45
Use formatRemaining with the parametric timeRemainingPhrase template instead
of the removed remainingTimeSuffix key.

Co-authored-by: Cursor <cursoragent@cursor.com>
Adds integration coverage that play button aria-label updates when
document.documentElement.lang changes and the i18n provider has no
explicit lang attribute.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use mergeLocaleOverlays loadedTags instead of merged overlay so
English-only lazy merges no longer block browser translation fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add createI18n with ambient lang inheritance, browser translation fallback,
default loadLocale, and translated aria labels across React player UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wrap the player Provider with I18nProvider so preset skins inherit locale
and lazy locale loading, and restore English ARIA expectations in tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Let outer I18nProvider (sandbox locale) win over player chrome, and skip
nested default providers so locale props are not shadowed.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pass langRootRef from Container for ambient lang resolution, fall back to
documentElement before mount, and inherit ancestor locale when a nested
provider only supplies translation overrides.

Co-authored-by: Cursor <cursoragent@cursor.com>
Only pass locale to I18nProviderRoot when a value is resolved so nested
providers do not assign undefined under exactOptionalPropertyTypes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Re-check lazy-load sequence after getBrowserTranslations resolves so a
superseded locale cannot register browser translations globally.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use formatRemaining with the parametric timeRemainingPhrase template instead
of the removed remainingTimeSuffix key.

Co-authored-by: Cursor <cursoragent@cursor.com>
Container's langRootRef no longer forces a nested provider that shadows
an ancestor locale or translations prop.

Co-authored-by: Cursor <cursoragent@cursor.com>
Track whether a provider locale came from an explicit prop so Container's
langRootRef still resolves player shell lang when a test or app wrapper
supplies an ambient ancestor provider.

Co-authored-by: Cursor <cursoragent@cursor.com>
Adds regression tests for document.documentElement.lang updates on
I18nProvider with and without langRootRef.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use mergeLocaleOverlays loadedTags instead of merged overlay so
English-only lazy merges no longer block browser translation fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wire locale switching across HTML, React, and CDN sandbox presets with shared
locale helpers, browser-only locale prefetch, and i18n e2e tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep postMessage-driven toggles from forcing a cache-busted iframe reload
when autoplay, muted, or other shell controls change.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the templates/cdn index override that produced an invalid relative
chunk path under Vite 8; setup already mirrors templates into src/cdn.

Co-authored-by: Cursor <cursoragent@cursor.com>
Serialize overlapping HTML/CDN locale updates, validate locale only in
shared listeners, and remove the vite e2e spec that referenced a missing page.

Co-authored-by: Cursor <cursoragent@cursor.com>
Track the previous locale so the CDN preview only cache-busts when locale
actually changes, not on the initial effect run.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the readyLocale gate so locale switches and browser prefetch
failures no longer unmount the player preview.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Update preview iframe src when locale changes so embedded reloads keep
the selected language, not just the initial URL param.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the misplaced "Media utilities" comment above the i18n re-exports.

Co-authored-by: Cursor <cursoragent@cursor.com>
…locale

Stop pinning lang on media-i18n-provider and I18nProvider locale props so
document.documentElement.lang and the locale picker both drive i18n through
the ambient observer as documented.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant