Skip to content

feat(i18n): convert to opaque keys - #1848

Merged
sampotts merged 1 commit into
mainfrom
feat/i18n-keys
Jul 28, 2026
Merged

feat(i18n): convert to opaque keys#1848
sampotts merged 1 commit into
mainfrom
feat/i18n-keys

Conversation

@sampotts

@sampotts sampotts commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

As discussed in our meeting earlier, this moves over from using English as the key to opaque keys for the i18n locale files and usages. If we're happy with the DX of this change and the direction, then we can merge. If not, we can keep the existing English as a key. My preference would be to move to this but I realize there are aspects that weren't fully discussed earlier:

1. Drift

We now have the default text inline and the English locale catalogue and there's potential for them to drift - i.e. <media-text token="buttons.play">Pause</media-text> or t('buttons.play', { default: 'Pause' }) which could cause SSR issues along with confusion.

We can solve this by adding a build-time consistency check that validates known keys against en.ts - so Pause !== Play would throw. This can come in a later release if we decide to take this route.

2. State-derived text

At the end of the meeting we discussed relying on CSS to hide/show multiple <media-text> elements based on state like we do for icons, e.g.:

<media-play-button commandfor="play-tooltip" class="media-button media-button--subtle media-button--icon media-button--play">
  ${renderIcon('restart', { class: 'media-icon media-icon--restart' })}
  ${renderIcon('play', { class: 'media-icon media-icon--play' })}
  ${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
</media-play-button>
<media-tooltip id="play-tooltip" side="top" class="media-surface media-tooltip">
  <media-tooltip-label></media-tooltip-label>
  <media-tooltip-shortcut class="media-tooltip__kbd"></media-tooltip-shortcut>
</media-tooltip>

becomes:

<media-play-button commandfor="play-tooltip" class="media-button media-button--subtle media-button--icon media-button--play">
  ${renderIcon('restart', { class: 'media-icon media-icon--restart' })}
  ${renderIcon('play', { class: 'media-icon media-icon--play' })}
  ${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
  <media-text token="buttons.play" class="media-text media-text--play">Play</media-text>
  <media-text token="buttons.pause" class="media-text media-text--pause">Pause</media-text>
  <media-text token="buttons.replay" class="media-text media-text--restart">Replay</media-text>
</media-play-button>
<media-tooltip id="play-tooltip" side="top" class="media-surface media-tooltip">
  <media-tooltip-label>
    <media-text token="buttons.play" class="media-text media-text--play">Play</media-text>
    <media-text token="buttons.pause" class="media-text media-text--pause">Pause</media-text>
    <media-text token="buttons.replay" class="media-text media-text--restart">Replay</media-text>
  </media-tooltip-label>
  <media-tooltip-shortcut class="media-tooltip__kbd"></media-tooltip-shortcut>
</media-tooltip>

Notice we'd likely need to handle it in <media-tooltip-label> as well since that currently calls getResolvedLabel() on the trigger. If we're moving all of the state-derived text to the UI layer, we'd have to handle that too.

Size changes

The increase is primarily from the locale migration rather than runtime logic:

  • Locale files now contain nested semantic translations for all shipped locales.
  • Generated tree-shakeable text descriptors were added for built-in UI copy.
  • The i18n generator now creates descriptors and validates locale completeness.
  • Shared translation types, flattening utilities, and descriptor guards were added.
  • UI components and platform adapters now resolve descriptors before rendering.
  • Additional tests cover descriptor resolution, locale loading, browser translation, and platform output.

The runtime additions are relatively small; most of the size comes from locale data, generated files, and the associated test coverage.


Note

Medium Risk
Wide i18n API and key-shape change across core and all locales; wrong or missing keys would break UI strings, though build-time locale completeness validation reduces that risk.

Overview
Replaces English-as-key locale strings with nested opaque keys (e.g. buttons.play, errors.network) across all shipped locale packs and moves typing from types to params with generated TranslationParams for placeholder contracts.

Build pipeline: generate-i18n-locales now flattens packs for loadLocale, validates every locale against English keys, and emits tree-shakeable i18n/text/* descriptors; a new generate-i18n-types step runs on prebuild. Package exports add ./i18n/text/*.

Runtime: Registry and browser translation work on FlatTranslations; new Text descriptors plus resolveText / translateText support typed copy. Sandbox CDN checks use ['buttons.play'] instead of .Play.

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

@vercel

vercel Bot commented Jul 16, 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 Jul 28, 2026 6:28am

Request Review

@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 7826717
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6a684c0aaea281000871b73d
😎 Deploy Preview https://deploy-preview-1848--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread packages/core/src/core/ui/time-slider/time-slider-core.ts
Comment thread packages/core/src/core/ui/input-feedback/tests/labels.test.ts
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html

Path Base initial PR initial Diff % Lazy
/video/minimal-skin 51.07 kB 52.12 kB +1.06 kB +2.1% -4.08 kB 🔺
/video/minimal-skin.tailwind 51.81 kB 52.79 kB +999 B +1.9% -4.08 kB 🔺
/video/skin 51.16 kB 52.24 kB +1.08 kB +2.1% -4.08 kB 🔺
/video/skin.tailwind 51.92 kB 52.93 kB +1.01 kB +1.9% -4.08 kB 🔺
/audio/minimal-skin 41.71 kB 41.80 kB +91 B +0.2% -4.08 kB 🔽
/audio/minimal-skin.tailwind 42.17 kB 42.30 kB +133 B +0.3% -4.08 kB 🔽
/audio/skin 44.43 kB 45.25 kB +847 B +1.9% -4.08 kB 🔺
/audio/skin.tailwind 44.96 kB 45.73 kB +786 B +1.7% -4.08 kB 🔺
/live-video/minimal-skin 48.07 kB 48.43 kB +367 B +0.7% -4.08 kB 🔺
/live-video/minimal-skin.tailwind 48.51 kB 48.98 kB +481 B +1.0% -4.08 kB 🔺
/live-video/skin 49.64 kB 50.69 kB +1.05 kB +2.1% -4.08 kB 🔺
/live-video/skin.tailwind 50.22 kB 51.26 kB +1.04 kB +2.1% -4.08 kB 🔺
/live-audio/minimal-skin 34.01 kB 33.97 kB -34 B -0.1% -4.08 kB 🔽
/live-audio/minimal-skin.tailwind 33.44 kB 33.41 kB -32 B -0.1% -4.08 kB 🔽
/live-audio/skin 36.93 kB 37.52 kB +608 B +1.6% -4.08 kB 🔺
/live-audio/skin.tailwind 36.49 kB 37.04 kB +564 B +1.5% -4.08 kB 🔺
/ui/airplay-button 10.70 kB 10.26 kB -452 B -4.1% -4.08 kB 🔽
/ui/audio-track-radio-group 10.41 kB 10.07 kB -354 B -3.3% -4.08 kB 🔽
/ui/captions-button 11.00 kB 10.52 kB -493 B -4.4% -4.08 kB 🔽
/ui/captions-radio-group 10.45 kB 10.13 kB -323 B -3.0% -4.08 kB 🔽
/ui/cast-button 10.72 kB 10.23 kB -494 B -4.5% -4.08 kB 🔽
/ui/compounds 31.88 kB 32.04 kB +160 B +0.5% -4.08 kB 🔽
/ui/controls 7.72 kB 7.72 kB +4 B +0.1% -4.08 kB 🔽
/ui/error-dialog 11.00 kB 10.67 kB -339 B -3.0% -4.08 kB 🔽
/ui/fullscreen-button 10.71 kB 10.23 kB -497 B -4.5% -4.08 kB 🔽
/ui/menu 19.47 kB 19.08 kB -398 B -2.0% -4.08 kB 🔽
/ui/mute-button 10.71 kB 10.25 kB -472 B -4.3% -4.08 kB 🔽
/ui/pip-button 10.73 kB 10.24 kB -497 B -4.5% -4.08 kB 🔽
/ui/play-button 10.72 kB 10.24 kB -484 B -4.4% -4.08 kB 🔽
/ui/playback-rate-button 10.97 kB 10.44 kB -546 B -4.9% -4.08 kB 🔽
/ui/playback-rate-radio-group 10.34 kB 9.84 kB -508 B -4.8% -4.08 kB 🔽
/ui/poster 8.46 kB 7.93 kB -544 B -6.3% -4.08 kB 🔽
/ui/quality-radio-group 11.02 kB 10.64 kB -387 B -3.4% -4.08 kB 🔽
/ui/seek-button 10.76 kB 10.31 kB -462 B -4.2% -4.08 kB 🔽
/ui/slider 5.13 kB 5.76 kB +651 B +12.4% -4.08 kB 🔴
/ui/status-announcer 11.24 kB 10.87 kB -379 B -3.3% -4.08 kB 🔽
/ui/status-indicator 12.23 kB 11.89 kB -342 B -2.7% -4.08 kB 🔽
/ui/time 10.14 kB 9.72 kB -427 B -4.1% -4.08 kB 🔽
/ui/time-slider 14.21 kB 13.82 kB -401 B -2.8% -4.08 kB 🔽
/ui/tooltip 8.39 kB 7.84 kB -566 B -6.6% -4.08 kB 🔽
/ui/volume-indicator 12.27 kB 11.95 kB -325 B -2.6% -4.08 kB 🔽
/ui/volume-slider 12.18 kB 11.65 kB -536 B -4.3% -4.08 kB 🔽
/video (default) 51.13 kB 52.23 kB +1.10 kB +2.1% -4.08 kB 🔺
/video (default + hls) 190.45 kB 191.58 kB +1.13 kB +0.6% -4.08 kB 🔺
/video (minimal) 51.18 kB 52.14 kB +988 B +1.9% -4.08 kB 🔺
/video (minimal + hls) 190.51 kB 191.59 kB +1.08 kB +0.6% -4.08 kB 🔺
/audio (default) 44.41 kB 45.24 kB +848 B +1.9% -4.08 kB 🔺
/audio (minimal) 41.67 kB 41.78 kB +119 B +0.3% -4.08 kB 🔽
Presets (7)
Entry Initial Lazy
/video (default) 52.23 kB 50.16 kB
/video (default + hls) 191.58 kB 50.16 kB
/video (minimal) 52.14 kB 50.16 kB
/video (minimal + hls) 191.59 kB 50.16 kB
/audio (default) 45.24 kB 50.16 kB
/audio (minimal) 41.78 kB 50.16 kB
/background 4.20 kB
Media (10)
Entry Initial
/media/background-video 1.14 kB
/media/container 1.71 kB
/media/dash-video 214.67 kB
/media/hlsjs-video 141.51 kB
/media/mux-audio 165.02 kB
/media/mux-video 165.05 kB
/media/native-hls-video 9.06 kB
/media/simple-hls-audio-only 19.10 kB
/media/simple-hls-video 21.13 kB
/media/vimeo-video 12.32 kB
Players (5)
Entry Initial
/video/player 8.22 kB
/audio/player 5.38 kB
/background/player 3.92 kB
/live-video/player 7.63 kB
/live-audio/player 5.39 kB
Skins (30)
Entry Type Initial Lazy
/video/minimal-skin.css css 5.70 kB
/video/skin.css css 5.66 kB
/video/minimal-skin js 52.12 kB 50.16 kB
/video/minimal-skin.tailwind js 52.79 kB 50.16 kB
/video/skin js 52.24 kB 50.16 kB
/video/skin.tailwind js 52.93 kB 50.16 kB
/audio/minimal-skin.css css 3.97 kB
/audio/skin.css css 3.86 kB
/audio/minimal-skin js 41.80 kB 50.16 kB
/audio/minimal-skin.tailwind js 42.30 kB 50.16 kB
/audio/skin js 45.25 kB 50.16 kB
/audio/skin.tailwind js 45.73 kB 50.16 kB
/background/skin.css css 133 B
/background/skin js 1.14 kB
/live-video/minimal-skin.css css 5.70 kB
/live-video/skin.css css 5.66 kB
/live-video/minimal-skin js 48.43 kB 50.16 kB
/live-video/minimal-skin.tailwind js 48.98 kB 50.16 kB
/live-video/skin js 50.69 kB 50.16 kB
/live-video/skin.tailwind js 51.26 kB 50.16 kB
/live-audio/minimal-skin.css css 3.97 kB
/live-audio/skin.css css 3.86 kB
/live-audio/minimal-skin js 33.97 kB 50.16 kB
/live-audio/minimal-skin.tailwind js 33.41 kB 50.16 kB
/live-audio/skin js 37.52 kB 50.16 kB
/live-audio/skin.tailwind js 37.04 kB 50.16 kB
/global.css css 183 B
/shared.css css 153 B
/tailwind.css css 161 B
/skin-element js 1.51 kB
UI Components (39)
Entry Initial
/ui/airplay-button 2.53 kB
/ui/alert-dialog 2.87 kB
/ui/alert-dialog-close 2.34 kB
/ui/alert-dialog-description 2.31 kB
/ui/alert-dialog-title 2.34 kB
/ui/audio-track-radio-group 3.02 kB
/ui/buffering-indicator 2.62 kB
/ui/captions-button 2.63 kB
/ui/captions-radio-group 3.05 kB
/ui/cast-button 2.55 kB
/ui/compounds 3.14 kB
/ui/controls 2.86 kB
/ui/error-dialog 2.88 kB
/ui/fullscreen-button 2.54 kB
/ui/hotkey 2.42 kB
/ui/menu 2.89 kB
/ui/mute-button 2.53 kB
/ui/pip-button 2.59 kB
/ui/play-button 2.55 kB
/ui/playback-rate-button 2.63 kB
/ui/playback-rate-radio-group 2.85 kB
/ui/popover 3.23 kB
/ui/poster 2.41 kB
/ui/quality-radio-group 2.99 kB
/ui/seek-button 2.62 kB
/ui/seek-indicator 2.74 kB
/ui/seek-indicator-value 466 B
/ui/slider 2.88 kB
/ui/status-announcer 2.47 kB
/ui/status-indicator 2.53 kB
/ui/status-indicator-value 390 B
/ui/thumbnail 2.55 kB
/ui/time 2.87 kB
/ui/time-slider 2.89 kB
/ui/tooltip 2.91 kB
/ui/volume-indicator 2.56 kB
/ui/volume-indicator-fill 385 B
/ui/volume-indicator-value 414 B
/ui/volume-slider 2.88 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react

Path Base initial PR initial Diff % Lazy
/video/minimal-skin 41.05 kB 41.41 kB +376 B +0.9% -4.08 kB 🔺
/video/minimal-skin.tailwind 47.15 kB 47.46 kB +317 B +0.7% -4.08 kB 🔺
/video/skin 40.78 kB 40.99 kB +211 B +0.5% -4.08 kB 🔽
/video/skin.tailwind 46.77 kB 47.10 kB +342 B +0.7% -4.08 kB 🔺
/audio/minimal-skin 33.92 kB 34.18 kB +263 B +0.8% -4.08 kB 🔽
/audio/minimal-skin.tailwind 36.17 kB 36.23 kB +60 B +0.2% -4.08 kB 🔽
/audio/skin 33.88 kB 34.15 kB +275 B +0.8% -4.08 kB 🔽
/audio/skin.tailwind 38.10 kB 38.30 kB +206 B +0.5% -4.08 kB 🔽
/live-video/minimal-skin 35.51 kB 35.71 kB +203 B +0.6% -4.08 kB 🔽
/live-video/minimal-skin.tailwind 41.44 kB 41.59 kB +156 B +0.4% -4.08 kB 🔽
/live-video/skin 35.46 kB 35.70 kB +243 B +0.7% -4.08 kB 🔽
/live-video/skin.tailwind 41.43 kB 41.62 kB +189 B +0.4% -4.08 kB 🔽
/live-audio/minimal-skin 24.31 kB 24.28 kB -23 B -0.1% -4.08 kB 🔽
/live-audio/minimal-skin.tailwind 27.44 kB 27.43 kB -7 B -0.0% -4.08 kB 🔽
/live-audio/skin 24.34 kB 24.36 kB +24 B +0.1% -4.08 kB 🔽
/live-audio/skin.tailwind 27.51 kB 27.48 kB -25 B -0.1% -4.08 kB 🔽
/ui/airplay-button 9.87 kB 9.46 kB -420 B -4.2% -4.08 kB 🔽
/ui/audio-track 7.35 kB 6.99 kB -363 B -4.8% -4.08 kB 🔽
/ui/captions-button 9.89 kB 9.43 kB -475 B -4.7% -4.08 kB 🔽
/ui/captions-radio-group 7.46 kB 7.12 kB -345 B -4.5% -4.08 kB 🔽
/ui/cast-button 9.90 kB 9.43 kB -487 B -4.8% -4.08 kB 🔽
/ui/error-dialog 9.78 kB 9.44 kB -346 B -3.5% -4.08 kB 🔽
/ui/fullscreen-button 9.88 kB 9.40 kB -483 B -4.8% -4.08 kB 🔽
/ui/live-button 8.37 kB 7.94 kB -444 B -5.2% -4.08 kB 🔽
/ui/menu 19.32 kB 18.95 kB -381 B -1.9% -4.08 kB 🔽
/ui/mute-button 9.87 kB 9.44 kB -436 B -4.3% -4.08 kB 🔽
/ui/pip-button 9.91 kB 9.41 kB -516 B -5.1% -4.08 kB 🔽
/ui/play-button 9.86 kB 9.42 kB -451 B -4.5% -4.08 kB 🔽
/ui/playback-rate-button 9.92 kB 9.42 kB -509 B -5.0% -4.08 kB 🔽
/ui/quality 7.88 kB 7.51 kB -377 B -4.7% -4.08 kB 🔽
/ui/seek-button 9.92 kB 9.47 kB -463 B -4.6% -4.08 kB 🔽
/ui/slider 10.86 kB 11.43 kB +584 B +5.3% +50.16 kB 🔺
/ui/status-announcer 10.49 kB 10.15 kB -352 B -3.3% -4.08 kB 🔽
/ui/status-indicator 11.52 kB 11.18 kB -348 B -3.0% -4.08 kB 🔽
/ui/time 9.10 kB 8.72 kB -392 B -4.2% -4.08 kB 🔽
/ui/time-slider 11.75 kB 11.36 kB -392 B -3.3% -4.08 kB 🔽
/ui/volume-indicator 11.61 kB 11.26 kB -357 B -3.0% -4.08 kB 🔽
/ui/volume-slider 11.28 kB 10.81 kB -485 B -4.2% -4.08 kB 🔽
/video (default) 40.84 kB 41.16 kB +327 B +0.8% -4.08 kB 🔺
/video (default + hls) 178.81 kB 179.24 kB +433 B +0.2% -4.08 kB 🔺
/video (minimal) 41.17 kB 41.49 kB +334 B +0.8% -4.08 kB 🔺
/video (minimal + hls) 179.35 kB 179.56 kB +219 B +0.1% -4.08 kB 🔽
/audio (default) 33.95 kB 34.21 kB +270 B +0.8% -4.08 kB 🔽
/audio (minimal) 34.01 kB 34.25 kB +248 B +0.7% -4.08 kB 🔽
Presets (7)
Entry Initial Lazy
/video (default) 41.16 kB 50.16 kB
/video (default + hls) 179.24 kB 50.16 kB
/video (minimal) 41.49 kB 50.16 kB
/video (minimal + hls) 179.56 kB 50.16 kB
/audio (default) 34.21 kB 50.16 kB
/audio (minimal) 34.25 kB 50.16 kB
/background 579 B
Media (9)
Entry Initial
/media/background-video 403 B
/media/dash-video 213.00 kB
/media/hlsjs-video 139.91 kB
/media/mux-audio 163.30 kB
/media/mux-video 163.38 kB
/media/native-hls-video 7.29 kB
/media/simple-hls-audio-only 17.36 kB
/media/simple-hls-video 19.43 kB
/media/vimeo-video 10.49 kB
Skins (27)
Entry Type Initial Lazy
/tailwind.css css 161 B
/video/minimal-skin.css css 5.56 kB
/video/skin.css css 5.52 kB
/video/minimal-skin js 41.41 kB 50.16 kB
/video/minimal-skin.tailwind js 47.46 kB 50.16 kB
/video/skin js 40.99 kB 50.16 kB
/video/skin.tailwind js 47.10 kB 50.16 kB
/audio/minimal-skin.css css 3.79 kB
/audio/skin.css css 3.68 kB
/audio/minimal-skin js 34.18 kB 50.16 kB
/audio/minimal-skin.tailwind js 36.23 kB 50.16 kB
/audio/skin js 34.15 kB 50.16 kB
/audio/skin.tailwind js 38.30 kB 50.16 kB
/background/skin.css css 90 B
/background/skin js 272 B
/live-video/minimal-skin.css css 5.56 kB
/live-video/skin.css css 5.52 kB
/live-video/minimal-skin js 35.71 kB 50.16 kB
/live-video/minimal-skin.tailwind js 41.59 kB 50.16 kB
/live-video/skin js 35.70 kB 50.16 kB
/live-video/skin.tailwind js 41.62 kB 50.16 kB
/live-audio/minimal-skin.css css 3.79 kB
/live-audio/skin.css css 3.68 kB
/live-audio/minimal-skin js 24.28 kB 50.16 kB
/live-audio/minimal-skin.tailwind js 27.43 kB 50.16 kB
/live-audio/skin js 24.36 kB 50.16 kB
/live-audio/skin.tailwind js 27.48 kB 50.16 kB
UI Components (33)
Entry Initial
/ui/airplay-button 2.46 kB
/ui/alert-dialog 2.61 kB
/ui/audio-track 2.29 kB
/ui/buffering-indicator 2.58 kB
/ui/captions-button 2.39 kB
/ui/captions-radio-group 2.28 kB
/ui/cast-button 2.45 kB
/ui/controls 2.49 kB
/ui/error-dialog 2.47 kB
/ui/fullscreen-button 2.45 kB
/ui/gesture 2.33 kB
/ui/hotkey 2.26 kB
/ui/live-button 2.34 kB
/ui/menu 2.74 kB
/ui/mute-button 2.48 kB
/ui/pip-button 2.49 kB
/ui/play-button 2.46 kB
/ui/playback-rate 2.47 kB
/ui/playback-rate-button 2.47 kB
/ui/popover 3.08 kB
/ui/poster 2.45 kB
/ui/quality 2.31 kB
/ui/seek-button 2.46 kB
/ui/seek-indicator 2.59 kB
/ui/slider 2.48 kB
/ui/status-announcer 2.31 kB
/ui/status-indicator 2.43 kB
/ui/thumbnail 2.50 kB
/ui/time 2.21 kB
/ui/time-slider 2.46 kB
/ui/tooltip 3.07 kB
/ui/volume-indicator 2.40 kB
/ui/volume-slider 2.56 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core

Path Base initial PR initial Diff % Lazy
. 10.56 kB 11.33 kB +785 B +7.3% 🔺
/i18n 2.66 kB 2.99 kB +344 B +12.6% -4.08 kB 🔴
/i18n/text/airplay 101 B 🆕
/i18n/text/buttons 137 B 🆕
/i18n/text/captions 93 B 🆕
/i18n/text/cast 114 B 🆕
/i18n/text/common 90 B 🆕
/i18n/text/errors 277 B 🆕
/i18n/text/fullscreen 98 B 🆕
/i18n/text/live 126 B 🆕
/i18n/text/menu 249 B 🆕
/i18n/text/pip 101 B 🆕
/i18n/text/playback 80 B 🆕
/i18n/text/seek 105 B 🆕
/i18n/text/slider 65 B 🆕
/i18n/text/status 179 B 🆕
/i18n/text/time 214 B 🆕
/i18n/text/volume 133 B 🆕
Entries (84)
Entry Initial Lazy
. 11.33 kB
/dom 17.67 kB
/dom/media/custom-media-element 2.09 kB
/dom/media/dash 208.97 kB
/dom/media/google-cast 4.03 kB
/dom/media/hls-js 136.02 kB
/dom/media/media-host 1.25 kB
/dom/media/media-played-ranges 576 B
/dom/media/mux 159.44 kB
/dom/media/native-hls 3.07 kB
/dom/media/simple-hls 18.93 kB
/dom/media/simple-hls-audio-only 16.86 kB
/dom/media/vimeo 9.87 kB
/media/predicate 563 B
/i18n 2.99 kB 50.16 kB
/i18n/locales/all 30.51 kB
/i18n/locales/ar 1.11 kB
/i18n/locales/az 1.01 kB
/i18n/locales/bg 1.17 kB
/i18n/locales/bn 1.20 kB
/i18n/locales/bs 926 B
/i18n/locales/ca 988 B
/i18n/locales/cs 978 B
/i18n/locales/cy 948 B
/i18n/locales/da 918 B
/i18n/locales/de 1023 B
/i18n/locales/el 1.37 kB
/i18n/locales/en 707 B
/i18n/locales/es 925 B
/i18n/locales/et 995 B
/i18n/locales/eu 939 B
/i18n/locales/fa 1.11 kB
/i18n/locales/fi 970 B
/i18n/locales/fr 1001 B
/i18n/locales/gd 1.00 kB
/i18n/locales/gl 929 B
/i18n/locales/he 1.03 kB
/i18n/locales/hi 1.21 kB
/i18n/locales/hr 948 B
/i18n/locales/hu 1019 B
/i18n/locales/it 958 B
/i18n/locales/ja 1.10 kB
/i18n/locales/ko 1.04 kB
/i18n/locales/lv 1012 B
/i18n/locales/mr 1.21 kB
/i18n/locales/nb 908 B
/i18n/locales/ne 1.20 kB
/i18n/locales/nl 934 B
/i18n/locales/nn 913 B
/i18n/locales/oc 999 B
/i18n/locales/pl 1.03 kB
/i18n/locales/pt 955 B
/i18n/locales/pt-BR 955 B
/i18n/locales/pt-PT 914 B
/i18n/locales/ro 996 B
/i18n/locales/ru 1.24 kB
/i18n/locales/sk 1018 B
/i18n/locales/sl 960 B
/i18n/locales/sr 989 B
/i18n/locales/sv 935 B
/i18n/locales/te 1.22 kB
/i18n/locales/th 1.19 kB
/i18n/locales/tr 1003 B
/i18n/locales/uk 1.27 kB
/i18n/locales/vi 1006 B
/i18n/locales/zh 947 B
/i18n/locales/zh-CN 947 B
/i18n/locales/zh-TW 949 B
/i18n/text/airplay 101 B
/i18n/text/buttons 137 B
/i18n/text/captions 93 B
/i18n/text/cast 114 B
/i18n/text/common 90 B
/i18n/text/errors 277 B
/i18n/text/fullscreen 98 B
/i18n/text/live 126 B
/i18n/text/menu 249 B
/i18n/text/pip 101 B
/i18n/text/playback 80 B
/i18n/text/seek 105 B
/i18n/text/slider 65 B
/i18n/text/status 179 B
/i18n/text/time 214 B
/i18n/text/volume 133 B
🏷️ @videojs/element — no changes
Entries (2)
Entry Initial
. 996 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Initial
. 1.39 kB
/html 696 B
/react 361 B
🔧 @videojs/utils — no changes
Entries (12)
Entry Initial
/array 104 B
/dom 2.74 kB
/events 319 B
/function 327 B
/jwt 176 B
/object 505 B
/predicate 265 B
/percent 281 B
/string 239 B
/style 190 B
/time 813 B
/number 158 B
📦 @videojs/spf — no changes
Entries (4)
Entry Initial
. 4.46 kB
/dom 6.48 kB
/hls 17.84 kB
/background-video 13.27 kB

ℹ️ How to interpret

JS sizes are initial static graph totals (minified + brotli). Lazy dynamic chunks are shown separately when present.

Icon Meaning
No change
🔺 Increased ≤ 10%
🔴 Increased > 10%
🔽 Decreased
🆕 New (no baseline)

Run pnpm size locally to check current initial sizes.

Comment thread packages/core/src/core/i18n/locales/en.ts
Comment thread packages/core/src/core/ui/airplay-button/airplay-button-core.ts Outdated
Comment thread packages/core/src/core/i18n/translator.ts Outdated
Comment thread packages/core/src/core/i18n/resolve-text.ts Outdated
Comment thread packages/core/src/core/i18n/text/airplay.ts Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will drift, shouldn't this just import and use the values defined in i18n/text?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text modules are generated from this file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I missed the comment at the top. Sounds good. Maybe we can make that shout more that the file is auto-generated?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, do we have a standard header we can add perhaps? It's only a small line currently. I'll make it more obvious.

Comment thread packages/core/src/core/i18n/flatten.ts Outdated
Comment thread packages/core/src/core/i18n/types.ts Outdated
Comment thread packages/core/src/core/ui/input-feedback/labels.ts Outdated
Comment thread packages/html/src/ui/menu/menu-back-element.ts Outdated
Comment thread packages/react/src/presets/audio/minimal-skin.tailwind.tsx Outdated
Comment thread packages/core/src/core/i18n/locales/ar.ts
Comment thread packages/react/src/ui/menu/menu-back.tsx Outdated
Comment thread packages/utils/src/object/flatten.ts Outdated
Comment thread packages/react/src/ui/menu/menu-back.tsx Outdated
Comment thread packages/core/scripts/generate-i18n-types.ts Outdated

@mihar-22 mihar-22 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for resolving all of my comments, this looks great!

Comment thread packages/core/src/core/ui/live-button/live-button-core.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit eb5024e. Configure here.

Comment thread packages/html/src/ui/time/time-element.ts Outdated
@sampotts
sampotts merged commit a3e673b into main Jul 28, 2026
27 checks passed
@sampotts
sampotts deleted the feat/i18n-keys branch July 28, 2026 06:46
@luwes luwes mentioned this pull request Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants