# CDN

Understand the browser-ready bundles, stylesheets, and URL layout published by the Video.js CDN

Start with the [CDN Installation Guide](./installation-cdn.md) to load Video.js and add a working player. This guide documents the browser-ready files the CDN serves and the layout rules behind their URLs.

## CDN URLs

Every file the CDN serves follows one URL pattern:

```plaintext
https://cdn.jsdelivr.net/npm/@videojs/cdn@<version>/<file>
```

> **Caution: Pin all your CDN URLs to the same version.**
>
> Bundles share content-hashed chunks that change between releases. A tag like `@latest` re-resolves over time, so two files might come from different releases and load duplicate modules that no longer share state.

## Player bundles

Each installation [preset](./presets.md) ships its bundles at the package root: one per skin choice, plus a player-only bundle. For the video preset:

| File | Registers |
| --- | --- |
| `video.js` | `<video-player>`, `<video-skin>`, and the UI elements the skin composes |
| `video-minimal.js` | `<video-player>`, `<video-minimal-skin>`, and the UI elements the minimal skin composes |
| `video-player.js` | `<video-player>` alone, for markup without a packaged skin |

The other presets follow the same pattern. Background video is the exception: one bundle, `background.js`, registers the player, the skin, and the `<background-video>` media element.

A skin bundle registers every UI element its skin is built from. Any element the skin does not compose is its own bundle under `ui/`.

## UI element bundles

Each [UI element](./ui-components.md) is its own bundle under `ui/`, for markup that a skin bundle does not already cover: a player-only bundle, [skin source](./customize-skins.md#style-skin-source) that adds a component the packaged skin lacks, or a [dialog](../reference/components/dialog.md) your page opens beside a packaged skin.

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/video-player.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/ui/play-button.js"></script>
```

Each path mirrors its npm subpath: `ui/play-button.js` registers the element that `@videojs/html/ui/play-button` does. Compound components list one bundle per part in their reference page’s Import section, and all of the bundles share chunks with the player.

## Media bundles

The default presets play through the browser’s own `<video>` and `<audio>`. Every other [media element](./media-sources.md) is its own bundle under `media/`, loaded beside the player bundle:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/video.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/media/hlsjs-video.js"></script>
```

Each path mirrors its npm subpath. Elements with more than one playback engine keep the extra flavors in a directory named for the element, such as `media/mux-video/spf.js`. Load one flavor per page: every flavor claims the same tag name, and the first registration wins.

## Extension bundles

Each [extension](./architecture.md) is its own bundle under `extensions/`, loaded beside the player and media bundles:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/video.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/media/mux-video.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/extensions/mux-data.js"></script>
```

As with media, each path mirrors its npm subpath: `extensions/mux-data.js` registers the element that `@videojs/html/extensions/mux-data` does.

## Locales

English ships inside the skin bundles. Each other locale is a bundle under `locales/` that registers its translations on import. Load it before the player script to avoid a flash of English:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/locales/es.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/video.js"></script>
```

One bundle exists per locale pack, plus bare-language aliases such as `pt`. For custom strings, see [Internationalize the player](./internationalization.md).

## Stylesheets

The skin bundles inline their CSS, so no `<link>` is required to render. The separate `.css` files do the jobs a bundle cannot:

- `global.css` holds the light-DOM rules. Link it in `<head>` and the player reserves its space before the elements upgrade. The background preset uses `background.css` instead.
- The skin sheets, such as `video.css` beside `video.js`, style declaratively rendered skins.
- `shadow.css` holds the shadow-root integration rules that hand-written shadow skins build on.

[Self-host the player](./self-hosting.md) shows both in use.

## Development bundles

Every JavaScript entry has a `.dev.js` sibling, such as `video.dev.js`, built with development warnings on. Swap the suffix while debugging; swap it back to ship.

## Shared chunks

Everything else at the root, including content-hashed files such as `adapter-<hash>.js`, is a shared chunk the entries import by relative path. Entries share these chunks, so loading several bundles stays cheap. Chunk names change every release: never link a chunk directly, and never copy a lone entry file. To mirror the CDN, copy the whole package directory and keep its layout; [Self-host the player](./self-hosting.md) covers it.

## Related pages

### Guides

- [CDN Installation Guide](./installation-cdn.md): Load Video.js from jsDelivr and build an HTML video player without installing Video.js packages
- [Self-host the player](./self-hosting.md): Serve the Video.js HTML player from your own origin for offline, air-gapped, or restricted-network deployments
- [Internationalize the player](./internationalization.md): Translate player labels and announcements: shipped locale packs, custom translations, runtime switching, and server rendering.