Skip to main content

Progressive Consent

Some embedded content, like YouTube videos or social media widgets, loads third-party trackers as soon as the page renders. Progressive consent lets you block that content behind a placeholder and only load it after the visitor explicitly grants consent. This approach is especially useful for meeting opt-in requirements under regulations like GDPR.

This guide walks through implementing progressive consent using DataGrail's ScriptControl plugin and custom services.

How It Works

Progressive consent follows a three-step pattern:

  1. Replace the embedded content (e.g., a YouTube <iframe>) with a static placeholder that explains why the content is blocked.
  2. Capture consent for the specific service when the visitor selects an action (e.g., "Accept & Play").
  3. Load the content dynamically once consent is confirmed.

DataGrail handles step 2 through custom services and the DG_BANNER_API, while your development team implements the placeholder and dynamic loading logic.

Create a Custom Service

Before writing any code, you need a custom service in DataGrail to represent the embedded content you want to gate behind consent.

  1. Navigate to the Tracking Services page in DataGrail Consent.
  2. Select Add Service in the top right.
  3. Specify a name (e.g., "YouTube Video"), vendor, domain, and category for the service. Note the category you assign — you will use it when wiring up consent in your code.
  4. Select Add Service and copy the newly-created service's ID (data-consent-id). You will need this ID if you implement the Block Associated Scripts section later in this guide.
Cross-Container Availability

Custom services are shared across all your active consent containers upon publishing. The same data-consent-id value can be used across all your containers without duplication.

Implement the Placeholder

Replace the standard embed code with a placeholder element. The example below demonstrates this for a YouTube video, but the same pattern applies to any third-party embed.

<div id="video-container"
style="width:560px; height:315px; background:#000; color:#fff;
display:flex; align-items:center; justify-content:center;">
<div id="consent-prompt">
<p>To watch this video, please accept YouTube cookies.</p>
<button id="enable-video">Accept & Play</button>
</div>
</div>

This container acts as a visual stand-in for the video. No requests are made to YouTube until the visitor takes action.

Because progressive consent handles content loading dynamically, you should block page reloads to prevent DataGrail from refreshing the page when consent preferences change. Without this, granting consent for the embed would trigger a full page reload instead of loading the content inline.

DataGrail Consent manages preferences at the category level (e.g., Marketing, Functional, Performance), not at the individual service level. When you created the custom service, you assigned it a category. The code below uses that category to check and grant consent.

Use the DG_BANNER_API to grant consent for the service's category when the visitor selects the action button, then dynamically inject the embed.

<script>
// Replace with the category your custom service belongs to.
// Valid values: 'marketing', 'functional', 'performance'
var CATEGORY = 'marketing';
var CATEGORY_KEY = 'dg-category-' + CATEGORY;

// Grant consent and load the video when the button is selected
document.getElementById('enable-video').addEventListener('click', function () {
var currentPrefs = window.DG_BANNER_API.getConsentPreferences();
var updatedOptions = currentPrefs.cookieOptions.map(function (opt) {
if (opt.gtm_key === CATEGORY_KEY) {
return Object.assign({}, opt, { isEnabled: true });
}
return opt;
});
window.DG_BANNER_API.setConsentPreferences(
Object.assign({}, currentPrefs, { cookieOptions: updatedOptions }),
{ runPreferenceCallbacks: false }
);
renderVideo();
});

// Dynamically inject the embed
function renderVideo() {
var container = document.getElementById('video-container');
container.innerHTML =
'<iframe width="560" height="315" ' +
'src="https://www.youtube-nocookie.com/embed/VIDEO_ID?autoplay=1" ' +
'frameborder="0" allowfullscreen></iframe>';
}

// Auto-load if the visitor already consented in a previous session
window.dgEvent = window.dgEvent || [];
window.dgEvent.push({
event: 'initial_preference_callback',
params: function (preferences) {
var options = preferences.consentPreferences.cookieOptions;
var category = options.find(function (opt) { return opt.gtm_key === CATEGORY_KEY; });
if (category && category.isEnabled) {
renderVideo();
}
}
});

// Re-check when the visitor updates preferences via the banner
window.dgEvent.push({
event: 'preference_callback',
params: function (preferences) {
var options = preferences.consentPreferences.cookieOptions;
var category = options.find(function (opt) { return opt.gtm_key === CATEGORY_KEY; });
if (category && category.isEnabled) {
renderVideo();
}
}
});
</script>

