AI consent screen
ProReact Native · ExpoA consent screen shown before personal data reaches a third-party AI service: it names the provider, lists what is sent and what is not, has an optional age tick, and offers a visible way to decline.
Installation
$ npx shadcn@latest add @goodui-native-pro/ai-consent-screenThen run npx expo install --fix so react-native-reanimated match your Expo SDK. Files land in components/goodui-native/ai-consent-screen.
Pro screens install from the license-gated @goodui-native-pro registry. Setup: Pro access.
Usage
// app/consent.tsx
import { router } from "expo-router";
import { AiConsentScreen } from "@/components/goodui-native/ai-consent-screen/ai-consent-screen";
export default function Consent() {
return (
<AiConsentScreen
provider="Acme AI"
sent={["The photo you pick", "Your prompt"]}
notSent={["Your contacts", "Your other photos"]}
minimumAge={18}
onAllow={() => {
saveConsent(true); // Persist it yourself, with the provider name and the date.
router.replace("/studio");
}}
onDecline={() => router.replace("/limited")}
onPrivacy={() => openPrivacyPolicy()}
/>
);
}When to use
- Before the first call that sends a photo, prompt or other personal data to an outside AI service.
- Asking again after the provider or the data you send changes.
- AI that runs fully on the device: nothing leaves the phone, so there is nothing to consent to.
- As a replacement for a privacy policy: pass onPrivacy and link to yours.
- Verifying age: the tick is a self-declaration, not a check.
API reference
| Prop | Type | Default |
|---|---|---|
| provider* The AI service that receives the data, by name. Stores expect it spelled out. | string | — |
| sent* Short lines: "The photo you pick", "Your prompt". | string[] | — |
| notSent* Short lines: "Your contacts", "Your other photos". | string[] | — |
| minimumAge Asks for an age tick before Agree. Omit for no age gate. | number | — |
| providerMark The glyph at the far end of the flow. | ReactNode | — |
| onAllow* | () => void | — |
| onDecline* | () => void | — |
| onPrivacy | () => void | — |
| labels | Partial<AiConsentLabels> | — |
| style Style for the outer container. | StyleProp<ViewStyle> | — |
| testID Identifier for end-to-end tests. | string | — |
Motion and haptics
- Three dots travel a wire from You to the provider on a loop.
- Reduced motion: the dots hold still on the wire.
- Haptic: Agree uses the confirm cue.
- Three animated views on the UI thread. The rest is static.
Accessibility
- The title is a header, the age row is a checkbox with its state, and the privacy line is a link.
- The data-flow picture is hidden from screen readers: the body text says the same thing in words.
Notes for AI
- Name the real provider in `provider`. List only what your app really sends in `sent`; do not soften it.
- The screen stores nothing. Save the answer, and do not send data until onAllow has run.
- Declining should leave the app usable where it can be. Do not loop people back to this screen.
- Translated copy is a starting point. Have a lawyer read it for the markets you ship to.
Related
A permission priming screen: each permission is a list row with a switch that asks the system only when turned on, a reminder preview drops in on a spring when notifications are allowed, a denial shows a banner with a way to Settings, and Not now is one tap away.
A paywall for AI apps with weekly and yearly plans that each carry a credit allowance. The billed amount is always the largest price, weekly math stays in small text, the auto-renew line sits next to the buy button, and Terms, Privacy and Restore are always shown. check-kit fails if a price variant breaks this.
A bottom sheet for reporting generated content: six reasons, a switch to hide similar content, and a thank-you state. It gives AI apps an in-app way to report results, which app stores expect of generated content.