Skip to main content

Anti-Flicker

When DataGrail Consent blocks an A/B testing tool (such as Optimizely, VWO, or AB Tasty) until a visitor's consent is known, the page first renders its original content. Once the tool is allowed to run, it applies its variant and the content visibly changes. This is called flicker.

Anti-flicker hides your page content while consent is being applied, then reveals it once the page is ready. The consent banner stays visible, so visitors can still make their choice while the rest of the page is hidden.

Available on Request

Anti-flicker must be enabled for your account before the setting appears in your container. To request it, contact support@datagrail.io.

When It Helps​

Anti-flicker doesn't wait for the visitor to select a button in the banner. Whether it prevents flicker depends on whether consent already allows your A/B testing tool when the page loads, and on the Reveal the page setting (see Reveal Options):

VisitorDoes Anti-Flicker Prevent Flicker?
Return visitor whose stored consent allows the A/B testing toolYes, with When the A/B testing tool reveals the page. The page stays hidden while the tool loads and applies its variant. With When consent is known, the page is revealed as soon as consent allows the tool to load, before it applies its variant, so flicker can still show.
Visitor in an opt-out region, where the default consent allows the toolYes, with When the A/B testing tool reveals the page, as for return visitors.
First visit in an opt-in regionNo. The tool stays blocked, so the page is revealed with its original content. When the visitor selects Accept, the tool loads and applies its variant on the visible page.

How It Works​

Anti-flicker runs as part of the DataGrail Consent script, together with a head snippet you add to your page. It works in three stages:

StageWhat Happens
HideThe head snippet, placed first in your page's <head>, hides the content you choose (the whole page by default) before the page first appears, using either an opacity or blur effect. When the DataGrail Consent script loads, it takes over from the snippet and applies your published settings. With the default body selector, the DataGrail consent banner and the IAB TCF dialog are never hidden.
RevealThe page is revealed when it is ready, based on the Reveal the page setting (see Reveal Options). If the Manage Inline Scripts plugin is on, the page also waits for it to finish its initial check of the scripts on the page.
TimeoutIf the page is not ready before the timeout, it is revealed anyway. The head snippet has its own timer, so a blocked or broken script can never leave your page hidden.

The page does not wait for the visitor to select a button in the banner. With When consent is known, it is revealed as soon as the consent state that applies to the visitor is known, including first visits, privacy signals such as Global Privacy Control, and policies that don't show a banner. With When the A/B testing tool reveals the page, the page can stay hidden after consent is known, until your A/B testing tool calls the reveal function or the timeout is reached.

Enable Anti-Flicker​

Anti-flicker is configured per container and is off by default. If you don't see the Page-Load Integrations section, anti-flicker hasn't been enabled for your account yet; contact support@datagrail.io. Follow these steps to turn it on:

  1. Navigate to Consent Management, Settings, Containers, and select the container for your site.
  2. In the container details, find the Page-Load Integrations section.
  3. Turn on the Anti-flicker toggle.
  4. Adjust the settings described below. If DataGrail blocks your A/B testing tool's script, set Reveal the page to When the A/B testing tool reveals the page.
  5. Select Save Page-Load Integrations.
  6. Publish your container. Anti-flicker settings take effect only after you publish.
  7. Add the head snippet to your page. See Add The Head Snippet.

Settings​

These settings appear once Anti-flicker is turned on:

SettingDefaultDescription
Element to hide (CSS selector)bodyThe content to hide while consent is applied. With body, everything on the page except the consent banner is hidden. Use a narrower selector, such as #main-content, to hide only the area your A/B tests change. The console rejects a selector whose text targets <html> or <body> itself, and DataGrail Consent turns anti-flicker off on any page where the selector matches <html> or <body>. See Selector Rules.
Elements to keep visible (CSS selector)EmptyContent that should stay visible while the rest is hidden, such as your site header. See Keeping Elements Visible.
Hiding methodHide (opacity)Hide (opacity) makes the content fully transparent. Blur leaves the page layout visible but blurred.
Timeout (ms)4000The longest the page stays hidden, in milliseconds, from 0 to 10000. The page is revealed after this long even if it is not ready. The head snippet includes this value, so copy the snippet again after you change it.
Reveal the pageWhen consent is knownWhen to reveal the page. If DataGrail blocks your A/B testing tool's script, choose When the A/B testing tool reveals the page. See Reveal Options.
A/B testing tool's categorySelect a category (required)Shown only when revealing with your A/B testing tool, and required in that mode. The consent category your A/B testing tool's script is blocked under. Only non-essential categories are listed.

Add The Head Snippet​

