Skip to main content
Blog|
How-to guides

How to add and embed videos in WordPress

|
Apr 13, 2026|9 min read
HOW-TO GUIDESHow to add and embed videos inWordPressHOSTNEYhostney.comApril 13, 2026

Short answer: paste the video URL on its own line in the block editor. WordPress detects it and embeds the player automatically. This works for YouTube, Vimeo, TikTok, Twitter/X, Facebook, and dozens of other services out of the box – no plugin, no code, no shortcode.

The rest of this guide covers the other scenarios: when you want to self-host the file instead, when you need a video background in a full-width section, how to pick between YouTube, Vimeo, and privacy-friendly alternatives, how to keep videos from slowing down your site, and how to handle live streams.

The fastest way: oEmbed (just paste the URL)#

WordPress has built-in support for a standard called oEmbed. When you paste a URL from a supported service on its own line in the block editor, WordPress asks that service for the embed HTML and drops the correct player into your post.

How to do it:

  1. Copy the video URL from YouTube, Vimeo, etc. (for YouTube, use the https://youtu.be/... or https://www.youtube.com/watch?v=... format – both work).
  2. In the WordPress block editor, create a new block and paste the URL on its own line.
  3. Press Enter or Tab. WordPress converts the URL into an Embed block showing the video player.

That is the entire process. You do not need a YouTube plugin, a Vimeo plugin, or any HTML. WordPress handles the iframe, the responsive sizing, and the aspect ratio for you.

Services WordPress embeds automatically include YouTube, Vimeo, TikTok, Twitter/X, Facebook, Instagram, Reddit, Spotify, SoundCloud, Flickr, Imgur, Dailymotion, and Twitch. The full list is in WordPress core and gets updated periodically.

If pasting a URL does not auto-embed, add an Embed block manually: click the + button, type “embed,” pick the right service (or use the generic “Embed” block), and paste the URL there.

The Video block (self-hosted files)#

If you have a video file you want to host on your own server instead of uploading to YouTube, use the Video block:

  1. In the block editor, click + and search for “Video.”
  2. Upload the file from your computer or pick one already in the Media Library.
  3. WordPress inserts an HTML5 <video> tag with basic controls.

This works. It is also almost always a bad idea. Here is why.

Why self-hosting video is usually a bad idea

Video is hundreds of times larger than any other content on your site. A single 10-minute HD video can be 500 MB to 2 GB. That creates four problems:

  1. Bandwidth. Every visitor who plays the video downloads it from your hosting. One viral post can consume more bandwidth in a day than your entire site does in a year. Many hosts either throttle you or charge overage fees at that point.
  2. Storage. Video eats disk space fast. If you publish video regularly, you will outgrow your plan’s storage limit.
  3. No adaptive streaming. YouTube and Vimeo automatically adjust video quality based on the viewer’s connection speed – 1080p on fiber, 480p on a slow mobile connection. A self-hosted <video> tag serves the same file to everyone. Slow connections buffer constantly or fail outright.
  4. No transcoding. If you upload a 4K file, visitors download 4K even if they are watching on a phone. YouTube transcodes your upload into multiple resolutions automatically. Self-hosting does not.

Self-hosting only makes sense in narrow cases: short clips (under 10 seconds), internal tools where the audience is small and known, or sites with a strict privacy requirement that rules out external services.

If you are on managed WordPress hosting, the NVMe storage and container resources you get are optimized for dynamic PHP workloads and caching, not for serving video to thousands of visitors. We go into the storage side of this in NVMe WordPress hosting: why storage type affects site speed.

Picking a video host#

For anything you want watched by the public, use a dedicated video platform.

ServiceFree?Ads?Private video supportBest for
YouTubeYes, unlimitedYes (for viewers, unless you pay Premium)Limited (unlisted/private)Maximum reach, SEO, discovery
VimeoLimited free tierNoStrong (password, domain whitelist)Polished/professional, client work
Bunny StreamPay-as-you-goNoYes, with token authPrivacy-friendly, full control, no YouTube branding
Cloudflare StreamPay per minuteNoYesInfrastructure-first, developers
WistiaLimited freeNoYesMarketing/lead capture with built-in CTA

Use YouTube if you want the video to be discoverable, rank in search, and reach the widest audience. The tradeoff is the YouTube UI, related-video suggestions at the end, and ads your viewers may see.

Use Vimeo if you need a clean player without suggested videos or ads, private/password-protected videos, or the professional Vimeo player aesthetic. Good for client work, tutorials, portfolios.

Use Bunny Stream or Cloudflare Stream if you want a player with no third-party branding, no tracking, and full control over who can watch. Both work well with custom players and have geographic-restriction and token-authentication features. This is what privacy-focused sites usually pick.

For any of these, once you have the video live on the platform, embedding it in WordPress is the same oEmbed paste-and-enter process from the first section.

Video backgrounds in full-width sections#

A muted, looping video background behind a hero section is a common design pattern. There are three ways to implement it.

Option 1: block editor “Cover” block

The simplest approach if you are using the default block editor:

  1. Add a Cover block.
  2. Choose “Upload” or “Media Library” and pick a video file.
  3. Set the block to full-width under the block settings.
  4. Add your heading, button, or other content inside the Cover block.

The Cover block gives you overlay controls, a focal point picker, and easy content layering. The downside is the same self-hosting issue from earlier – the video file lives on your server, and Gutenberg does not give you fine-grained control over compression or preload behavior.

Option 2: page builder (Elementor, Divi, Bricks)

Most page builders have a “Section” or “Container” element with a built-in video background option. They usually support:

  • Uploaded video files
  • YouTube/Vimeo URLs as backgrounds (auto-muted, auto-looped, with the player chrome hidden)
  • Fallback images for mobile
  • Lazy loading

Elementor calls it “Background Type > Video.” Divi has “Background Video” under section settings. Bricks has it in the section background panel. All three handle the video-behind-content layering automatically.

Option 3: hand-rolled CSS

For a lightweight implementation without a page builder, add this to a Custom HTML block or a full-width section:

<section class="hero">
  <video autoplay muted loop playsinline poster="/wp-content/uploads/hero-poster.jpg">
    <source src="/wp-content/uploads/hero.mp4" type="video/mp4">
  </video>
  <div class="hero-content">
    <h1>Your headline here</h1>
  </div>
</section>
.hero { position: relative; overflow: hidden; }
.hero video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
}
.hero-content { position: relative; z-index: 1; }

