Skip to content

Video Embed

Video embed components are used to embed videos from video hosting services such as YouTube, Wistia, or Vimeo.

<VideoEmbed source="https://www.youtube.com/embed/lJIrF4YjHfQ" />

API Reference

This component root is based on the <div> element and can take in any additional HTML attributes. In addition, the <iframe> attributes can be passed to the component to customize the video embed as well through the iframeAttrs prop. The following are the custom props that can be passed to the component.

Prop Type Default
source *
string
iframeAttrs
HTMLAttributes<'iframe'>

Accessibility

The <VideoEmbed> component has some accessibility considerations baked into it. The following are some of the key accessibility features that are included in the component and worth considering:

  • There is a hidden skip link prior to the embed that allows users to skip past the video and its controls. This is done by using a visually hidden hash link that only displays on keyboard focus and is linked to an empty div immediately after the video embed.

Examples

YouTube

<VideoEmbed source="https://www.youtube.com/embed/lJIrF4YjHfQ" />

Wistia

<VideoEmbed source="https://fast.wistia.net/embed/iframe/30q7n48g4f?seo=true&videoFoam=false" />

Vimeo

<VideoEmbed source="https://player.vimeo.com/video/877473729?h=255330332d&title=0&byline=0&portrait=0" />

Astro Component

Depending on the framework, it’s sometimes beneficial to use a component. In this case, we have put together the following Astro component to serve as a blueprint for how you could possibly set up a Video Embed component, and what properties to consider.

VideoEmbed.astro
---
import type { HTMLAttributes } from 'astro/types'
import Button from '@/components/elements/Button.astro'
interface Props extends HTMLAttributes<'div'> {
/**
The source of the video. E.g. 'https://www.youtube.com/embed/lJIrF4YjHfQ'
*/
source: string
/**
Additional attributes to pass to the iframe element.
*/
iframeAttrs: HTMLAttributes<'iframe'>
}
const { source, class: className, iframeAttrs, ...attrs } = Astro.props
// Generate a unique ID for the video element
const id = `video-${crypto.randomUUID()}`
---
<div
class:list={['relative', className]}
data-component="VideoEmbed"
{...attrs}
>
<Button
href={`#${id}`}
variant="text"
class="sr-only focus-visible:not-sr-only">Skip past video</Button
>
<iframe
src={source}
class:list={['aspect-video size-full', iframeAttrs?.class]}
allow={iframeAttrs?.allow || 'autoplay; fullscreen; picture-in-picture'}
allowfullscreen={iframeAttrs?.allowfullscreen || true}
{...iframeAttrs}></iframe>
</div>
<div id={id}></div>