DataGrail Consent loads asynchronously with every install type: Google Tag Manager, the embedded deployment loader, and Adobe. Your page can appear before consent.js starts, so anti-flicker needs a small inline snippet in your page's <head> that hides the content before the first paint. Follow these steps to add it:

  1. In your container's Page-Load Integrations section, turn on the Anti-flicker toggle.
  2. Select Save Page-Load Integrations. The snippet appears under Anti-flicker only after you save, and it always reflects your saved settings. If you have unsaved changes, the console shows "This snippet reflects your saved settings. Save to update it."
  3. Publish your container. Publish before you add the snippet to your page.
  4. Copy the snippet from the Anti-flicker snippet box.
  5. Paste the snippet once, as the first element in your page's <head>, directly in the page.
  6. If your site sets a Content Security Policy, add both hashes to your policy. See Content Security Policy.
  7. Publish your site.
Place The Snippet First In The Head

The snippet does nothing unless it runs first in your page's <head>, before the page has appeared. If <body> already exists or the page has already been painted when it runs, it exits without hiding anything. Adding it through Google Tag Manager or another tag manager, or through a CMS footer or body code field, does no harm, but it doesn't prevent flicker either.

If consent.js is blocked or fails to load, the snippet reveals the page when its timeout is reached. If the snippet ends up on a page more than once, DataGrail Consent removes every copy when it reveals the page.

Content Security Policy​

If your site sets a Content Security Policy, the console shows two hashes, such as 'sha256-…', below the snippet. Add them to your policy as follows:

BoxAdd It ToWhy
Content Security Policy script-src hashYour script-src directiveSo the browser runs the snippet.
Content Security Policy style-src hashYour style-src directive, unless it already allows inline stylesSo the browser applies the style the snippet adds. Without it, the snippet runs but hides nothing.

Both hashes change whenever the snippet changes, so update your policy each time you copy the snippet again.

Copy The Snippet Again After Changes​

The snippet is built from your saved settings. After you change the Element to hide, the Elements to keep visible, the Hiding method, or the Timeout (ms), follow these steps:

  1. Select Save Page-Load Integrations.
  2. Publish your container.
  3. Copy the snippet again, and replace the old snippet on your page.
  4. If your site sets a Content Security Policy, replace both hashes in your policy.

Changes to Reveal the page and A/B testing tool's category don't change the snippet.

Without The Snippet

Without the snippet, consent.js usually starts after your page has already appeared. In that case, anti-flicker skips hiding rather than hiding a page the visitor can already see, and consent.js logs a console warning. The page doesn't blink, but it isn't protected from flicker either. If you can edit only your tag manager and not the page itself, you can't get flicker-free behavior.

Remove The Snippet When You Turn Anti-Flicker Off

When you turn anti-flicker off, remove the snippet from your page as well. A leftover snippet still hides your page on each load until DataGrail Consent loads and removes it, or until the snippet's timeout is reached if DataGrail Consent doesn't load.

Reveal Options​

The Reveal the page setting controls what the page waits for before it is revealed:

OptionReveals The PageBest For
When consent is knownAs soon as the visitor's consent state has been appliedSites where your A/B testing tool already runs before consent is applied, or independently of it, for example because DataGrail doesn't block its script. No code changes needed.
When the A/B testing tool reveals the pageWhen your A/B testing tool calls the reveal function after applying its variantSites where DataGrail blocks your A/B testing tool's script until consent allows it.

If DataGrail blocks your A/B testing tool's script, choose When the A/B testing tool reveals the page and call the reveal function. With When consent is known, the page is revealed at the same moment consent allows the tool to load, so the time the tool needs to download and apply its variant happens on the visible page. When consent is known only hides the page until consent is applied, which is enough only when your tool already runs before or independently of consent.

Reveal With Your A/B Testing Tool​

When you choose When the A/B testing tool reveals the page, your A/B testing tool must tell DataGrail Consent when it has finished applying its variant. Call the reveal function from your tool's "variant applied" or "experiment activated" callback. Use optional chaining (?.), so the call does nothing instead of throwing an error if the callback runs before consent.js has loaded:

// Call this once your A/B testing tool has applied its variant
window.DG_BANNER_API?.antiFlicker?.reveal();

The page is revealed right away in these cases, without waiting for the reveal function:

  • The visitor has not consented to the category you selected in A/B testing tool's category. Your A/B testing tool won't run, so there is nothing to wait for.
  • The timeout is reached.

Calling reveal() more than once, or after the page has already been revealed, has no effect. Calling it early only reveals the page sooner. It never allows a blocked script to run.

Deleted Categories

If the category you selected is later deleted from your consent project, the container shows a warning and publishing falls back to When consent is known until you choose another category.

Keeping Elements Visible​

The Elements to keep visible setting exempts content from being hidden. It only applies to elements that the Element to hide setting matches directly:

