Do you want to make your consent choices again?

The new granular amp-consent - demo and explanation!

The consent dialog will appear when you first visit the page. It won't reappear after you've saved consent choices. To remove those consent choices, if you use Chrome DevTools, visit the Application tab. On the left, under Storage, you'll see an entry called Local Storage. Look for a key that begins with amp-store:{xxx}, remove that, and refresh the page.

The AMP team has expanded amp-consent so that it can handle granular consent. amp-consent was created to allow users to make a consent choice on a web domain. The site developer could mark components on a page to only be activated after the user made a positive consent choice.

This global consent still exists! Now, granular consent is possible as well. This means the user can make a set of choices for a domain - not just one. The new granular consent exists alongside the existing global consent. Normally you won't want to use these in conjunction, but granular consent reuses parts of the global consent API. Read on.

Getting started

First, you'll want to define a set of consent choices that your users can make. We'll call those purposes.

Then you'll want to set up your <amp-consent> component. That looks like this:

<amp-consent layout="nodisplay" id="siteConsent">

The id gives you a way to access this component through actions. The id is mandatory, and a page can contain at most one <amp-consent>.

Configuration

The <amp-consent> needs to contain a consent configuration object that defines its behavior. That will look something like this:

 
      <script type="application/json">
        {
          "consentInstanceId": "consent1",
          "consentRequired": true,
          "promptUI": "consent-dialog",
          "postPromptUI": "reprompt-dialog",
          "uiConfig": {
            "overlay": true
          },
          "purposeConsentRequired": ["purpose-analytics", "purpose-marketing"]
        }
      </script>
    

Let's look at the keys in this object.

consentInstanceId: mandatory. You won't use this unless you're calling a server, such as a server belonging to a consent management provider (CMP). amp-consent does incorporate this string into the key it uses to store consent information in local storage.

consentRequired: optional. If this is true, the components you specify are blocked until consent is given. It can also be remote or false, which are useful with CMPs.

promptUI: mandatory. You'll want to create a dialog that the user can use to make consent choices. Specify the id of that DOM element here.

purposeConsentRequired: optional. An array containing purpose types. Until the user has made a consent choice for each, the consent dialog will appear every time they visit a page on this domain that contains an <amp-consent>. To make every consent type optional, you can either set this to an empty array or omit it entirely.

The consent dialog

This will typically contain a set of inputs, often checkboxes - and a couple of buttons. The inputs will let the user make consent choices, and the buttons will let them save their choices, save/reject everything, or simply dismiss the dialog.

Setting consents for individual purposes

When the user makes a consent choice, use the setPurpose action to temporarily store that information. Use it like this:

setPurpose({purpose type}={boolean value}

For example, if your user tells you they want to refuse marketing cookies, you might want to set a purpose called purpose-marketing to false. You'd do it like this:

setPurpose(purpose-marketing=false)

You'd apply this action to the id of your <amp-consent> component. Here's how that might look on a typical checkbox:

<input on="change:consent1.setPurpose(purpose-marketing=event.checked">

To set the consent state for all purposes for which the user has not made a choice, use the special purpose value purposeConsentDefault.

Actions that dismiss the dialog

There are also three actions you can use to let the user complete their choices. These are the same actions you'd use to deal with global consent, so they require a bit of explanation.

Of course, your user may make a selection for some consent purposes, but not all of them. You can set their choice for the remaining consent purposes by passing accept or reject an argument: (purposeConsentDefault={false|true}.

Normally you'll probably want to do something like the following:

    <button on="tap:consent1.accept(purposeConsentDefault=false)">
      Save
    </button>
    <button on="tap:consent1.dismiss">
      Dismiss
    </button>

accept(purposeConsentDefault=false) will accept the consent choices the user has made and reject the rest.

Note that after you save the user's choices with accept or reject actions, the changes will apply on the page immediately. This means that any components that have blocked pending user consent will be unblocked right away. However, changes made after a reprompt action are not applied until the user reloads the page. This avoids confusion caused by blocked components being suddenly unblocked, etc. If this behavior is confusing for your users, however, let us know by filing an issue on github.

Debugging hints

<amp-consent> stores the user's choices in local storage. If you use Chrome DevTools, visit the Application tab. On the left, under Storage, you'll see an entry called Local Storage. Click the arrow to expand that and see what's stored for the current domain. You'll see a key called amp-store:{xxx}, where {xxx} is that domain. The value contains the JSON AMP has stored there, base64-encoded.

To decode that, go to the Console and enter atob(localStorage.getItem('amp-store:{xxx}')), again substituting the domain for {xxx}. You'll see a bunch of JSON. Inside there, you'll see any consent types the user's accepted with the value 1, and any types they've rejected with the value 2.