Optimize Video Embeds with a Custom Statamic Tag and Alpine.js

Lokman Musliu Founder and CEO of Lucky Media
Lokman Musliu

January 23, 2024 · 3 min read

Statamic logo development agency

Embedding videos on your website has both benefits and drawbacks. Videos can make your content more exciting and helpful for your visitors. But they might also make your website slower. Slow websites can make for a bad user experience, which we don’t want.

We’ve found a solution to use Alpine.js and a custom Statamic Tag to get the thumbnail image of the YouTube video you want to put on your site.

Using thumbnail images for improved performance

Starting with the thumbnail image is important because it avoids the slowdown from loading a full video player right away. Visitors will first see a quick-loading image. If they want to watch the video, they can click on the thumbnail. Then, the actual video player will load. This way, your site is smart with resources and doesn’t waste bandwidth on videos that might not get watched.

We made this solution for YouTube, but you can change it to work with other video platforms. This lets you put in videos from different places without slowing down your site.

Here’s how to keep your website fast and friendly while still having great content that your audience likes.

Create a custom Statamic tag

We start by creating a custom tag within your Statamic project. Open your terminal, navigate to your project’s directory, and execute this command:

please make:tag YoutubePreview

Research custom tags for Statamic with their official documentation here: Statamic Custom Tags.

Writing the tag

Start by capturing the URL parameter. If it’s missing, return a default placeholder image. Then, use Statamic’s CoreModifiers class to verify if the URL can be embedded. Failing that, you’ll return an empty response.

Here’s the code snippet:

$url = $this->params->get('url');

if (empty($url)) {

    return '/assets/placeholder.png';

}

if (!app(CoreModifiers::class)->isEmbeddable($url)) {

    return [];

}

Next, determine if the URL is from YouTube and extract the video ID to create the URL for the preview image.

if (Str::contains($url, 'youtube.com')) {

    parse_str(parse_url($url)['query'], $newUrl);

    $url = $newUrl['v'];

    $url = "https://img.youtube.com/vi/{$url}/hqdefault.jpg";

} elseif (Str::contains($url, 'youtu.be')) {

    $newUrl = explode('/', $url);

    $url = $newUrl[3];

    $url = "https://img.youtube.com/vi/{$url}/hqdefault.jpg";

}

return $url;

Fully assembled, your custom tag code should look like this:

namespace App\Tags;

use Statamic\Modifiers\CoreModifiers;
use Statamic\Support\Str;
use Statamic\Tags\Tags;

class YoutubePreview extends Tags
{
    public function index(): array|string
    {
        $url = $this->params->get('url');

        if (empty($url)) {
            return '/assets/placeholder.png';
        }

        if (!app(CoreModifiers::class)->isEmbeddable($url)) {
            return [];
        }

        if (Str::contains($url, 'youtube.com')) {
            parse_str(parse_url($url)['query'], $newUrl);

            $url = $newUrl['v'];

            $url = "https://img.youtube.com/vi/{$url}/hqdefault.jpg";

        } elseif (Str::contains($url, 'youtu.be')) {

            $newUrl = explode('/', $url);

            $url = $newUrl[3];

            $url = "https://img.youtube.com/vi/{$url}/hqdefault.jpg";
        }

        return $url;
    }
}

Refreshing your frontend template

In your Antlers template file, create a variable $meta_img to hold the YouTube preview image URLs, populated using the YouTube Preview Tag. This variable is essential for showcasing the video thumbnails.

{{ $meta_img = {youtube_preview :url="video_link"} }}

Feed the video_link from your page’s blueprint into the youtube_preview tag you’ve just created.

Adding interactivity with Alpine.js

Alpine.js helps you switch between the thumbnail and the embedded video when the user interacts with it. Statamic’s directives, like {{ if video_link | is_embeddable }}, confirm that the video can be embedded before it’s displayed.

Your final template will look like this:

{{ $meta_img = {youtube_preview :url="video_link"} }}

<div x-data="{ open: false }" class="mb-8 relative w-full h-full cursor-pointer overflow-hidden aspect-video">
    <div x-show="!open" @click="open = true" x-cloak>
      <img class="object-cover w-full h-auto lazy" src="{{ glide :src="$meta_img" preset='lg' }}" alt="youtube-preview">
    </div>

    <template x-if="open">
        {{ if video_link | is_embeddable }} 
            <iframe src="{{ video_link | embed_url }}?autoplay=1" allow="autoplay" allowfullscreen class="absolute inset-0 w-full h-full"></iframe>
        {{ /if }}
    </template>

    <div x-bind:class="open && 'hidden'" @click="open = true" x-cloak>
        <div class="absolute top-1/2 left-1/2 z-20 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer">
            <div class="play-button"></div>
        </div>
    </div>
</div>

x-cloak is an Alpine.js directive that prevents elements from flickering before Alpine.js initializes. To learn more about directives visit Alpine.js Directives.

To make x-cloak effective, include this CSS in your site.css:

[x-cloak] { 
  display: none !important; 
}

Conclusion

By following these steps, you’ve added a custom YouTube Preview Tag to your Statamic project, making your site’s multimedia better. Statamic, Alpine.js, and your new tag work together to create an interactive video preview. Try it out and improve your web app.


Bring Your Ideas to Life 🚀

Kickstart Your Statamic Project with the #1 Statamic Agency

Are you planning a new Statamic project or thinking about migrating your WordPress site to Statamic? Learn more about our expertise as a renowned Statamic development agency.

Technologies

StatamicAlpine.js
Lokman Musliu Founder and CEO of Lucky Media
Lokman Musliu

Founder and CEO of Lucky Media

Stay up-to-date

Be updated with all news, products and tips we share!

Let’s chat

We partner with a limited number of brands each quarter to ensure senior-level attention on every project.

lokman and arlind headshots
Teamwork

Related posts

March 9, 2022

Event Listeners for Statamic
Statamic