This approach uses DataGrail's callback system instead of native browser events, which ensures the consent check works regardless of script load order.

Replace VIDEO_ID with the YouTube video identifier. Update CATEGORY to match the category you assigned to the custom service in the DataGrail portal.

Category-Level Consent

Granting consent for a category enables all services in that category, not just the one tied to the placeholder. For example, enabling the Marketing category also enables other marketing services. This is by design — DataGrail's consent model operates at the category level to align with how consent regulations define purposes of data processing.

Privacy-Enhanced Mode

Use YouTube's privacy-enhanced domain (youtube-nocookie.com) in the embed URL. This prevents YouTube from setting cookies on the visitor's browser until they interact with the video player.

Block Associated Scripts

If your embed also loads a JavaScript API (e.g., the YouTube IFrame Player API), use ScriptControl to prevent the script from executing until consent is granted.

Modify the script tag to use type="text/plain" and add the data-consent-id attribute:

Before:

<script type="text/javascript"
src="https://www.youtube.com/iframe_api">
</script>

After:

<script type="text/plain"
data-consent-id="YOUR_YOUTUBE_SERVICE_ID"
src="https://www.youtube.com/iframe_api">
</script>

This ensures the script remains inert until DataGrail detects a valid consent preference for the service.

Verify the Implementation

After deploying your changes, confirm that third-party requests are properly blocked until consent is granted.

  1. Open your site in an incognito or private browser window to start without existing consent preferences.
  2. Open the browser console and confirm that consent has not yet been granted for the category tied to your custom service:
    window.DG_BANNER_API.categoryEnabled('marketing')
    This should return false. Replace marketing with the category you assigned to the custom service.
  3. Verify that the placeholder is visible and no requests to the third-party domain (e.g., youtube.com) appear in the Network tab.
  4. Select the action button (e.g., "Accept & Play") and confirm that the embed loads. Run categoryEnabled('marketing') again to verify it now returns true.
  5. Refresh the page and verify that the embed loads automatically based on the stored consent preference.
  6. If you also implemented the Block Associated Scripts section, run the following to confirm your scripts are managed by ScriptControl:
    window.DG_BANNER_API.plugins.scriptControl.managedScripts()
DataGrail Privacy Inspector

Install the DataGrail Privacy Inspector Chrome extension for a streamlined view of all network requests and consent state on your site.

Applying to Other Embeds

The placeholder pattern is not limited to YouTube. You can apply progressive consent to any third-party embed that loads trackers, including:

Embed TypeExample DomainUse Case
Social media widgetsplatform.twitter.comEmbedded tweets or follow buttons
Map providersmaps.googleapis.comEmbedded Google Maps
Chat widgetswidget.intercom.ioCustomer support chat
Analytics dashboardslookerstudio.google.comEmbedded reports

For each embed, create a separate custom service in DataGrail, build a placeholder, and follow the same consent wiring pattern described above.

Troubleshooting

Embed loads before consent is granted

Verify that you have replaced the original embed code with the placeholder. If the <iframe> or <script> tag is still present in the page source, the browser will load it regardless of consent state. Also confirm that associated scripts use type="text/plain" with the correct data-consent-id.

Embed does not load after granting consent

Open the browser console and run window.DG_BANNER_API.getConsentPreferences() to confirm that consent was recorded for the correct category. You can also run window.DG_BANNER_API.categoryEnabled('marketing') (replacing marketing with your category) to quickly check the status. Ensure the CATEGORY_KEY in your placeholder logic matches the category assigned to the custom service in the DataGrail portal.

Consent resets on every page load

This can occur when testing in incognito mode with cookies cleared, or when the DataGrail Consent script has not fully loaded before your placeholder logic runs. Make sure you are using DataGrail's callback system (initial_preference_callback and preference_callback) as shown in the implementation example above, rather than native browser events like window.addEventListener.

 

Need help?
If you have any questions, please reach out to your dedicated Account Manager or contact us at support@datagrail.io.

Disclaimer: The information contained in this message does not constitute as legal advice. We would advise seeking professional counsel before acting on or interpreting any material.