The four critical attributes on the <video> tag:

  • autoplay – starts playing when the page loads
  • muted – required for autoplay to work in modern browsers; autoplay with sound is blocked everywhere
  • loop – restarts the video when it ends
  • playsinline – prevents iOS from forcing fullscreen playback

The poster attribute loads instantly while the video downloads, so the section is not blank for the first few hundred milliseconds. Use a still frame from the video.

Compress the video aggressively. A background video should be under 5 MB ideally, under 10 MB absolutely. Use a short loop (10-20 seconds), 720p maximum, and H.264 encoding. Tools like HandBrake or ffmpeg can bring most footage under the limit without visible quality loss at the sizes a hero section uses.

Lazy loading and performance#

Videos hurt page speed if you let them. A few rules:

Never autoplay sound. Browsers block it and users hate it.

Do not preload videos below the fold. Add preload="none" to any <video> tag that is not the hero. The browser will only start downloading when the user clicks play.

<video controls preload="none" poster="/path/to/thumb.jpg">
  <source src="/path/to/video.mp4" type="video/mp4">
</video>

Lazy-load YouTube and Vimeo embeds. A YouTube iframe loads about 1 MB of JavaScript and makes 10+ network requests before the user ever clicks play. For pages with multiple video embeds, this is significant. Options:

  • Use a “facade” pattern: show a static thumbnail image with a play button, and only swap in the real iframe when the user clicks. The lite-youtube-embed library does exactly this.
  • Modern browsers support loading="lazy" on iframes. It helps a little, but does not prevent the upfront payload when the iframe is near the viewport.
  • Some caching/performance plugins (WP Rocket, LiteSpeed Cache, Perfmatters) have a “lazy load YouTube/Vimeo” option that swaps in the facade pattern automatically.

If you are working through a broader speed-up, videos are one piece – see how to speed up WordPress for the full priority order (caching, image optimization, database, CSS/JS, video). For stores specifically, product videos interact with cart AJAX and should go through WooCommerce speed optimization.

Serve video from a CDN if you self-host. Even a short background video benefits from edge caching. If you are not sure whether a CDN applies to your site, should I use a CDN for my website walks through when it helps.

Live streaming in WordPress#

“Live streaming in WordPress” usually means embedding a stream that is happening elsewhere, not running the stream from WordPress itself. WordPress is a publishing platform, not a streaming server.

Option 1: embed a YouTube Live stream. When you start a live stream on YouTube, the live URL is oEmbed-compatible. Paste it in the editor and viewers see the live player with the chat sidebar (optional) on the frontend. The stream survives the eventual transition to a regular video-on-demand URL after the broadcast ends.

Option 2: embed a Twitch stream. Works the same way – paste the channel or stream URL and WordPress embeds the Twitch player.

Option 3: Restream.io. If you stream to multiple platforms simultaneously (YouTube, Twitch, Facebook, LinkedIn), Restream handles the multi-destination push and gives you a single embeddable player.

Option 4: dedicated live streaming plugins. Plugins like Castr, VdoCipher, and StreamYard offer WordPress integrations that handle authentication, pay-per-view, and DRM. These are for paid live events, webinars with gating, or enterprise use cases.

Do not try to run the actual stream ingest and transcoding on a WordPress server. It is a completely different workload – real-time, CPU-intensive, and incompatible with the PHP-FPM + caching architecture WordPress runs on. Use a streaming service and embed.

A quick checklist#

Before hitting publish on a post with video:

  • Paste-to-embed works? If not, use the Embed block manually.
  • Self-hosted video is under 10 MB and has a poster image?
  • Background videos have autoplay muted loop playsinline and a poster fallback?
  • Below-the-fold videos have preload="none" or a facade pattern?
  • Mobile viewers get either a fallback image or a compressed video variant?
  • Live streams are embedded from YouTube/Twitch/Restream, not hosted on your server?

Video is one of those features where the defaults in WordPress work well if you pick the right host, and cause problems fast if you fight the platform. For most sites, the answer is: upload to YouTube or Vimeo, paste the URL into a WordPress post, and let oEmbed do the rest. The more elaborate scenarios – backgrounds, lazy loading, live streams – are all variations on that core pattern.

Related articles