Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/finsweet/attributes/llms.txt

Use this file to discover all available pages before exploring further.

The fs-videohls attribute integrates hls.js into your Webflow project, enabling HTTP Live Streaming (HLS) support for browsers that don’t natively support it. This allows adaptive bitrate streaming using .m3u8 manifest files.

How It Works

The attribute automatically:
  • Detects HLS manifest URLs (.m3u8 files) in video sources
  • Initializes hls.js for browsers that need it
  • Falls back to native HLS support on Safari/iOS
  • Works with CMS-driven video lists
  • Manages HLS instances and cleanup

Installation

<script src="https://cdn.jsdelivr.net/npm/@finsweet/attributes-videohls@1/videohls.js"></script>

Basic Usage

Using the Manifest Attribute

The most straightforward approach is to use the fs-videohls-manifest attribute:
<video 
  fs-videohls-manifest="https://example.com/video/playlist.m3u8"
  controls
  playsinline
></video>

Using Source Elements

Alternatively, add .m3u8 sources directly:
<video controls playsinline>
  <source src="https://example.com/video/playlist.m3u8" type="application/vnd.apple.mpegurl">
  <source src="https://example.com/video/fallback.mp4" type="video/mp4">
</video>

Using the src Attribute

<video 
  src="https://example.com/video/playlist.m3u8"
  controls
  playsinline
></video>

Configuration

Manifest Attribute

Specify the HLS manifest URL directly on the video element:
<video 
  fs-videohls-manifest="https://cdn.example.com/streams/live.m3u8"
  controls
></video>
The fs-videohls-manifest attribute takes priority over source elements and the src attribute when determining the HLS manifest URL.

Working with CMS Lists

The attribute integrates with fs-list for dynamic video collections:
<div fs-list-element="list">
  <div fs-list-element="item">
    <video 
      fs-videohls-manifest="{cms-video-hls-url}"
      controls
      playsinline
      poster="{cms-video-poster}"
    ></video>
  </div>
</div>
The attribute listens for list load events and automatically initializes HLS for newly added videos.

Technical Details

Browser Support Detection

The attribute checks if HLS initialization is needed:
// Native HLS support (Safari/iOS)
if (video.canPlayType('application/vnd.apple.mpegurl')) {
  // Use native playback, no hls.js needed
}

// hls.js support check
if (Hls.isSupported()) {
  // Initialize hls.js
}

Manifest URL Detection

The attribute searches for HLS manifest URLs in this order:
  1. fs-videohls-manifest attribute value
  2. <source> elements with .m3u8 extension
  3. Video src attribute with .m3u8 extension
const HLS_FILE_EXTENSION_REGEX = /.*\.m3u8$/;

HLS Instance Management

Each video gets its own HLS instance:
const hlsInstance = new Hls();
hlsInstance.loadSource(manifestURL);
hlsInstance.attachMedia(video);
Instances are stored and properly destroyed on cleanup:
destroy() {
  for (const [, hlsInstance] of hlsInstancesStore) {
    hlsInstance.destroy();
  }
}

Advanced Examples

With Custom Controls

<div class="video-container">
  <video 
    fs-videohls-manifest="https://cdn.example.com/stream.m3u8"
    playsinline
  ></video>
  
  <div class="custom-controls">
    <button class="play-btn">Play</button>
    <button class="pause-btn">Pause</button>
    <div class="progress-bar"></div>
  </div>
</div>

Multiple Quality Levels

<!-- The HLS manifest handles quality switching automatically -->
<video 
  fs-videohls-manifest="https://cdn.example.com/adaptive/master.m3u8"
  controls
  playsinline
>
  <!-- Fallback for browsers without HLS support -->
  <source src="https://cdn.example.com/video-720p.mp4" type="video/mp4">
</video>
HLS manifests can include multiple quality levels, and hls.js will automatically switch between them based on network conditions (adaptive bitrate streaming).

Live Streaming

<video 
  fs-videohls-manifest="https://live.example.com/stream/live.m3u8"
  controls
  playsinline
  class="live-video"
>
</video>

Best Practices

Provide Fallback Sources

Always include MP4 fallbacks for maximum compatibility:
<video controls playsinline>
  <source src="stream.m3u8" type="application/vnd.apple.mpegurl">
  <source src="fallback.mp4" type="video/mp4">
</video>

Use Appropriate Attributes

<video 
  fs-videohls-manifest="video.m3u8"
  controls
  playsinline
  preload="metadata"
  poster="thumbnail.jpg"
></video>
  • controls: Shows video controls
  • playsinline: Prevents fullscreen on iOS
  • preload="metadata": Loads video metadata without downloading the entire video
  • poster: Shows thumbnail before playback

CDN and CORS

Ensure your HLS manifest and segments are:
  • Served from a CDN for better performance
  • Configured with proper CORS headers
  • Using HTTPS for secure connections

Troubleshooting

Video Not Loading

  • Verify the .m3u8 manifest URL is accessible
  • Check browser console for CORS errors
  • Ensure the manifest file is properly formatted

Safari Issues

Safari has native HLS support and doesn’t use hls.js:
  • The attribute will skip hls.js initialization on Safari
  • Test that your manifest works with native Safari playback

CMS Integration

  • Ensure the CMS field contains a valid .m3u8 URL
  • Verify the attribute is present before the list loads
  • Check that fs-list is properly initialized

HLS Manifest Example

A basic HLS master playlist (.m3u8):
#EXTM3U
#EXT-X-VERSION:3

#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=1280x720
720p.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1920x1080
1080p.m3u8
Each quality level references its own media playlist with video segments.