Element to HideElements You Can Keep Visible
body (default)Direct children of <body>, such as body > header or #site-header when the header is a direct child of <body>
A custom selector, such as .page-sectionElements that also match the custom selector, such as .page-section.hero

An element nested inside hidden content stays hidden, even if it matches Elements to keep visible. This is a limitation of how browsers apply CSS.

You can enter multiple selectors in either field by separating them with commas, for example #site-header, #site-footer.

Selector Rules​

The consent banner and the IAB TCF dialog sit directly inside <body>, so hiding <html> or <body> itself would hide them too. The console checks your selectors when you save and rejects these:

SelectorExampleSaved?
Exactly body (the default)bodyYes. Everything except the consent banner and the IAB TCF dialog is hidden.
An element inside <body>#main-content, body .hero, body > mainYes
A selector whose text targets <html> or <body> itselfhtml, :root, *, body.home, html *, a list that contains body such as body, #promoNo
A selector that starts with an attribute selector or a pseudo-class and has nothing before it[data-content], :is(main), [data-content].heroNo. Add an element type or ancestor, such as main[data-content] or body :is(main).
A selector with {, }, ;, <, or /*, or that ends in \.hero { color: red }No

When Element to hide targets <html> or <body>, the console shows "Hide selector can't target the html or body element itself (use body to hide the whole page)." For the other characters, it shows Hide selector can't contain {, }, ; or < or Hide selector can't contain /* or end with \. Elements to keep visible follows the same character rules.

The save check reads only the selector text, so a class or id that your site puts on <body>, such as .home, can be saved. On pages where it matches <body>, the head snippet hides the whole <body>, including the consent banner, until consent.js loads. consent.js then removes the hide style and logs a console warning, so anti-flicker is off for that page. Use a selector that matches your page content, not <body>.

Broad selectors such as div or body * don't hide the consent banner or the IAB TCF dialog, because both are kept out of the hide rule and render separately from your page's content. They can still hide more of your page than you intend, so use a selector that matches only the content your A/B tests change.

If a selector is invalid in the visitor's browser, anti-flicker turns itself off for that page load rather than hiding the wrong content.

Troubleshooting​

Use these answers to resolve common anti-flicker issues:

Visitors still see flicker

Check the following:

  • The head snippet is on the page, as the first element in <head> and not added through a tag manager. Without it, anti-flicker skips hiding when consent.js loads after the page has appeared. See Add The Head Snippet.
  • The visitor is on a first visit in an opt-in region. The A/B testing tool can't run until the visitor accepts, so it applies its variant on the visible page. See When It Helps.
  • If you use When consent is known and DataGrail blocks your A/B testing tool, the tool applies its variant after the page is revealed. Switch to When the A/B testing tool reveals the page and call window.DG_BANNER_API?.antiFlicker?.reveal() from your tool.
  • Your container has been published since you changed the settings, and you copied the snippet again. See Copy The Snippet Again After Changes.
The snippet is on the page but nothing is hidden

Check the following:

  • The snippet is the first element in <head>, directly in the page. Added later in the page, or through a tag manager or a footer or body code field, it exits without hiding anything.
  • If your site sets a Content Security Policy, it includes the current Content Security Policy script-src hash in script-src and the current Content Security Policy style-src hash in style-src (or style-src allows inline styles). Both hashes change each time the snippet changes.
I can't save my selector, or no snippet appears

If the console shows "Hide selector can't target the html or body element itself (use body to hide the whole page)," change Element to hide to body or to a selector for your page content. See Selector Rules.

If the console shows "No snippet is available for the saved selectors. Change the element to hide or the elements to keep visible, then save.", anti-flicker is on but a saved selector is one the snippet can't use: it contains {, }, ;, or <, or the Element to hide targets <html> or <body> itself. The console rejects these selectors when you save, so this appears only when settings saved before those checks existed contain such a selector. Change Element to hide or Elements to keep visible so they follow the Selector Rules, then save.

The page stays hidden until the timeout

If you reveal with your A/B testing tool, confirm that your tool calls window.DG_BANNER_API?.antiFlicker?.reveal() after applying its variant, and that the A/B testing tool's category matches the category your tool's script is blocked under.

If your A/B testing tool doesn't run on a page, the page waits for the timeout. Consider a shorter timeout. If DataGrail doesn't block your A/B testing tool, you can reveal with When consent is known instead.

My A/B testing tool's own anti-flicker hides the consent banner

Some A/B testing tools include their own anti-flicker feature. Use either your tool's anti-flicker or DataGrail's, not both. If you use your tool's, configure it to exclude the DataGrail consent banner and the IAB TCF dialog with the .dg-consent-banner, .dg-tcf-consent selector. See VWO for an example.

These articles cover related topics:

 

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.