TanStack Start Advanced
IAB GPP
What GPP does
ConsentGPP from c15t/react/gpp installs window.__gpp, the GPP 1.1 CMP
API, and keeps its GPP string in step with the visitor's choices. Prebid.js,
Google Ad Manager and other ad tech read US privacy signals from it.
Turn on GPP
Render ConsentGPP inside ConsentRoot in src/routes/__root.tsx:
ConsentGPP renders nothing. __gpp exists only in the browser: the
component installs it after it mounts and removes it when it unmounts. Apps
that do not import c15t/react/gpp bundle none of the GPP code.
The props are the GPP options listed below, for example
<ConsentGPP usFallback="none" />.
The GPP string follows the policy and location the root loader resolves for the visitor. A US visitor's state comes from the geo headers your host sends; see geography headers if it is missing.
To add the TCF EU section for visitors under an iab policy, set up
IAB TCF as well.
How the policy decides the section
The policy rule c15t matched for the visitor decides whether a section applies. The visitor's location only picks which US section carries it.
| Matched rule and visitor | Section in the GPP string |
|---|---|
iab rule, with IAB TCF set up | tcfeuv2 (ID 2): the TC String the CMP confirmed, unchanged |
iab rule, any visitor, with tcf: false | None; applicableSections is [-1] |
Any other rule with the preferences or opt-out right, US visitor in a state with a section | That state's section, such as usca (ID 8) |
| The same rule, US visitor whose region is unknown or whose state has no section | usnat (ID 7), MSPA US National version 2; none with usFallback: 'none' |
The same rule, usApproach: 'national' | usnat for every US visitor |
A rule without those rights, such as none | None |
A visitor outside the US under any rule other than iab | None |
Every opt-in and opt-out rule has the preferences right, and every
opt-out rule also has opt-out. A none rule has them only if you add
them. A rule that gives the visitor no way to opt out produces no US
section, even when the visitor sends a GPC signal.
State sections exist for California, Colorado, Connecticut, Delaware, Florida,
Iowa, Minnesota, Montana, Nebraska, New Hampshire, New Jersey, Oregon,
Tennessee, Texas, Utah and Virginia. Indiana, Kentucky, Maryland and Rhode
Island are not encoded yet: their published specifications start the section
with a header that the IAB reference implementation does not encode. Visitors
there get the fallback, usnat by default. So does a US visitor whose region
the geo headers did not supply.
The MSPA US National specification describes usnat for MSPA signatories
that chose the national approach. Without mspaMode, c15t reports the
fallback as a transaction the MSPA does not cover (MspaCoveredTransaction: 2), which still carries the opt-outs to vendors such as Prebid.js. If you
reserve usnat for the national approach, set usFallback: 'none'; those
visitors then get no section until their state resolves.
What the US sections report
SaleOptOut,SharingOptOutandTargetedAdvertisingOptOut:1(opted out) when themarketingcategory is not permitted, otherwise2. A refusal, a GPC signal the rule maps tomarketingthroughprivacySignals.gpc, and an opt-in rule without a grant all count.- The opt-out notices:
1(given), since the rule offers an opt-out. - The sharing or processing notice:
1when the rule has thedisclosureright, otherwise2. Gpc: the browser's Global Privacy Control signal, in sections that have a GPC subsection. It is reported even when the rule does not map GPC to a category, so give US rules aprivacySignals.gpcmapping if the opt-outs should follow it too.- Sensitive data and known-child consents:
0(not applicable). c15t has no category for them, so the string states that you do not process sensitive data or knowingly process children's data. If you do, GPP from c15t does not describe your processing; collect and signal that consent separately. MspaCoveredTransaction:2(not covered) unless you setmspaMode.
The notice fields are your attestation, made through the rule's rights: c15t cannot see whether your privacy notice is on the page. Show the notices the rule promises, including a persistent opt-out control.
GPP options
Every field is optional. Pass them in the gpp option, where gpp: true
uses the defaults, as props on ConsentGPP in React, or to mountGPP() in
@c15t/browser.
| Option | Default | Effect |
|---|---|---|
cmpId | the IAB CMP ID c15t holds, else 1 | CMP ID reported by ping. The GPP specification has string creators without a registered ID, including MSPA US National creators, use 1. A TCF EU section needs the registered ID its TC String names. |
usApproach | 'state' | 'state' uses the visitor's state section. 'national' reports usnat for every US visitor; the MSPA reserves it for signatories that chose the national approach. |
usFallback | 'usnat' | Under the state approach, the section for a US visitor whose state is unknown or has no section: 'usnat' or 'none'. |
mspaMode | unset | 'opt-out-option' or 'service-provider'. Set it only if you signed the IAB Multi-State Privacy Agreement; the transaction is then reported as covered. In service provider mode the opt-outs are reported as not applicable. |
optOutCategories | ['marketing'] | Categories whose refusal reports an opt-out of sale, sharing and targeted advertising. |
tcf | true | Include the tcfeuv2 section under an iab policy. It needs IAB TCF set up as well. |
Check the signal
Open the browser console on a page with GPP on and call:
For a California visitor who has not opted out, the result includes
applicableSections: [8], signalStatus: 'ready' and
parsedSections.usca[0].SaleOptOut === 2. After the visitor refuses
marketing, SaleOptOut is 1. __gpp('getField', cb, 'usca.SaleOptOut')
returns the same value. Scripts in iframes reach the API through the
__gppLocator frame and postMessage.
Under an iab rule, parsedSections.tcfeuv2 uses the field names of the
IAB Europe TCF section, such as PurposeConsent, VendorConsent and
PubRestrictions. getSection and getField answer null for tcfeuv2,
as the IAB reference implementation does: TCF vendors read consent from
events, not on demand.
signalStatus stays 'not ready' while the policy is pending, while the
banner or dialog is open, while an iab rule has no confirmed TC String,
and while a new TC String is decoded. Listeners added with
addEventListener get signalStatus: 'not ready', then cmpDisplayStatus
and sectionChange events, then signalStatus: 'ready'.
Ad tags that load before c15t
c15t installs __gpp in the browser once consent starts, after it loads the
GPP code. Vendor scripts that call __gpp earlier need a stub. c15t takes over
the calls and listeners a stub queued, whether the stub keeps listeners on
__gpp.events, as the GPP specification's sample does, or returns them from
__gpp('events'), as @iabgpp/stub does. Call initializeGPPStub() from
@c15t/iab/gpp in your first script, or use the IAB's own stub snippet.
When another stub already answers iframes, c15t leaves that to it, so each
iframe call gets one reply.
If a CMP that has already loaded owns __gpp, c15t leaves it in place.
The gpp option reports the conflict to the onError callback,
ConsentGPP logs it, and mountGPP() and createGPP() throw. Run one GPP
CMP per page.
GPP signals what the visitor chose; it does not block scripts. Gate vendor scripts with c15t's script loading as well.