How to integrate UniConsent CMP SDK for Flutter with mobile apps

UniConsent CMP is a package for handling GDPR IAB TCF 2.3 consent management in Flutter apps. You can find a demo app integrated with UniConsent CMP in the "uniconsent_demo" directory.

Prerequisites

  • UniConsent CMP plan with Mobile app support
  • UniConsent CMP SDK package (request from support)

Getting started

To include the UniConsent package in your Flutter project, add it as a dependency in your pubspec.yaml file:

dependencies:
  uniconsent:
    path: ../uniconsent

Then, sync the dependency by running the following command:

flutter pub get

Before integrating the SDK, customize the consent banner appearance in the UniConsent Dashboard to match your brand and optimize consent rates.

Step 1: Brand Styling in Dashboard

Go to Projects → Select your Project → Settings → Step 5: UI & Style Settings to configure:

  • Main Button Colour — Set the primary action button color to match your brand
  • Main Button Text Colour — Adjust text color on the primary button for readability
  • Background Colour — Set the banner background color to blend with your app
  • Text Colour — Ensure body text has appropriate contrast

Step 2: Advanced Styling with Custom CSS (Optional)

For more precise control, add custom CSS in the CSS Content field under Step 5. This is recommended to make the banner feel native to your app and achieve the best consent rate:

/* Example: Style the accept button to match your brand */
.unic-btn-accept {
  background-color: #4CAF50;
  border-radius: 8px;
  font-weight: 600;
}

/* Example: Adjust banner font */
.unic-banner {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Example: Make the reject button less prominent */
.unic-btn-reject {
  background-color: transparent;
  border: 1px solid #ccc;
  color: #666;
}

Tip: A well-branded consent UI that feels native to your app typically achieves higher consent rates. Users are more likely to engage positively with a banner that matches the look and feel they expect.

Usage

To use the UniConsent CMP in your app, follow these steps:

Initialize the CMP with an App ID from your account manager:

// Init CMP with appId
UniConsent.instance.setAppId("YOUR_APP_ID_CHANGE_THIS");
// Set language (Optional)
UniConsent.instance.setLanguage("EN");

Display the CMP UI:

// Display CMP as full-screen page (default)
UniConsent.instance.launchCMP(context);

// Display CMP as a modal bottom sheet
UniConsent.instance.launchCMP(context, displayMode: CMPDisplayMode.modalSheet);

// Display CMP as a center dialog
UniConsent.instance.launchCMP(context, displayMode: CMPDisplayMode.dialog);

Event Handler

Listen for SDK lifecycle events with subscribe(). This is the recommended way to know when the UI is displayed and when it is closed.

Available events (CMPEventType):

  • CMPEventType.uiDisplay — Consent UI is displayed
  • CMPEventType.uiClose — Consent UI is closed
UniConsent.instance.subscribe((event) {
  switch (event.type) {
    case CMPEventType.uiDisplay:
      print('CMP UI displayed');
      break;
    case CMPEventType.uiClose:
      print('CMP UI closed');
      break;
    default:
      break;
  }
});

Listen for consent changes with an optional callback:

// Display CMP UI with consent change callback
UniConsent.instance.launchCMP(context, onConsentChanged: (info) {
  // Called when the user saves consent choices
  print('Consent updated: ${info?.tcString}');
});

For full control, use buildCMPWidget() to embed the CMP in your own layout:

// Embed in your own widget tree
UniConsent.instance.buildCMPWidget(
  onConsentChanged: (info) { /* ... */ },
  onClose: () { /* dismiss your custom UI */ },
);

Automatically check if consent is needed on app launch:

// Check if consent should be requested (e.g. first visit, or vendor list updated)
final shouldRequest = await UniConsent.instance.shouldRequestConsent();
if (shouldRequest) {
  UniConsent.instance.launchCMP(context);
}

Get the tcString if required:

// Get tcString
final info = await UniConsent.instance.getConsentInfo();
print(info?.tcString);

Read the consent status:

// Read consent status
final info = await UniConsent.instance.getConsentInfo();
if (info is ConsentInfo &&
    info.purposeConsents.contains(DataUsagePurpose.useLimitedDataToSelectAds)) {
  // do something
}

Reset consent status if required:

// Clear all consent data
await UniConsent.instance.clearAll();

If your app opens a WebView that loads a web page with the UniConsent CMP tag, you can pass the native consent status so the CMP tag recognises existing consent and does not show the banner again.

import 'package:webview_flutter/webview_flutter.dart';
import 'package:uniconsent/uniconsent.dart';

final controller = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted)
  ..setNavigationDelegate(NavigationDelegate(
    onPageStarted: (url) async {
      // Inject consent at page start, before CMP tag runs
      await UniConsent.instance.syncConsent(controller);
    },
  ))
  ..loadRequest(Uri.parse('https://example.com'));

Exported types

The following types are available when importing package:uniconsent/uniconsent.dart:

  • UniConsent — main SDK singleton
  • UniConsentInfo — base consent data (sdkId, tcString, gdprApplies, vendorListVersion, etc.)
  • ConsentInfo — extends UniConsentInfo with purpose-level consent lists
  • DataUsagePurpose — enum of IAB TCF 2.3 purpose IDs
  • KVDBKeys — IAB TCF storage key constants (e.g. KVDBKeys.tcString, KVDBKeys.purposeConsents)
  • CMPDisplayMode — enum for display style (page, modalSheet, dialog)
  • CMPEventType — enum for lifecycle events (sdkInit, ready, uiDisplay, uiClose)
  • CMPEvent — event object with a type property
  • CMPEventCallback — typedef for the subscribe() callback
  • LogLevel — debug / prod
  • ConsentCallback — typedef for the onConsentChanged callback
  • UniConsentCMPContent — the core CMP widget for custom layouts

Notes

  1. Users should have the ability to access a "Privacy Settings" button or link in the settings section of your application in order to open the CMP UI.
  2. You can utilize the shouldRequestConsent() function to check whether you should request new consent based on the status. Display the CMP UI as needed when a user opens the application.