docs(site): document self-hosted and offline player builds#1680
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Deploy Preview for vjs10-site ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
@R-Delfino95 is attempting to deploy a commit to the Mux Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
decepulis
left a comment
There was a problem hiding this comment.
imo this should be its own guide. I don't know if we want every user thinking about self-hosting.
Either that or a tab alongside cdn/npm/etc.
| ## Self-host the player | ||
|
|
||
| The CDN tab loads the player from a public CDN. For offline, air-gapped, or locked-down deployments, you can serve everything from your own origin instead. Pick one of the options below. | ||
|
|
||
| <FrameworkCase frameworks={["html"]}> | ||
|
|
||
| ### Bundle a single file (recommended) | ||
|
|
||
| Install the package, put the JavaScript imports from the **Use your player** step above into an entry file, then let any bundler produce one self-contained module you can host anywhere. For the default video player that's: | ||
|
|
||
| ```js title="player.js" | ||
| import '@videojs/html/video/player'; | ||
| import '@videojs/html/video/skin'; | ||
| ``` | ||
|
|
||
| ```bash | ||
| npm install @videojs/html | ||
| npx esbuild player.js --bundle --format=esm --minify --sourcemap --outfile=public/player.js | ||
| ``` | ||
|
|
||
| Load the output with `type="module"`, the same as the CDN path: | ||
|
|
||
| ```html | ||
| <script type="module" src="/player.js"></script> | ||
| ``` | ||
|
|
||
| You get one file (plus a sourcemap), no runtime requests to a CDN, and only the features you import. Any bundler works (Vite, Rollup, webpack) as long as the output stays ESM. | ||
|
|
||
| ### Mirror the prebuilt CDN files | ||
|
|
||
| To skip the bundler, copy the prebuilt CDN bundle to your server as-is. | ||
|
|
||
| <Aside type="caution" title="Copy the whole cdn/ directory"> | ||
| The CDN entry files like `video.js` and `media/hls-video.js` are not standalone. They import shared, content-hashed chunks (`default-*.js`, `ui-*.js`, and more) that live alongside them. Copying a single file breaks at runtime, so mirror the entire `cdn/` directory and keep its layout intact. | ||
| </Aside> | ||
|
|
||
| ```bash | ||
| npm install @videojs/html | ||
| mkdir -p public | ||
| cp -r node_modules/@videojs/html/cdn public/videojs | ||
| ``` | ||
|
|
||
| Then point the script tag at your copy instead of the CDN: | ||
|
|
||
| ```html | ||
| <script type="module" src="/videojs/video.js"></script> | ||
| ``` | ||
|
|
||
| The file name matches your selection: the CDN tab above generated it (for example `video.js`, `audio.js`, or `background.js`). Every option is present in the `cdn/` folder you copied. | ||
|
|
||
| Hashed chunk names change between releases, so re-copy the directory whenever you upgrade `@videojs/html`. | ||
|
|
||
| ### HLS and other media types | ||
|
|
||
| HLS and other non-default media need their own module on top of the player, the same way the **Use your player** step adds it to the generated imports. Match it in your self-hosted build: | ||
|
|
||
| - **Bundle:** add the media import to your entry file (`import '@videojs/html/media/hls-video';`) and use the matching `<hls-video>` element with your `.m3u8` source. | ||
| - **Mirror:** serve the media file too and add its script tag (`<script type="module" src="/videojs/media/hls-video.js"></script>`). | ||
|
|
||
| Without the media module the player UI renders but the video never loads, with no console error. | ||
|
|
||
| </FrameworkCase> | ||
|
|
||
| <FrameworkCase frameworks={["react"]}> | ||
|
|
||
| Your bundler includes `@videojs/react` in your app like any other dependency, so your production build already serves the player from your own origin with no CDN or runtime fetches. Offline and self-hosted deployments need no extra steps. | ||
|
|
||
| </FrameworkCase> | ||
|
|
There was a problem hiding this comment.
This isn't really providing any information to react devs. I don't think we should even show this information to react readers.
Let's make this an HTML-only section.
Or, if we spin this out to its own guide, let's make it an HTML-only guide.
There was a problem hiding this comment.
You are right, I reviewed it and it looks much better if we create a separate section in the HTML how-to.
I have already made the changes!
Closes #1637
Summary
Add a dedicated "Self-host the player" guide (HTML-only) for serving the player without a public CDN.
Validation
video.jsplus all shared chunks from localhost (no 404s).frameworks: ['html']), so it shows for HTML readers only — not React.Out of scope (separate follow-ups)
Surfaced while investigating but intentionally not part of this docs change:
bundledDependenciesso the npm tarball is self-sufficient.Note
Low Risk
Documentation-only changes with no runtime or API impact.
Overview
Adds an HTML-only Self-host the player how-to that explains serving
@videojs/htmlwithout a public CDN, for offline, air-gapped, or restricted networks.The guide covers bundling a single ESM file (recommended entry imports + esbuild example) and mirroring the full
node_modules/@videojs/html/cdntree, with a caution that CDN entry scripts depend on hashed shared chunks. It also documents loading extra media modules (e.g. HLS) for both approaches.The page is registered in
docs.config.tsunder How to withframeworks: ['html'], and the installation guide’s See also section links to it for the HTML framework view only.Reviewed by Cursor Bugbot for commit 3e9a8d2. Bugbot is set up for automated code reviews on this repo. Configure here.