If you manage a WordPress site and incorporate video content into your publishing, marketing, or monetization efforts, you might have encountered the term “VAST tag.” While it may sound technical, understanding VAST tags can be important—especially when working with video ad networks or trying to monetize your own video content. This tutorial will walk you through what a VAST tag is, why it’s useful, and how to implement it using a compatible video player alongside Advanced Ads.
Table of Contents
What are VAST tags?
VAST is a standardized format maintained by the IAB Tech Lab (Interactive Advertising Bureau). It was created to ensure consistent communication between ad servers and video players, no matter which platforms or vendors are involved. If you’re curious about the technical specification behind the tags you’re going to work with—or you’re planning to integrate more advanced features like skippable ads, wrappers, or companion banners—you can find the full documentation on the IAB’s VAST standard page.
Many WordPress publishers come across VAST tags not because they’re looking for them, but because a partner, platform, or ad network provides one. For example, if you join a video ad network like Primis, Brid.TV, or Unruly, you’ll often receive a VAST tag—a URL pointing to a short XML file that tells your video player how to integrate a video ad into the original video and track impressions and clicks for the ad.
In those cases, VAST isn’t something you choose to use—it’s just how the ads are delivered. You’ll need a player on your site that understands how to handle that tag, and a way to insert it properly.
Some publishers encounter VAST when they decide to host their own video content rather than rely on platforms like YouTube. That decision might come from wanting more control over branding, avoiding third-party recommendations, or needing to integrate with a specific ad server like Google Ad Manager.
If you’re serving your own MP4 files from your server or content delivery network (CDN), and you want to show a pre-roll ad before the video starts, VAST becomes the link between your ad setup and the video player on your web page.
What are pre-roll ads?
A pre-roll ad is a video advertisement that plays before the main video content. It’s the most common format used with VAST tags. Other common types include mid-roll ads (which play during the video, usually at set intervals) and post-roll ads (which appear after the content ends). Some players also support skippable or interactive ads, depending on what the VAST tag provides and the player’s capabilities.
There’s also a smaller group of users—affiliates and lead generators—who use video ads as part of a campaign flow. Sometimes, an affiliate program or advertising offer based on cost-per-action (CPA) requires that a short video be played before the user is sent to a landing page or offer.
In that case, the advertiser might provide a VAST tag and expect you to track views and completions. Supporting that tag isn’t optional; it’s part of running the campaign as intended. Whether you’re using videos on landing pages, opt-in forms, or product reviews, VAST might be the only way to deliver the required video ad.
It’s worth noting that this doesn’t apply to YouTube or Vimeo videos that you might have embedded on your website. While those platforms are convenient and widely used, they don’t allow third-party ad insertion—unless you’re part of their monetization programs.
If you’re hosting your own videos and want to monetize them directly, or need to integrate video ads from a network or ad partner, you’ll need a player that supports VAST and a way to connect it to your WordPress site. That’s where Advanced Ads and this tutorial come in.
Requirements and limitations for using VAST tags
Before you can display a video ad using a VAST tag, a few technical requirements need to be in place. VAST doesn’t handle the actual playback—it just delivers the instructions. It’s up to your video player to understand and act on them.
First, you’ll need access to a VAST tag. This is usually a URL pointing to an XML file, provided by an ad network, affiliate campaign, or your own ad server. It defines the media file, clickthrough URL, tracking events, and any fallback behavior. If you don’t have one yet, we’ll also show you how to create a simple one for testing later on.
Second, you’ll need a video player that supports VAST. The built-in WordPress video block and the native HTML5 <video>
tag won’t work—they can play video files, but they can’t load ads or respond to tracking events. You’ll need a player that either comes with VAST support or can be extended with it. The video itself also needs to be self-hosted or accessible through a direct video file URL (usually a .mp4).
One other technical hurdle to be aware of is browser security. VAST tags are usually hosted on a different domain than your site, and modern browsers block these cross-origin requests unless the server explicitly allows it. If your tag doesn’t work and the browser console shows a CORS (Cross-Origin Resource Sharing) error, this is likely the reason. We’ll cover how to work around that later in the tutorial.
How to choose a VAST-compatible video player
Since VAST tags require a compatible player to function, the next step is choosing one that fits your site. As mentioned earlier, the default WordPress video block and the HTML5 <video>
element won’t handle VAST ads—you’ll need something more capable.
Some WordPress video plugins come with VAST support built in or offer it as a premium feature. FV Player with the FV Player VAST add-on and Elite Video Player, for instance, both allow you to paste a VAST tag into their interface and handle most of the setup for you. These tools are designed for convenience and may be a good choice if you’re focused on video publishing and already committed to a particular plugin ecosystem.
If you’re comfortable working with a few lines of code—or want more flexibility—we recommend using an open-source player like Video.js in combination with Advanced Ads. This gives you full control over how ads are loaded, when they appear, and how they integrate with your other placements. With Advanced Ads handling the ad logic and display conditions, and the player handling the video rendering, you get a clean, modular setup that’s easy to manage and scale.
This approach is especially useful if video ads are just one part of your monetization strategy. You can target them the same way you do banners and avoid locking yourself into a video plugin that might not meet your long-term needs. In this tutorial, we’ll walk you through how to implement that kind of setup using Advanced Ads and a self-hosted player.
Using a WordPress plugin with built-in VAST support
The easiest way to start using VAST tags on your WordPress site is with a video player plugin that already supports them. These tools handle the heavy lifting: they load the ad, display it in the right position (usually as a pre-roll), and track basic performance data automatically.
Two popular options are FV Player with the FV Player VAST add-on and Elite Video Player, both premium plugins. They allow you to enter a VAST tag directly into their settings and display the ad before, during, or after your main video. The setup varies slightly between plugins—here’s a thorough walkthrough for FV Player with the FV Player VAST add-on (premium).
When using a third-party video plugin, Advanced Ads can still help with overall ad management. You can place videos with ads only in specific conditions, such as on selected posts, in certain categories, or only for users from a particular region with Advanced Ads Pro’s Geo-Targeting feature. If the video plugin outputs a shortcode or block, you can embed it inside an Advanced Ads placement and manage it like any other ad on your site.
That said, keep in mind that you’ll be relying on the video plugin’s ad settings. If you want more flexibility or integration with your ad server, the manual approach in the next section may be a better fit.
Integrate VAST tags manually with Video.js
If you prefer more flexibility or want to avoid relying on third-party video plugins, you can manually embed the VAST-compatible video player Video.js. This method takes a little more effort, but it gives you full control over the player’s behavior and integrates well with Advanced Ads, especially if you’re already using it to manage when, where, and to whom your ads are shown.
What is Video.js?
The lightweight, open-source Video.js is the player itself—not just an add-on or wrapper. It replaces the default HTML5 browser video controls with its own interface and adds features through plugins. Once extended with the Google IMA SDK, it becomes a fully VAST-compatible player, capable of handling pre-roll ads, tracking events, and more.
What is Google’s IMA SDK?
The IMA SDK (Interactive Media Ads Software Development Kit) is provided by Google and handles the heavy lifting of loading, displaying, and tracking video ads from a VAST tag. When integrated with Video.js through the videojs-ima plugin, it ensures that your player follows ad network standards for playback, click tracking, and impression reporting.
How to set up Video.js with the IMA plugin
To get started, you’ll need a self-hosted video file (typically in .mp4 format), a working VAST tag, and Advanced Ads. We’ll create two ads—one for the player code and one for the video and its VAST tag—and assign the one for the player to a header placement. With this clean setup, you can selectively inject the player in posts where you actually want to show videos and place as many videos with VAST tags within the content as needed.
Load the video player
In your page’s header, we’ll add the following code. Here’s what each line does:
video.min.js
is the core Video.js player script, which provides the base video player functionality and custom controls.ima3.js
is Google’s IMA SDK (Interactive Media Ads) script. It enables communication with ad servers, handles VAST parsing, and manages ad playback and tracking.videojs-contrib-ads.min.js
is the Video.js ads framework. This plugin manages the coordination between content and ad playback, ensuring that ads and videos don’t conflict. It is required for all ad plugins.videojs.ima.min.js
is the Video.js plugin that connects the IMA SDK to the Video.js player. It’s the bridge between your player and VAST-based ad delivery.video-js.css
is the Video.js player stylesheet, which styles the video controls, progress bar, and other UI elements.
<script src="https://vjs.zencdn.net/8.10.0/video.min.js"></script>
<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
<script src="https://cdn.jsdelivr.net/npm/videojs-contrib-ads@6.9.0/dist/videojs-contrib-ads.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/videojs-ima@1.8.0/dist/videojs.ima.min.js"></script>
<link href="https://vjs.zencdn.net/8.10.0/video-js.css" rel="stylesheet" />
Code language: HTML, XML (xml)
- Copy the above code.
- In your backend, go to Advanced Ads > Ads and create a new ad.
- Select the Plain Text and Code ad type and give it a clear name.
- Paste the code into the Ad Parameters field and save the ad.
- Go to Advanced Ads > Placements and create a new placement.
- Select the Header Code placement type and give it a clear name.
- Assign the ad to the placement and save it.
If you have a license for Advanced Ads Pro, you can edit the placement and set up targeting with a huge range of Display and Visitor Conditions. For example, you could limit the placement to posts where you actually display videos, loading the player scripts only when they’re needed—try that with a video player plugin.
Load the video and the VAST tags
Next, we’ll add the actual video to your post’s content. Here’s what the following code does:
- Create a Video.js player
The<video>
element is set up with a specific ID, classes for styling, and a source file for the main video. It uses Video.js to replace the default browser controls. - Initialize the Video.js player in JavaScript
videojs(’my-video’)
connects the HTML video element to the Video.js API. - Configure the IMA plugin with a VAST tag
Theima()
method sets up the player to use the Google IMA SDK with your VAST tag URL, enabling ad playback. - Wait for the first user interaction
Theplayer.one(’click’, ...)
function ensures the ad container is initialized only after the user clicks. This satisfies browser autoplay and ad restrictions. - Start playback after ad container setup
Once the user clicks, the ad display container is initialized, and the pre-roll ad starts playing (if one is returned by the VAST tag)—followed by the main video.
<video id="my-video" class="video-js vjs-default-skin" controls preload="auto" width="640" height="360">
<source src="[Path To Your Main Video File]" type="video/mp4" />
</video>
<script>
var player = videojs('my-video');
player.ima({
adTagUrl: '[Path To Your VAST XML File]',
debug: true
});
player.one('click', function () {
player.ima.initializeAdDisplayContainer();
player.play();
});
</script>
Code language: HTML, XML (xml)
- Copy the above code.
- In your backend, go to Advanced Ads > Ads and create a new ad.
- Select the Plain Text and Code ad type and give it a clear name.
- Paste the code into the Ad Parameters field and replace [Path To Your Main Video File] and [Path To Your VAST XML File] with the proper URLs.
- Save the ad.
- Edit the post with your main video, insert an Advanced Ads block at the desired position, and select the ad you just created.
- Save the post.
If you want to show videos with ads in the same place on several posts, consider assigning an ad group containing all video code ads to a site-wide placement and targeting each video code ad to its intended audience segments or content.
This setup shows a pre-roll ad from your VAST tag before the main video starts. Most browsers require a user interaction before playing ads, so the ad is triggered after the first click.
Manual integration is a great option if you want a lightweight, plugin-free solution or if you need tighter control over how your video ads are delivered. It works especially well when combined with Advanced Ads for scheduling, targeting, and output control.
Ran into trouble manually integrating VAST tags with Video.js?
If your VAST tag returns an error or doesn’t load the ad, check your browser’s developer console for CORS errors. Many ad servers block cross-origin requests unless they explicitly allow your domain. If needed for testing, you can also host your own VAST XML file in a PHP wrapper that includes the required CORS headers—we’ll cover that in the next section.
How to create and host your own VAST XML for testing
If you’re like me and love to try things out before fully committing, you’re probably itching to tinker with everything I’ve explained so far. But how do you get a VAST XML file for sandboxing without signing up with a real video ad provider? The good news is that you can easily create and host your own VAST XML file. The bad news… well, let’s make the file first.
When you’re testing your video player setup, it’s often easier to use a simple, self-hosted VAST file rather than relying on ad network tags that might expire, rotate, or require domain approval. Creating your own VAST XML lets you control exactly what ad plays, how long it lasts, and where it links.
At its core, a VAST tag is just an XML file that follows a specific structure. Here’s a basic example that includes a 15-second pre-roll ad using a public test video:
<?xml version="1.0" encoding="UTF-8"?>
<VAST version="3.0">
<Ad id="test-ad">
<InLine>
<AdSystem>Test Ad Server</AdSystem>
<AdTitle>Sample Pre-roll</AdTitle>
<Impression><![CDATA[https://example.com/impression]]></Impression>
<Creatives>
<Creative sequence="1" id="1">
<Linear>
<Duration>00:00:15</Duration>
<TrackingEvents>
<Tracking event="start"><![CDATA[https://example.com/start]]></Tracking>
<Tracking event="complete"><![CDATA[https://example.com/complete]]></Tracking>
</TrackingEvents>
<VideoClicks>
<ClickThrough><![CDATA[https://example.com/clickthrough]]></ClickThrough>
</VideoClicks>
<MediaFiles>
<MediaFile delivery="progressive" type="video/mp4" width="640" height="360">
<![CDATA[https://www.w3schools.com/html/mov_bbb.mp4]]>
</MediaFile>
</MediaFiles>
</Linear>
</Creative>
</Creatives>
</InLine>
</Ad>
</VAST>
Code language: HTML, XML (xml)
To use this file, save it with a .xml extension and upload it to any public folder on your server.
However, this is where things get tricky.
When your video player tries to load the XML file through the IMA SDK, it doesn’t just fetch it quietly in the background. Because this is a cross-origin request made by JavaScript, the browser enforces strict rules: it requires that the server sending the XML explicitly allows your site to access it.
If the server hosting your XML doesn’t include the correct CORS (Cross-Origin Resource Sharing) headers, the browser will block the file—even if it’s technically valid and publicly accessible.
This often results in the dreaded error “Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource…”
That message means the server hosting the VAST XML didn’t send a header like:
Access-Control-Allow-Origin: https://your-site.com
Code language: JavaScript (javascript)
or:
Access-Control-Allow-Origin: *
Code language: HTTP (http)
Unfortunately—and here’s the bad news—, WordPress and most shared hosts don’t send these headers for XML files by default. Even if your XML file is on the same domain, the way the IMA SDK makes the request can trigger a cross-origin check.
To work around this, we recommend a simple fix: rename your VAST XML file to .php, and add the required headers manually. Keep in mind that this is only for sandboxing purposes. Here’s how:
- Create a new PHP file, e.g., “vast-test.php”
- Add this at the top:
<?php
header("Content-Type: application/xml");
header("Access-Control-Allow-Origin: *");
?> - Paste your VAST XML content from before below the PHP block.
- Upload this file to your server into your theme folder or another public directory.
Once hosted, you can use the full URL of this .php file as your adTagUrl
in the player config. The browser will now accept the file without blocking it, and the ad will play as expected.
Self-hosted VAST files are great for sandbox testing, demonstrating to clients, or integrating with ad systems that expect a static endpoint. Just remember to replace the test video URL and links with your actual ad creatives before going live.
For the sake of completeness, here’s the content of your “vast-test.php” for testing:
<?php
header("Content-Type: application/xml");
header("Access-Control-Allow-Origin: *");
?>
<?xml version="1.0" encoding="UTF-8"?>
<VAST version="3.0">
<Ad id="test-ad">
<InLine>
<AdSystem>Test Ad Server</AdSystem>
<AdTitle>Sample Pre-roll</AdTitle>
<Impression><![CDATA[https://example.com/impression]]></Impression>
<Creatives>
<Creative sequence="1" id="1">
<Linear>
<Duration>00:00:15</Duration>
<TrackingEvents>
<Tracking event="start"><![CDATA[https://example.com/start]]></Tracking>
<Tracking event="complete"><![CDATA[https://example.com/complete]]></Tracking>
</TrackingEvents>
<VideoClicks>
<ClickThrough><![CDATA[https://example.com/clickthrough]]></ClickThrough>
</VideoClicks>
<MediaFiles>
<MediaFile delivery="progressive" type="video/mp4" width="640" height="360">
<![CDATA[https://www.w3schools.com/html/mov_bbb.mp4]]>
</MediaFile>
</MediaFiles>
</Linear>
</Creative>
</Creatives>
</InLine>
</Ad>
</VAST>
Code language: HTML, XML (xml)
And here’s the result. Once you click the play icon, the pre-roll ad—Advanced Ads’ 4-second tutorial intro—should start, followed by the main video. Clicking on the ad takes you to example.com, and all tracking events will also be conveyed to that domain. (Main video by Haakon Birkeli via Pexels)
Common problems and troubleshooting
If your video ad setup isn’t working as expected, don’t worry—it usually comes down to one of a few common issues. Here are the most likely culprits, what they look like, and how to fix them.
The video plays, but the ad doesn’t
If your main video loads but no ad appears, the most likely causes are that the VAST tag didn’t return a valid ad, that the ad request was blocked, or that the player wasn’t properly configured to support VAST.
Double-check the adTagUrl for typos and make sure your VAST source is actually returning a video ad. If you’re using a custom VAST XML, open the file in your browser to confirm it loads and is correctly formatted.
The console shows a “Cross-Origin Request Blocked” error
This means the browser refused to load your VAST XML because the server hosting it didn’t include the right CORS headers. Even if your site and the file are on the same domain, the way the IMA SDK requests the file can trigger this restriction. If you’re seeing this error, go back to the previous section and try the PHP workaround with proper headers added at the top.
If you’ve done that and still see errors related to CORS, make sure that your firewall and server settings aren’t restricting access to the PHP-wrapped VAST file or altogether keep you from accessing PHP files directly.
I’m using a YouTube or Vimeo video, and the ad won’t load
That’s because these platforms don’t allow third-party ad injection. If you’re embedding videos from YouTube or Vimeo, you won’t be able to load VAST ads into them. To use VAST, you’ll need to host your own video files (like .mp4) or use a video hosting platform that supports custom players and VAST integration.
If you’ve covered all of the above and something’s still not working, the browser console is your best friend. Open the developer tools (usually F12 or right-click > Inspect > Console), reload the page, and look for warnings or errors related to video, ads, or file loading. Often, the error message will point you in the right direction—even if it looks cryptic at first.
Conclusion
If your goal was simply to test whether a VAST tag plays in a self-hosted video player, you’re already there. If you’re planning to run real ads—whether through an ad network, your own ad server, or affiliate partnerships—you now have a working foundation to build on.
From here, you might explore using Advanced Ads to target video ads by device, user role, or content category or scheduling video ads as part of a larger monetization strategy.
You can also revisit your player choice if your needs change. Plugins with built-in VAST support are convenient, but the manual integration offers more control, especially for developers or those managing larger campaigns.