Skip to content

feat(site): add media element API reference pages#1342

Open
decepulis wants to merge 11 commits intomainfrom
claude/refine-local-plan-ClRzU
Open

feat(site): add media element API reference pages#1342
decepulis wants to merge 11 commits intomainfrom
claude/refine-local-plan-ClRzU

Conversation

@decepulis
Copy link
Copy Markdown
Collaborator

@decepulis decepulis commented Apr 14, 2026

Summary

  • Wire generateMediaElementReferences() into the api-docs builder so pnpm api-docs generates JSON for 6 media elements (hls-video, dash-video, mux-video, mux-audio, native-hls-video, simple-hls-video)
  • Add MediaReference.astro rendering component with Host Properties table, Native Attributes, Events, CSS Custom Properties (reuses ApiCSSVarsTable), and Slots sections
  • Create 7 reference pages: 6 auto-generated via <MediaReference> + background-video (hand-authored)
  • Add "Media Elements" sidebar section between Components and Hooks & Utilities
  • Add BasicUsage demos (HTML + React) for all 7 elements

Closes #1253

Test plan

  • pnpm api-docs generates 6 JSON files in generated-media-reference/
  • pnpm typecheck passes
  • pnpm -F site test — 374 tests pass
  • pnpm check:workspace — 6/6 checks pass
  • Verify all 7 pages render correctly in both HTML and React framework tabs via pnpm dev
  • Verify sidebar shows "Media Elements" section in correct position
  • Verify TOC headings appear for API Reference sections

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ


Note

Medium Risk
Medium risk because it changes the docs generation pipeline (api-docs-builder) and TOC heading injection logic, which could break site builds or navigation if the generated JSON/schema or heading IDs drift.

Overview
Adds first-class media element API reference support to the docs site.

The api-docs-builder now generates and schema-validates media element reference JSON into a new generated-media-reference/ output, which is wired into astro:content via a new mediaReference collection and ignored in .gitignore.

Introduces a MediaReference.astro renderer (including a MediaHostPropsTable) plus a mediaReferenceModel and updates remarkConditionalHeadings so <MediaReference media="..." /> injects API Reference headings into the page TOC.

Adds a new “Media Elements” sidebar section and new reference pages/demos for background-video (hand-authored) and streaming elements (dash-video, hls-video, mux-audio, mux-video, native-hls-video, simple-hls-video), with React demos currently commented out on several pages due to SSR import issues.

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

claude added 4 commits April 14, 2026 22:11
Add generateMediaElementReferences() to the builder entry point so
`pnpm api-docs` generates JSON for media elements (hls-video, dash-video,
mux-video, mux-audio, native-hls-video, simple-hls-video). Register a
new mediaReference content collection in Astro with a Zod schema matching
the pipeline output.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
Create MediaReference.astro that loads generated media element JSON and
renders Host Properties, Native Attributes, Events, CSS Custom Properties,
and Slots sections. Add mediaReferenceModel.js for shared heading/id
computation. Wire into remarkConditionalHeadings for table-of-contents
injection.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
Create 7 MDX reference pages: hls-video, dash-video, native-hls-video,
simple-hls-video, mux-video, mux-audio (auto-generated via MediaReference),
and background-video (hand-authored tables). Add "Media Elements" sidebar
section between Components and Hooks & Utilities.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
Add BasicUsage demos (HTML + React) for hls-video, dash-video,
native-hls-video, simple-hls-video, mux-video, mux-audio, and
background-video. Wire demos into each MDX page using FrameworkCase
and StyleCase components.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 14, 2026

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

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Apr 30, 2026 4:44pm

Request Review

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 14, 2026

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit ef5aa9d
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/69f386fd14fad00008511f2d
😎 Deploy Preview https://deploy-preview-1342--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.

The React media components (`@videojs/react/media/*`) import from
`@videojs/core/dom/media/*` which top-level imports dashjs/hls.js —
libraries that access `window` at module load time. This crashes
Astro's SSR prerender. Remove all demos until the underlying SSR
issue is resolved.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
claude added 3 commits April 29, 2026 14:34
…lan-ClRzU

# Conflicts:
#	.gitignore
#	site/scripts/api-docs-builder/src/index.ts
#	site/src/content.config.ts
#	site/src/utils/remarkConditionalHeadings.js
Add BasicUsage demos (HTML + React) for hls-video, dash-video,
native-hls-video, simple-hls-video, mux-video, mux-audio, and
background-video. Wire demos into each MDX page.

