Full-bleed background video seems straightforward until you get into the details: lazy loading for below-fold instances, accessibility considerations, giving mobile users a way out of a heavy video download, and a play/pause button that actually works well. These two components take care of all of that.

How to Use

Drop either component into any Etch section. The CSS positions the video behind the rest of the section content automatically, so placement in the structure panel doesn’t affect the output. That said, putting it last in the panel just makes the structure easier to read at a glance.

Which One Should I Use?

If your video is a file in your media library or any direct MP4 URL, use the Native Video component. No external dependencies, no setup beyond pointing it at your file.

If your video is hosted on Bunny Stream and you want adaptive bitrate streaming with automatic quality switching, use the Bunny Stream component. It also gives you a proper poster image when paused rather than freezing on the current frame.

If your video is on Bunny Stream but you don’t need adaptive bitrate, the Native Video component works fine with a direct MP4 URL too!

If you’re leaving playOnMobile enabled on, Bunny Stream is probably the better choice. Adaptive bitrate means mobile users get a smaller, lower-resolution file appropriate for their connection rather than the same full-resolution MP4 as desktop.

Native Video Bunny Stream
Video uploaded to WordPress ✅
Any direct MP4 URL ✅
Hosted on Bunny Stream ✅ ✅
Adaptive bitrate / auto quality ✅
No external dependencies ✅
Poster shown when paused ✅
Freezes on current frame when paused ✅
Lazy loading (below-fold) ✅

Shared Behavior

Both components behave the same way in the areas that matter most:

Native Video

The Native Video component uses a standard HTML <video> element with no external dependencies. When paused, the video freezes on the current frame.

Props

Prop Type Default Description
video Media — MP4 video file
poster Media — Image shown before the video loads
aboveFold Boolean true Set to false for below-fold videos to enable lazy loading
hasOverlay Boolean true Dark overlay on top of the video
enablePause Boolean true Play/pause toggle button
playOnMobile Boolean true Set to false to disable video on mobile
videoDescription Text — Optional screen-reader-only description of the video content

Above the Fold

The aboveFold prop is worth paying attention to. When true, the video loads immediately on page load. When false, loading is deferred until the component is near the viewport. Any background video that isn’t visible on initial page load should have this set to false to avoid loading a video the user may never even see.

Bunny Stream

Most WordPress hosts aren’t configured with the right headers and caching rules to serve video efficiently, so offloading to a CDN like Bunny Stream is usually the better call.

The Bunny Stream component embeds your video via Bunny’s player iframe with adaptive bitrate streaming and automatic quality switching. When paused, the video fades out and the poster image is shown rather than freezing on a frame.

Props

Prop Type Default Description
libraryId Text — Your Bunny Stream library ID
videoId Text — The video ID from your Bunny library
cdnHostname Text — Your Bunny CDN hostname, used to display the auto-generate the poster
posterUrl Text Auto Overrides the auto-generated Bunny thumbnail
hasOverlay Boolean true Dark overlay on top of the video
enablePause Boolean true Play/pause toggle button
playOnMobile Boolean true Set to false to show the poster only on mobile
videoDescription Text — Optional screen-reader-only description of the video content

Finding Your IDs

Log in to dash.bunny.net, go to Stream, and select your library. The Library ID and CDN Hostname are in the library settings. The Video ID is the UUID shown on any video’s detail page.

Since libraryId and cdnHostname are the same for every video in a given library, it’s worth setting them as defaults directly in the component. That way you only need to drop in the videoId for each instance rather than re-entering the same values every time.

Poster Image

The poster shows before the video loads and whenever the video is paused. If cdnHostname is set, the poster is auto-generated from Bunny’s thumbnail for that video. You can override it with any image URL using posterUrl.

To customize the auto-generated thumbnail: Stream → your library → click the video → Thumbnail. Scrub to any frame or upload a custom image.

Bunny CDN Settings

A few settings in your Bunny Stream library can affect how the component behaves. These are under Stream → your library → Security.

Allowed Domains
Restricts which domains can embed and play videos from your library. Add your production domain and any staging or dev domains you need. If left empty, all domains are allowed. The component will silently fail to load on any domain not on this list.

Block Direct URL File Access
When enabled, direct requests to CDN files are blocked unless they include a valid referrer header. This setting affects the auto-generated poster. If the poster fails to load, either disable this setting or use the posterUrl prop with a WordPress-hosted image instead.

Embed View Token Authentication
When enabled, the iframe embed requires a signed token. The component doesn’t support this out of the box, so leave it off unless you have server-side token generation in place.

CDN Token Authentication
Same situation as above. Requires server-side implementation and is not supported by the component as shipped.

Styling

Both components share the same CSS custom properties. Override them on the component itself or any ancestor element.

CSS

The mobile breakpoint for playOnMobile is set in CONFIG at the top of each component’s javascript. Both default to 768px.

JavaScript

Accessibility

The play/pause button uses aria-label and aria-pressed so screen readers announce the current state correctly, is fully keyboard accessible, and has a visible focus style. For anyone who has prefers-reduced-motion enabled, the video is paused by default.

The Video Description prop lets you add a screen-reader-only text description of the video content. This is optional, but worth filling in for meaningful context that a screen reader user would benefit from knowing about.