Skip to content

Onboarding paywall carousel for Jetpack Compose

OnboardingPaywall is design 6 of M3 Expressive Paywall. A short HorizontalPager of benefit pages that ends in the plan selection. A Skip button jumps to the plans, and the legal footer appears on the plan page, where buying becomes possible.

Onboarding paywall, light theme
Light
Onboarding paywall, dark theme
Dark
implementation("com.github.sanikantv:m3-expressive-paywall:v1.0.0")
  • The paywall is the last step of your onboarding.
  • You want to explain value before you ask for money.
val pages = listOf(
BenefitPage("Capture every idea", "Write, sketch and save in one tap, even offline.", PaywallIcons.Sparkle),
BenefitPage("Remember on time", "Smart reminders bring notes back when you need them.", PaywallIcons.Bell),
BenefitPage("See your progress", "Weekly insights show how your ideas grow.", PaywallIcons.Insights),
)
OnboardingPaywall(
pages = Sample.pages,
plans = Sample.plans,
legal = Sample.legal,
onPurchase = buy,
onRestore = restore,
onClose = finishOnboarding,
)
// Open straight on the plan page, e.g. when the user taps "Upgrade" later in the app.
val pagerState = rememberPagerState(initialPage = Sample.pages.size) { Sample.pages.size + 1 }
OnboardingPaywall(
pages = Sample.pages,
plans = Sample.plans,
legal = Sample.legal,
onPurchase = buy,
onRestore = restore,
onClose = close,
pagerState = pagerState,
)
Parameter Type Default Description
pages List<BenefitPage> required Benefit pages shown before the plans. Three or four work best.
plans List<PaywallPlan> required Plans on the last page.
legal PaywallLegal required Terms and Privacy URLs for the footer links.
onPurchase (PaywallPlan) -> Unit required Called with the selected plan when the button is tapped. Start your billing flow here.
onRestore () -> Unit required Called from the Restore link.
onClose () -> Unit required Called from the close button.
modifier Modifier Modifier Applied to the paywall’s root.
plansTitle String “Ready to go Pro?” Headline of the plan page.
plansSubtitle String? “Pick a plan to keep everything you just saw.” Line under it.
initialPlanId String? null Plan to preselect.
pagerState PagerState rememberPagerState { pages.size + 1 } Pager state, for example to start on the plan page.

Full signature: OnboardingPaywall in the API reference.

The page count is pages.size + 1; the extra page is the plan selection. Pass your own pagerState to control it.

  • The page indicator announces “Page 2 of 4”.
  • Skip and Next are real buttons, so the carousel works without swiping.
  • Treating onClose as “cancel onboarding”. Usually it should finish onboarding and continue to the free experience.
  • Long benefit copy. One line of title and one or two lines of description per page.

Built by Sanikant. Set in Google Sans Flex (SIL Open Font License). Not affiliated with Google.