Before starting this tutorial, why create a video widget when there is already an Elementor video widget?
Because the default Elementor video widget loads the video frame, that is bad for page speed but it is to give you many controls like the autoplay, suggested videos, player control, etc…
In this tutorial, I will show you how to create a video widget that only loads the video thumbnail as you can see on the homepage of this site, this will make you win a lot of speed especially if you have many videos on the same page.
Let’s begin!

Step 1 – Call the Widget

The first step is to call the Elementor video widget we will create. I assume that you use a child theme but you can, of course, create a new plugin if you prefer.

Add the following code in the functions.php file of your child theme:

class OceanWP_Child_Theme {

* Main Theme Class Constructor
public function __construct() {

// Register the video widget
add_action( 'elementor/widgets/widgets_registered', array( 'OceanWP_Child_Theme', 'widgets_registered' ) );

// Load the video widget script
add_action( 'elementor/frontend/after_register_scripts', array( 'OceanWP_Child_Theme', 'register_scripts' ) );

} // End constructor

// Register the video widget
public static function widgets_registered() {

// We check if the Elementor plugin has been installed / activated.
if ( defined( 'ELEMENTOR_PATH' ) && class_exists( 'Elementor\Widget_Base' ) ) {
require_once( get_stylesheet_directory() .'/widgets/video.php' );


// Load the video widget script
public static function register_scripts() {

// Register video script
wp_register_script( 'owp-video', get_stylesheet_directory_uri() .'/js/video.js', [ 'jquery' ], 1.0, true );


new OceanWP_Child_Theme;

The first function calls the video widget and the second function is to call the JS script that we need for this widget.

Step 2 – Widget Creation

In this second step, we will create the Elementor widget.
Create a widgets folder, this way you will be able to add other Elementor widgets to have a clean child theme.
Then, create a video.php file in this folder, open this file in your text editor and add this code:

namespace Elementor;

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {

class OWP_Widget_Video extends Widget_Base {

public function get_name() {
return 'owp-video';

public function get_title() {
return 'Video Widget';

public function get_icon() {
return 'eicon-youtube';

public function get_script_depends() {
return [ 'owp-video' ];

protected function _register_controls() {

'label' => 'Video',

'label' => 'Video ID',
'type' => Controls_Manager::TEXT,



protected function render() {
$id = $this->get_settings( 'video_id' ); ?>

<div class="owp-fit-aspect-ratio">
<div class="owp-youtube-player" data-id="<?php echo esc_attr( $id ); ?>">
<div class="owp-play"><i class="eicon-play"></i></div>


protected function _content_template() {}


Plugin::instance()->widgets_manager->register_widget_type( new OWP_Widget_Video() );

You can see that I use only one option to get the video ID, I want to keep this widget very simple.
You can also see that I call the JS script at step 1 in the get_script_depends() function, this script will be only loaded when you will add this video widget on your page.

Step 3 – The JS Script

The JS code will do all the magic, it will take your video thumbnail from YouTube via the video ID you will put in the widget and will replace the thumbnail by an iframe when you will click on it.

Create a js folder in your child theme and create a video.js file inside this folder. Open this file in your text editor and add this JS code:

document.addEventListener( 'DOMContentLoaded', function() {
var i,
video = document.getElementsByClassName( 'owp-youtube-player' );

for (i = 0; i < video.length; i++) {

// We get the thumbnail image from the YouTube ID
video[i].style.backgroundImage = 'url(//' + video[i] + '/maxresdefault.jpg)';

video[i].onclick = function() {
var iframe  = document.createElement( 'iframe' ),
embed   = '';
iframe.setAttribute( 'src', embed.replace( 'ID', ) );
iframe.setAttribute( 'frameborder', '0' );
iframe.setAttribute( 'allowfullscreen', '1' );
this.parentNode.replaceChild( iframe, this );


} );

This is a very simple code to display the video when you click on its thumbnail.
You can add or change some controls at line 12.

Step 4 – The CSS Code

Right now, there is no way to load a CSS file only when an Elementor widget is used as a JS script, so add directly this CSS code in the style.css file of the child theme:

.owp-fit-aspect-ratio {
position: relative;
height: 0;
padding-bottom: 56.25%;

.owp-fit-aspect-ratio iframe {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
border: 0;
line-height: 1;

.owp-youtube-player {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: 50%;

.owp-youtube-player {
cursor: pointer;
text-align: center;

.owp-youtube-player img {
display: block;
width: 100%;

.owp-play {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);

.owp-play i {
font-size: 120px;
color: #fff;
opacity: 0.8;
text-shadow: 1px 0 6px rgba(0, 0, 0, 0.3);
-webkit-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;

.owp-youtube-player:hover .owp-play i {
opacity: 1;

Step 5 – Add your Video ID in the Widget

The final step is to copy/paste your video ID into our video widget. To get the ID, it is very simple, open your YouTube video in your browser, for example:

The video ID of this link is what you see just after watch?v=, so jeZfDUWfbd8.

Now, open the Elementor editor, you will see a new video widget, add it to your page or post, and paste your video ID in the Video ID field.
Note: If you don’t find the widget, do a search for Video, you will see Video Widget, this is our widget.

That all! Now, go to the front-end of your site, you will see your video thumbnail and when you click on it, your video will appear.


You can see that it is a simple widget easy to create and much better than adding a YouTube embed code that directly load the video frame.
Tell me in the comments if you like this tutorial and if you want more tutorials like this.

This Post Has 20 Comments

  1. Fabio

    Hello Nicolas,

    Great article! What if we are using a cache plugin like WP rocket?
    Since version 2.11 December 14, 2017, they have added a feature that also automatically replace Youtube video’s by clickable thumbnails. This seems very much “duplicate” function.
    Will this not conflict and run into issues? Or perhaps I don’t need your script when WP rocket is activated?
    Or is it better to disable this feature in WP rocket and use your script?

    From changelog version 2.11:
    “Enhancement: As a new lazyload option, you can now replace Youtube videos by clickable thumbnails, which can help your loading time if you have a lot of videos on the same page”


    1. Nicolas Lecocq

      Hello Fabio, glad that you like the article 🙂
      I saw this new feature in WP Rocket, I never tested it but I think this is the same thing so it is totally up to you 🙂
      For my part, I prefer to use my own widget to control everything (style, no title or description in the video, etc…).

  2. Antonio Martins

    Amazing Nicolas, thank you. I will use this widget instead of Elementor’s.

  3. David Wilks

    Hi Nicolas. As always, thanks for your continual optimization ideas, both within the theme code and externally as here.

  4. Kennet Jansson

    Ok nice. Is it possible to hide/delete the YouTube logo in right down corner?

  5. x

    Issue with your base theme when numbered list is used. Hope somebody has appraised you of the issue!
    On the other note ie. your work and contribution : Simply Splendid!

  6. Paul


    How can we work the video widget like this by using the ‘Embed Code’ or ‘oEmbed URL’ or ‘Link’ Post options in ‘OceanWP Settings’ on a post?

    It would be great to be able to have a client simply fill out the content, and the video URL (paste it into the oEmbed URL and/or Link or something like that) and have that URL apply to this widget. I seem to see references to it in ACF’s documentation and the oEmbed documentation, but would it be possible to apply it to this custom widget?

    1. Nicolas Lecocq

      Hello, why do you want to use an embed code for this widget? You just need to add your video ID. With an embed code, the iframe will be loaded, this widget is specially built to not use the iframe.

  7. Esteban

    Hello, I just want to add a play icon in each post thumbnail at the home of the website.

  8. Rob

    Hello Nicolas, we are really loving Ocean WP and Elementor. One question: Could you guys make a Footer Widget for YouTube in the same manner that you have already for Facebook and Twitter? We have clients asking for a solution like this. Thanks in advance! Rob_

  9. Antonia

    Hi Nicolas! Thanks such much for your amazing work! I have a question for you, if I add this widget will I be able to have youtube video autoplay with sound?

  10. jeffphoto

    Ok Need some help as the above is REALLY confusing to someone who doesn’t know what most of that stuff means and you left out a LOT of steps where you just assume that people know.
    Is there a way to get more help with this? Because this is definitely a big problem with my site at the moment that needs fixed.
    Here is the list of questions:
    1. Step 1: it’s unclear which part of that code you copy and past and in what line you are to past it into the functions php file. Does it go at the end of what is there now? In between? Do I include the first and last line you have in there that calls it the ocean wp child theme, as that is not what mine is called or doesn’t have that at all in my code?

    2. Step 2 – you assume and I have no idea how you create a widgets folder, where to create, and then how to create a video.php file in it? Where are you doing this? From what I see there is no place to add a folder?

    3. Step 3 again says to create a JS script folder. Where and how?

    4. Step 4: again it doesn’t indicate where to add that code in the CSS. it indicated line 1 in your photo, but obviously, there is already stuff in that spot. So where do you put it?

    So as you can see, you are a missing a lot of steps, unless you are already an expert on how to do this stuff.
    Can you please advice some how?

    1. Nicolas Lecocq

      Hello, it is indeed for users who already know how to do some things.

      1. The child theme name doesn’t matter, the process is the same.

      2. I don’t know what is your computer but go to your child theme and if you do a right click on your mouse, you will logically see a “Create new folder”, then name it widgets. For the PHP file, you can just copy any PHP file, then rename it, open it in your text editor and delete everything in it.

      3. Same as two.

      4. In that case, at the very end of your file.

      Also, there are some plugins to do that, so if it is really to hard to do it via a child theme, you can use a plugin.

      Feel free to ask me if you miss a point.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.