Skip to content
FrameworkStyle

Poster

Poster image component that displays a thumbnail until video playback starts

Import

import { Poster } from '@videojs/react';

Anatomy

<Poster.Root>
  <Poster.Image />
</Poster.Root>

Behavior

The poster shows before playback starts. Once the user plays or seeks, it hides; pausing does not bring it back. Loading a new source shows it again.

You can set the poster URL on the player. This is useful when you want to change the poster from inside a skin, or keep all your media metadata in one place:

<VideoPlayer poster="poster.jpg" />

Supply your own image

The component fills in a source only when you leave one out. srcset, sizes, loading, <picture>, and framework image components all stay available.

Poster.Root owns visibility and loading state. Image attributes go on Poster.Image:

<Poster.Root>
  <Poster.Image srcSet="poster-480.jpg 480w, poster-1080.jpg 1080w" sizes="100vw" />
</Poster.Root>

To render a different image component, use render on Poster.Image. It receives the poster URL as src, undefined until one resolves:

<Poster.Root>
  <Poster.Image
    render={({ src, ...props }: ComponentProps<'img'>) =>
      src ? <Image {...props} src={src} alt="" fill /> : null
    }
  />
</Poster.Root>

Inside a skin, pass the same function as renderPoster. The skin draws your image in place of its own:

<VideoSkin
  renderPoster={({ src, ...props }: ComponentProps<'img'>) =>
    src ? <Image {...props} src={src} alt="" fill /> : null
  }
/>

A skin styles the <img> it draws directly. Render something that is not an <img> and its sizing is yours.

Styling

Attribute Values Description
data-visible Present / absent Present before playback starts
data-loading Present / absent Present while the image is fetching
data-loaded Present / absent Present once the image has loaded
data-error Present / absent Present when the image failed

The three load attributes track the image on screen, including one you supplied yourself.

React renders a root <div> around the <img>. The state attributes are on Poster.Root, so other presentation layers can use the same lifecycle:

<Poster.Root className="media-poster">
  <img className="media-poster-blur" src={blurDataURL} alt="" aria-hidden />
  <Poster.Image className="media-poster-image" />
  <div className="media-poster-overlay" aria-hidden />
</Poster.Root>
.media-poster:not([data-visible]) {
  opacity: 0;
}

.media-poster:not([data-loading]) .media-poster-blur {
  opacity: 0;
}

Accessibility

Unlike the native <video poster> attribute, this component lets you describe the poster for screen readers.

The image is decorative by default (alt=""), since a URL says nothing about what the image shows. When the poster carries meaning, say so:

<Poster.Root>
  <Poster.Image alt="Keynote speaker at a conference" />
</Poster.Root>

Whether a poster is informative or decorative is your judgment, per the WAI guidelines.

Examples

Basic Usage

import { Container, createPlayer, PlayButton, Poster } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';

const { Player } = createPlayer({ features: videoFeatures });

export default function BasicUsage() {
  return (
    <Player poster="https://image.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/thumbnail.jpg">
      <Container className="media-container">
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" playsInline />

        <Poster.Root className="media-poster">
          <Poster.Image className="media-poster-image" />
        </Poster.Root>

        <PlayButton
          className="media-play-button"
          render={(props, state) => <button {...props}>{state.paused ? 'Play' : 'Pause'}</button>}
        />
      </Container>
    </Player>
  );
}

API Reference

Root

Manages poster visibility and image loading state.

Renders a div and exposes data-visible, data-loading, data-loaded, and data-error for styling every layer in the poster presentation. Render Poster.Image inside it for the image that supplies the loading lifecycle.

State

State is accessible via the render, className, and style props.

PropertyTypeDetails
visibleboolean
srcstring
loadingboolean
loadedboolean
errorboolean

Data attributes

AttributeTypeDetails
data-visible
data-loading
data-loaded
data-error

Image

Displays the poster image managed by Poster.Root.

Renders an img, so srcSet, sizes, loading, and the rest of the native image attributes remain available. Leave the source off and the player's resolved poster fills it in. The image is decorative unless you supply alt.

Props

PropTypeDefaultDetails
classNamestring | ((state: PosterCore.State) => string | undefined)
renderReactElement | ((props: HTMLProps, state: PosterCore.State) => ReactElement | null)
styleCSSProperties | ((state: PosterCore.State) => CSSProperties | undefined)