Rheo
Consent banner on web app with analytics paused until acceptance
Engineering

Consent-first product analytics for web and mobile apps

A practical checklist for consent-gated product analytics on web and mobile, and how marketing consent for Engage differs from analytics collection.

Regulators and platform policies pushed consent to the front of mobile and web shipping. Product teams still need funnels, experiments, and lifecycle triggers. The mistake is treating one toggle as permission for everything: product analytics, crash reporting, ads, and lifecycle email do not share the same legal or user-expectation bucket.

This post is a engineering-focused checklist for consent-first product analytics on React Native and web, plus how Rheo Engage fits when you need marketing consent separate from analytics. Honest scope: Rheo is not legal advice. Patterns here match how growth teams ship in the EU, UK, and US without collecting events into the void: or blasting email before consent exists.

Two consents, two pipelines

PurposeTypical legal basis (varies by region)User expectationRheo surface
Product analytics, funnels, A/B metricsLegitimate interest / consent (web)"Help improve the app"Analytics SDK after gate
Lifecycle email, promotional pushMarketing consent"Send me offers and tips"Engage automations
Strictly necessaryContract / necessityLogin, billing, securityAlways on

Mixing them creates bugs: Engage fires win-back email to users who only accepted analytics, or web analytics fires before the CMP returns granted.

Rule of thumb: analytics events for measurement can often start after analytics consent (or LI with opt-out, depending on counsel). Engage journeys that promote the product need marketing consent on the profile.

Web: wait for the CMP, then initialize

On web, Rheo and other SDKs should not call init with full tracking until consent is known.

  1. Load app shell with no analytics network calls (or only anonymous, non-identifying pings if counsel approves).
  2. Render CMP (Cookiebot, OneTrust, custom banner).
  3. On analytics: true, initialize Rheo Analytics with your app id.
  4. On marketing: true, enable Engage enrollment and marketing identifiers.
  5. Persist consent version + timestamp on the user record for audit.

Web checklist

StepImplementation note
Block SDK initGuard Rheo.init behind consent callback
Default deniedNo pre-consent events in network tab
Re-consentHandle CMP updates; re-run init or flush queue
GPC / DNTRespect signals your policy promises
Session replay (if any)Stricter gate than page views: often separate toggle
User lands → CMP shown → analytics granted → Rheo.init({ analytics: true })
                         marketing granted → engage.enableMarketing()

If you use PostHog or Mixpanel on web in parallel, apply the same gate so you do not leak one vendor before consent while Rheo waits.

Mobile: ATT, GDPR, and in-app privacy screens

Mobile adds App Tracking Transparency (iOS), Google Play Data safety declarations, and in-app privacy settings.

iOS patterns

LayerWhat to gate
ATT promptIDFA-linked ad networks: not always product analytics
In-app privacy centerAnalytics on/off, marketing email on/off
SDK initDelay identifying events until user accepts in-app policy

Product analytics using first-party app instance ids often sits below ATT for many teams, but EU users may still need explicit analytics consent in your privacy UI. Do not conflate "ATT denied" with "no analytics."

React Native checklist

ItemDetail
Single consent moduleExpose getAnalyticsConsent() / getMarketingConsent() to JS
Lazy SDK startNative module no-ops until consent true
Pre-consent queueOptional: queue events locally, flush once: cap queue size
Identify timingCall identify only after account + consent align
Push tokensRegister for push only after marketing consent if pushes are promotional
Deep linksDo not auto-enroll Engage from campaign until marketing consent

Expo and bare React Native share the same rule: native module init order matters. If a third-party SDK auto-starts in AppDelegate, you may leak events before JS consent runs: audit native dependencies.

Rheo Engage automations: trial nudges, win-back email, feature adoption pushes: should check marketing consent (and channel preferences) before send.

Automation typeConsent check
Transactional (receipt, password reset)Usually outside marketing: use your auth/email stack
Lifecycle tips with upsellMarketing
Win-back with discountMarketing
"You stalled on onboarding" product emailOften marketing; counsel may treat differently if purely functional

Sync consent from:

  • Signup checkbox ("Send me product updates")
  • Account settings toggle
  • CMP marketing category on web

When consent is revoked, Engage should suppress future promotional sends and respect unsubscribe on email. Product analytics may continue only if analytics consent remains (region-dependent).

Data minimization for subscription apps

Subscription funnels tempt you to collect everything. Consent-first design collects what you use.

EventCollect when…Skip when…
onboarding_step_completedAnalytics consentPre-consent
paywall_viewedAnalytics consentPre-consent
Email address for EngageMarketing + accountLead forms without opt-in
Revenue propertiesOften server-side from RC/StripeDuplicating PAN or raw receipts in client events

Server-side revenue from RevenueCat webhooks reduces client PII and keeps finance-aligned truth.

TestPass criteria
Fresh install, deny allNo Rheo analytics requests in Charles/Proxyman
Grant analytics onlyFunnel events appear; Engage promo does not send
Grant marketingEngage test journey delivers to test user
Revoke marketing mid-journeyNext step suppressed
Web hard refreshConsent read from storage; no double fire

Automate at least one Detox/Maestro flow that asserts network silence before accept.

Rheo in a mixed analytics stack

Teams on Amplitude or PostHog for warehouse analytics sometimes run Rheo for Convert + Engage only. Consent still applies:

  • Mirror consent flags into event properties (analytics_consent: true) for downstream filtering.
  • Do not forward pre-consent events to third parties via integrations.

Experiment dashboard

Operational ownership

RoleOwns
EngineeringSDK gates, init order, consent APIs
Legal / DPOWording, basis per region
GrowthWhich Engage journeys require marketing consent
SupportPrivacy center UX and export/delete requests

Ship a one-page consent matrix linked from your internal wiki before the next major SDK bump.

Consent-first analytics is slower to instrument once and faster forever: fewer incident calls, fewer angry reviews, and Engage that actually respects the checkbox users clicked.

RegionCommon pattern for analyticsMarketing email/push
EU / UKExplicit consent or strict LI with opt-outOpt-in marketing consent
US state lawsDisclosure + opt-out for sale/shareCAN-SPAM unsubscribe
Apple platformsPrivacy nutrition labels match behaviorATT for tracking across apps

Align in-app copy with App Store and Play Data safety forms: reviewers compare screenshots to network traffic.

When analytics is "off" but product still works

Users who deny analytics consent should still complete onboarding and purchase. Rheo Convert flows render; only measurement and optional Engage segments that depend on denied events should degrade gracefully. Log locally in dev when a funnel step cannot be recorded so PMs do not confuse "zero conversion" with "zero traffic."

Start for free and configure Analytics and Engage with separate consent hooks in your React Native or web app.