---
title: ProviderMixin
description: Mixin that creates the player store and manages the full media attach lifecycle
---

import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import DocsLink from "@/components/docs/DocsLink.astro";

`ProviderMixin` creates a class that owns the player store and the media attach lifecycle. It publishes the store to context so descendants can consume it, and calls `store.attach()` when both a media element and a container are available.

### Store lifecycle

The store is created when the element is constructed. On `connectedCallback`, the mixin publishes three context values to its descendants:

{/* TODO: link context keys to concept page once written (https://github.com/videojs/v10/issues/1033) */}
- **`playerContext`** — the store, consumed by <DocsLink slug="reference/player-controller">`PlayerController`</DocsLink> and other controllers
- **`mediaContext`** — a setter callback for media elements to register themselves
- **`containerContext`** — a setter callback for container elements to register themselves

When a media element and a container both register, the provider calls `store.attach({ media, container })`. If no media element registers via context within a [microtask](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide), the provider falls back to `querySelector('video, audio')` to support plain `<video>` and `<audio>` elements.

{/* TODO: link destroyCallback to lifecycle reference once written (https://github.com/videojs/v10/issues/1034) */}
On `disconnectedCallback`, the mixin detaches the current media target but keeps the store alive. An element moved in the DOM reconnects without losing state. The store is destroyed in `destroyCallback`.

### When to split provider and container

Use `ProviderMixin` separate from <DocsLink slug="reference/container-mixin">`ContainerMixin`</DocsLink> when the store owner is a different element from the container:

```ts
const { ProviderMixin, ContainerMixin } = createPlayer({ features: videoFeatures });

// Layout shell owns the store
class AppShell extends ProviderMixin(MediaElement) {}

// Content region is the fullscreen target and container reference
class VideoRegion extends ContainerMixin(MediaElement) {}
```

When a single element handles both responsibilities, compose the mixins directly:

```ts
const { ProviderMixin, ContainerMixin } = createPlayer({ features: videoFeatures });

class VideoPlayer extends ProviderMixin(ContainerMixin(MediaElement)) {}
```

<UtilReference util="ProviderMixin" />
