Consenti
Tutorial — Frontend + Backend — Step 7 of 9

Gate a Script

Load a third-party script only once consent is granted.

Everything from the frontend-only tutorial works identically here — gating reacts to the widget's own consent state, whether or not the backend is connected. Pick whichever fits what you're gating.

ConsentScript — inject/remove a <script> tag, keyed to one cookie

ts
import { ConsentScript } from '@consenti/ui'

new ConsentScript({
  cookieId: 'analytics',
  widget,
  src: 'https://cdn.example.com/analytics.js',
  onLoad: () => console.log('Analytics loaded'),
  onRevoke: () => console.log('Analytics removed'),
})

CategoryScript — same, keyed to a whole category

ts
import { CategoryScript } from '@consenti/ui'

new CategoryScript({
  categoryId: 'marketing',
  widget,
  src: 'https://example.com/ad-pixel.js',
})

ConsentAction / CategoryAction — callback instead of a script tag

ts
import { ConsentAction, CategoryAction } from '@consenti/ui'

new ConsentAction({
  id: 'analytics',
  widget,
  onGrant: () => analyticsSdk.optIn(),
  onDeny: () => analyticsSdk.optOut(),
})

new CategoryAction({
  id: 'marketing',
  widget,
  onGrant: () => adSdk.enableAll(),
  onDeny: () => adSdk.disableAll(),
})

scanConsentScripts — declarative, zero-JS gating

html
<script type="text/plain" data-consenti-category-script="marketing" src="https://example.com/pixel.js"></script>
ts
import { scanConsentScripts } from '@consenti/ui'

scanConsentScripts(widget)

Bonus — the same pattern on the backend

Since a backend is connected in this tutorial, you can react to grant/deny transitions server-side too — useful for server-only integrations (a CRM, an ad platform's server-to-server API) that have no <script> tag to gate. There is no server equivalent of ConsentScript/CategoryScript— injecting a tag only makes sense in a browser DOM the server doesn't have.

ts
import { createConsenti, ConsentAction, CategoryAction } from '@consenti/api'

const { eventBus, services } = createConsenti({ /* ... */ })

new ConsentAction({
  id: 'analytics',
  eventBus,
  onGrant: ({ visitorId }) => crm.optIn(visitorId),
  onDeny: ({ visitorId }) => crm.optOut(visitorId),
})

new CategoryAction({
  categoryId: 'marketing',
  eventBus,
  profiles: services.profile, // resolves the category's cookie ids per profile
  onGrant: ({ visitorId }) => adsPlatform.optIn(visitorId),
  onDeny: ({ visitorId }) => adsPlatform.optOut(visitorId),
})

Full reference in UI Events and API Events.