Note: React demos currently break the SSR build due to #1343
(top-level hls.js/dashjs imports access `window`). This branch
is parked until that issue is resolved.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
The React demos for HLS, DASH, Mux, NativeHLS, and SimpleHLS media
elements import from @videojs/react/media/* which chains into top-level
hls.js/dashjs imports that access `window` at module evaluation time,
breaking Astro's SSR prerender. HTML demos and background-video React
demo are unaffected.

Refs #1343

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Size
/video (default) 28.81 kB
/video (default + hls) 162.20 kB
/video (minimal) 26.29 kB
/video (minimal + hls) 159.64 kB
/audio (default) 26.67 kB
/audio (minimal) 24.24 kB
/background 4.16 kB
Media (8)
Entry Size
/media/background-video 1.04 kB
/media/container 1.72 kB
/media/dash-video 236.58 kB
/media/hls-video 134.69 kB
/media/mux-audio 160.91 kB
/media/mux-video 160.85 kB
/media/native-hls-video 4.62 kB
/media/simple-hls-video 16.01 kB
Players (3)
Entry Size
/video/player 7.00 kB
/audio/player 5.12 kB
/background/player 3.86 kB
Skins (29)
Entry Type Size
/video/minimal-skin.css css 3.54 kB
/video/skin.css css 3.57 kB
/video/minimal-skin js 26.27 kB
/video/minimal-skin.tailwind js 26.49 kB
/video/skin js 28.81 kB
/video/skin.tailwind js 28.89 kB
/audio/minimal-skin.css css 2.55 kB
/audio/skin.css css 2.51 kB
/audio/minimal-skin js 24.22 kB
/audio/minimal-skin.tailwind js 24.38 kB
/audio/skin js 26.66 kB
/audio/skin.tailwind js 26.78 kB
/background/skin.css css 115 B
/background/skin js 1.15 kB
/live-video/minimal-skin.css css 3.54 kB
/live-video/skin.css css 3.57 kB
/live-video/minimal-skin js 26.05 kB
/live-video/minimal-skin.tailwind js 26.12 kB
/live-video/skin js 28.54 kB
/live-video/skin.tailwind js 28.56 kB
/live-audio/minimal-skin.css css 2.55 kB
/live-audio/skin.css css 2.51 kB
/live-audio/minimal-skin js 24.05 kB
/live-audio/minimal-skin.tailwind js 24.01 kB
/live-audio/skin js 26.43 kB
/live-audio/skin.tailwind js 26.47 kB
/base.css css 162 B
/shared.css css 88 B
/skin-element js 1.35 kB
UI Components (25)
Entry Size
/ui/alert-dialog 989 B
/ui/alert-dialog-close 465 B
/ui/alert-dialog-description 451 B
/ui/alert-dialog-title 369 B
/ui/buffering-indicator 2.49 kB
/ui/captions-button 2.59 kB
/ui/cast-button 2.62 kB
/ui/compounds 4.15 kB
/ui/controls 2.03 kB
/ui/error-dialog 3.10 kB
/ui/fullscreen-button 2.58 kB
/ui/hotkey 1.91 kB
/ui/mute-button 2.58 kB
/ui/pip-button 2.55 kB
/ui/play-button 2.56 kB
/ui/playback-rate-button 2.67 kB
/ui/popover 1.82 kB
/ui/poster 1.88 kB
/ui/seek-button 2.59 kB
/ui/slider 1.51 kB
/ui/thumbnail 2.96 kB
/ui/time 2.52 kB
/ui/time-slider 3.92 kB
/ui/tooltip 2.03 kB
/ui/volume-slider 2.66 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Size
/video (default) 23.53 kB
/video (default + hls) 155.68 kB
/video (minimal) 21.14 kB
/video (minimal + hls) 153.27 kB
/audio (default) 19.10 kB
/audio (minimal) 17.62 kB
/background 756 B
Media (7)
Entry Size
/media/background-video 575 B
/media/dash-video 235.21 kB
/media/hls-video 133.34 kB
/media/mux-audio 159.31 kB
/media/mux-video 159.49 kB
/media/native-hls-video 3.13 kB
/media/simple-hls-video 14.55 kB
Skins (26)
Entry Type Size
/video/minimal-skin.css css 3.48 kB
/video/skin.css css 3.50 kB
/video/minimal-skin js 21.05 kB
/video/minimal-skin.tailwind js 24.58 kB
/video/skin js 23.46 kB
/video/skin.tailwind js 24.69 kB
/audio/minimal-skin.css css 2.45 kB
/audio/skin.css css 2.40 kB
/audio/minimal-skin js 17.57 kB
/audio/minimal-skin.tailwind js 20.05 kB
/audio/skin js 19.03 kB
/audio/skin.tailwind js 20.06 kB
/background/skin.css css 90 B
/background/skin js 272 B
/live-video/minimal-skin.css css 3.48 kB
/live-video/skin.css css 3.50 kB
/live-video/minimal-skin js 17.79 kB
/live-video/minimal-skin.tailwind js 21.19 kB
/live-video/skin js 20.18 kB
/live-video/skin.tailwind js 21.36 kB
/live-audio/minimal-skin.css css 2.45 kB
/live-audio/skin.css css 2.40 kB
/live-audio/minimal-skin js 15.79 kB
/live-audio/minimal-skin.tailwind js 18.04 kB
/live-audio/skin js 17.26 kB
/live-audio/skin.tailwind js 18.21 kB
UI Components (20)
Entry Size
/ui/alert-dialog 1.11 kB
/ui/buffering-indicator 1.85 kB
/ui/captions-button 2.03 kB
/ui/cast-button 2.04 kB
/ui/controls 1.89 kB
/ui/error-dialog 2.31 kB
/ui/fullscreen-button 2.03 kB
/ui/mute-button 2.05 kB
/ui/pip-button 2.03 kB
/ui/play-button 2.00 kB
/ui/playback-rate-button 2.02 kB
/ui/popover 1.87 kB
/ui/poster 1.74 kB
/ui/seek-button 2.10 kB
/ui/slider 3.33 kB
/ui/thumbnail 2.08 kB
/ui/time 2.54 kB
/ui/time-slider 3.00 kB
/ui/tooltip 2.17 kB
/ui/volume-slider 2.39 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (9)
Entry Size
. 4.96 kB
/dom 11.93 kB
/dom/media/custom-media-element 1.90 kB
/dom/media/dash 234.36 kB
/dom/media/google-cast 4.07 kB
/dom/media/hls 132.72 kB
/dom/media/mux 158.81 kB
/dom/media/native-hls 2.52 kB
/dom/media/simple-hls 13.89 kB
🏷️ @videojs/element — no changes
Entries (2)
Entry Size
. 996 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Size
. 1.39 kB
/html 695 B
/react 360 B
🔧 @videojs/utils — no changes
Entries (10)
Entry Size
/array 104 B
/dom 1.92 kB
/events 319 B
/function 327 B
/object 275 B
/predicate 265 B
/string 148 B
/style 190 B
/time 478 B
/number 158 B
📦 @videojs/spf — no changes
Entries (3)
Entry Size
. 4.29 kB
/dom 13.40 kB
/playback-engine 13.26 kB

ℹ️ How to interpret

All sizes are standalone totals (minified + brotli).

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

Run pnpm size locally to check current sizes.

@decepulis
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 1e05bd7. Configure here.

Move custom properties before regular properties per useSortedProperties
rule. Add aspect-ratio: 16/9 to video demos to prevent flat layout
before video loads. Mux-audio excluded (audio element).

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
Switch to the standard BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM
playback ID used by all other demos. Update DASH URL per reviewer
preference. Add predefined height to mux-audio demos to prevent
layout shift.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
Copy link
Copy Markdown
Collaborator Author

I found two docs-generation issues that look worth fixing before this lands:

  1. [P2] Mixin host properties are skipped

    In media-element-handler.ts lines 294-297, host inheritance only follows identifier extends clauses. MuxVideoMedia, MuxAudioMedia, NativeHlsMedia, and SimpleHlsMedia all extend mixin call expressions, so extractHostProperties() stops before HlsMedia, Google Cast, Mux Data, Native HLS, and SPF properties. After running pnpm -F site api-docs, mux-video.json and native-hls-video.json have empty hostProperties, so the new reference pages omit public properties such as castSrc, castReceiver, streamType, liveEdgeStart, and targetLiveWindow.

  2. [P2] Element-specific events are omitted

    In media-element-handler.ts lines 616-619, events are generated once from generic VideoEvents or AudioEvents and reused for every media element. HLS and native HLS hosts also dispatch streamtypechange and targetlivewindowchange, and tests listen for those events, but the generated JSON omits them from the Events section. The media references need to merge element- or host-specific events instead of using only the base media event set.

I tried to leave these as inline review comments, but GitHub would not anchor them because this file is not currently part of the PR diff.

Match the convention used in existing HTML demos (e.g. play-button)
where each attribute is on its own line for readability.

https://claude.ai/code/session_01GLtyequo6D3zqeddxsBjzQ
Copy link
Copy Markdown
Collaborator Author

One docs-content suggestion for the media reference pages: the generated Native Attributes and Events chip lists may be less useful than a short explanation of the forwarding behavior.

For attributes, the accurate statement is not quite “all native attributes are forwarded,” but rather that these elements accept common native media attributes and forward the supported set from CustomMediaElement.properties to the internal <video>/<audio> element. Something like:

Accepts common native media attributes and forwards them to the internal <video> element, including src, controls, autoplay, muted, loop, playsinline, poster, and preload.

For events, the runtime behavior is more useful than the exhaustive list: native media events are re-dispatched from the internal media element, so consumers can listen on the custom element directly. Something like:

el.addEventListener('play', onPlay);
el.addEventListener('timeupdate', onTimeUpdate);

Then list the element-specific events separately, e.g. for HLS/native HLS:

  • streamtypechange
  • targetlivewindowchange

That would probably read better than a large wall of event chips like canplaythrough, loadeddata, emptied, etc., while still being more accurate about what the component actually guarantees.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants