Skip to content
FrameworkStyle

Add a poster and loading placeholder

Set the image shown before playback, then add a lightweight placeholder while it loads

A poster is the image shown before your video plays. Set one on the player. If it loads slowly, add a small placeholder so the player does not start as empty space.

Set a poster

Set the player’s poster to an image URL:

import '@videojs/react/video/skin.css';
import { Video, VideoPlayer, VideoSkin } from '@videojs/react/video';

export function MyPlayer() {
  return (
    <VideoPlayer poster="/poster.jpg">
      <VideoSkin>
        <Video src="/video.mp4" playsInline />
      </VideoSkin>
    </VideoPlayer>
  );
}

If you use a ready-made skin, it includes Poster and shows the image automatically. If you build your own UI, add Poster yourself. It hides after the user plays or seeks.

Posters are decorative by default, with an empty alt. If the image communicates something that is not available elsewhere, add alt text when you customize the poster image.

Add a loading placeholder

A placeholder is a tiny preview that appears while the poster downloads. Keep it small enough to include with the page, such as a short data URL.

Use your framework’s image component

If you use VideoSkin, pass your framework’s image component to renderPoster. Video.js passes the poster URL as src.

import '@videojs/react/video/skin.css';
import { Video, VideoPlayer, VideoSkin } from '@videojs/react/video';
import NextImage from 'next/image';

export function MyPlayer() {
  return (
    <VideoPlayer poster="/poster.jpg">
      <VideoSkin
        renderPoster={({ src, ...props }) =>
          src ? (
            <NextImage
              {...props}
              src={src}
              alt=""
              fill
              placeholder="blur"
              blurDataURL="data:image/webp;base64,…"
            />
          ) : null
        }
      >
        <Video src="/video.mp4" playsInline />
      </VideoSkin>
    </VideoPlayer>
  );
}

Next.js generates blur data for static imports. Here, the poster URL arrives while the player runs, so provide blurDataURL yourself.

Use a plain image

For more control, add the placeholder as a background on the image that VideoSkin draws:

import '@videojs/react/video/skin.css';
import { Video, VideoPlayer, VideoSkin } from '@videojs/react/video';

export function MyPlayer() {
  return (
    <VideoPlayer poster="/poster.jpg">
      <VideoSkin
        renderPoster={(props) => (
          <img
            {...props}
            style={{
              ...props.style,
              background:
                "url('data:image/webp;base64,…') var(--media-object-position, center) / contain no-repeat",
            }}
          />
        )}
      >
        <Video src="/video.mp4" playsInline />
      </VideoSkin>
    </VideoPlayer>
  );
}

The examples use contain for both images. Use cover for both when the poster should fill the player. Keeping the same size and position prevents the image from jumping when the poster appears.

Let the media choose a poster

Some media components choose a poster for you. For example, MuxVideo creates one from its playback ID:

import '@videojs/react/video/skin.css';
import { MuxVideo } from '@videojs/react/media/mux-video';
import { VideoPlayer, VideoSkin } from '@videojs/react/video';

export function MyPlayer() {
  return (
    <VideoPlayer>
      <VideoSkin>
        <MuxVideo
          source={{
            playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
            poster: { time: 2 },
          }}
          playsInline
        />
      </VideoSkin>
    </VideoPlayer>
  );
}

When the player and media component both choose a poster, the player’s poster wins. See Metadata for how the player combines those values.

Add a poster to your own UI

When your UI already includes Poster, apply the same placeholder directly:

<Poster
  render={(props) => (
    <img
      {...props}
      style={{
        ...props.style,
        background:
          "url('data:image/webp;base64,…') var(--media-object-position, center) / contain no-repeat",
      }}
    />
  )}
/>

Troubleshooting

No poster appears

Check that the player has a poster or that the media component can create one from its source.

The final poster never appears

Pass the src from renderPoster to your image. If your image component requires a source, return null until src is available.

The placeholder and poster use different crops

Use the same fit for both images: pair background-size: contain with object-fit: contain, or use cover for both.

The placeholder adds too much page weight

Use fewer pixels and stronger compression. The placeholder only needs to suggest the poster’s color and shape until the full image appears.