From 964d9ca1d767c3512cf139fdb5aac597df2441fe Mon Sep 17 00:00:00 2001 From: Renzo Delfino <75499398+R-Delfino95@users.noreply.github.com> Date: Thu, 18 Jun 2026 14:48:22 -0300 Subject: [PATCH] docs(site): document self-hosted and offline player builds (#1680) --- site/src/content/docs/how-to/installation.mdx | 4 ++ .../docs/how-to/self-host-the-player.mdx | 64 +++++++++++++++++++ site/src/docs.config.ts | 6 +- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 site/src/content/docs/how-to/self-host-the-player.mdx diff --git a/site/src/content/docs/how-to/installation.mdx b/site/src/content/docs/how-to/installation.mdx index 05429e1e..93763cef 100644 --- a/site/src/content/docs/how-to/installation.mdx +++ b/site/src/content/docs/how-to/installation.mdx @@ -211,6 +211,10 @@ Content-Security-Policy: Skins + +Self-host the player + + ---- That's it! You now have a fully functional Video.js player. Go forth and play. diff --git a/site/src/content/docs/how-to/self-host-the-player.mdx b/site/src/content/docs/how-to/self-host-the-player.mdx new file mode 100644 index 00000000..e21414b9 --- /dev/null +++ b/site/src/content/docs/how-to/self-host-the-player.mdx @@ -0,0 +1,64 @@ +--- +title: Self-host the player +description: Serve the Video.js HTML player from your own origin for offline, air-gapped, or restricted-network deployments +--- + +import Aside from '@/components/Aside.astro'; +import DocsLink from '@/components/docs/DocsLink.astro'; + +By default, the installation flow 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. + +## Bundle a single file (recommended) + +Install the package, put the player's imports 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"`: + +```html + +``` + +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. + + + +```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 + +``` + +The file name matches your player: `video.js`, `audio.js`, `background.js`, and so on. 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. 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 `` element with your `.m3u8` source. +- **Mirror:** serve the media file too and add its script tag (``). + +Without the media module the player UI renders but the video never loads, with no console error. diff --git a/site/src/docs.config.ts b/site/src/docs.config.ts index 333e2f24..c299efaf 100644 --- a/site/src/docs.config.ts +++ b/site/src/docs.config.ts @@ -46,7 +46,11 @@ export const sidebar: Sidebar = [ sidebarLabel: 'How to', llmsDescription: 'Task-oriented guides with step-by-step instructions to achieve a specific outcome by applying one or more concepts. Each guide may assume you already understand the relevant concepts.', - contents: [{ slug: 'how-to/customize-skins' }, { slug: 'how-to/build-your-own-component' }], + contents: [ + { slug: 'how-to/customize-skins' }, + { slug: 'how-to/build-your-own-component' }, + { slug: 'how-to/self-host-the-player', frameworks: ['html'] }, + ], }, { sidebarLabel: 'Components',