How to add a custom video player to your Webflow site

Full control over video behavior → Customize controls, autoplay, looping, and fullscreen options.
GDPR compliance → Unlike YouTube, self-hosted videos do not use tracking cookies, meaning no consent is required.
Better branding → No third-party branding or suggested videos after playback.
Optimized performance → Self-hosted MP4/WebM videos load faster and do not rely on external services.
Before adding a video player, make sure your video is in MP4 and WebM formats for maximum compatibility.
Now that your video is ready, you need to insert it into Webflow using custom HTML, CSS, and JavaScript.
Insert this code in an embed element in Webflow:
<video class="video" width="100%" height="100%">
<source src="https://res.cloudinary.com/your-account/video.mp4" type="video/mp4">
<source src="https://res.cloudinary.com/your-account/video.webm" type="video/webm">
</video>
📌 Replace the URLs with the links from your Cloudinary Asset Manager.
Now, we’ll add JavaScript to control video playback, pause, fullscreen, and progress tracking.
Insert this JavaScript in Webflow’s custom code section:
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("video").forEach(video => {
const container = document.createElement("div");
container.classList.add("video-container");
video.parentNode.insertBefore(container, video);
container.appendChild(video);
const controls = document.createElement("div");
controls.classList.add("video-controls");
const playPauseBtn = document.createElement("button");
playPauseBtn.classList.add("video-button");
playPauseBtn.innerHTML = `
<svg id="pauseIcon" width="24" height="24" fill="white">
<path d="M8 19c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2v10c0 1.1.9 2 2 2m6-12v10c0 1.1.9 2 2 2s2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2"></path>
</svg>
<svg id="playIcon" width="24" height="24" fill="white" style="display: none;">
<path d="M8 6.82v10.36c0 .79.87 1.27 1.54.84l8.14-5.18a1 1 0 0 0 0-1.69L9.54 5.98A.998.998 0 0 0 8 6.82"></path>
</svg>
`;
controls.appendChild(playPauseBtn);
const progressContainer = document.createElement("div");
progressContainer.classList.add("video-progress-container");
const progressBar = document.createElement("div");
progressBar.classList.add("video-progress-bar");
progressContainer.appendChild(progressBar);
controls.appendChild(progressContainer);
const fullscreenBtn = document.createElement("button");
fullscreenBtn.classList.add("video-button");
fullscreenBtn.innerHTML = `
<svg width="24" height="24" fill="white">
<path d="M4 4h6v2H6v4H4V4m10 0h6v6h-2V6h-4V4m-6 10v4h4v2H4v-6h2m16 0v6h-6v-2h4v-4h2"></path>
</svg>
`;
controls.appendChild(fullscreenBtn);
container.appendChild(controls);
playPauseBtn.addEventListener("click", () => {
if (video.paused) {
video.play();
playPauseBtn.querySelector("#playIcon").style.display = "none";
playPauseBtn.querySelector("#pauseIcon").style.display = "block";
} else {
video.pause();
playPauseBtn.querySelector("#playIcon").style.display = "block";
playPauseBtn.querySelector("#pauseIcon").style.display = "none";
}
});
fullscreenBtn.addEventListener("click", () => {
if (video.requestFullscreen) {
video.requestFullscreen();
}
});
video.addEventListener("timeupdate", () => {
const percent = (video.currentTime / video.duration) * 100;
progressBar.style.width = `${percent}%`;
});
progressContainer.addEventListener("click", (e) => {
const rect = progressContainer.getBoundingClientRect();
const offsetX = e.clientX - rect.left;
video.currentTime = (offsetX / rect.width) * video.duration;
});
});
});
</script>
{{blog_article_ad}}
To make controls visible and responsive, add this CSS in Webflow’s Custom Code → Head Section:
<style>
.video-container {
position: relative;
width: 100%;
max-width: 100%;
overflow: hidden;
}
.video-controls {
position: absolute;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
padding: 8px;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
.video-container:hover .video-controls {
opacity: 1;
}
.video-button {
background: none;
border: none;
cursor: pointer;
}
.video-progress-container {
flex: 1;
height: 6px;
background: rgba(255, 255, 255, 0.3);
cursor: pointer;
position: relative;
}
.video-progress-bar {
width: 0%;
height: 100%;
background: white;
}
</style>
If you want your video to autoplay and loop without controls, use Finsweet’s Auto Video Attributes (Finsweet Auto Video). This solution removes controls but ensures seamless video playback.
By implementing a custom video player, you ensure GDPR compliance, improve branding, and gain full control over video behavior. If you want autoplay without controls, consider using Finsweet Auto Video Attributes. Now, your Webflow site can feature fully customized, self-hosted videos without relying on YouTube! 🚀
Webflow’s native Video element is great for embedding content from YouTube and Vimeo, but it lacks flexibility for customization and self-hosted videos. By following this guide, you’ll have a fully customized video player that fits your brand and ensures full control over the user experience.