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.


implementation("com.github.sanikantv:m3-expressive-paywall:v1.0.0")When to use it
Section titled “When to use it”- 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 on the plan page
Section titled “Open on the plan page”// 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,)Parameters
Section titled “Parameters”| 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.
Customization
Section titled “Customization”The page count is pages.size + 1; the extra page is the plan selection. Pass your own pagerState to control it.
Accessibility
Section titled “Accessibility”- The page indicator announces “Page 2 of 4”.
- Skip and Next are real buttons, so the carousel works without swiping.
Common mistakes
Section titled “Common mistakes”- Treating
onCloseas “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.
Related
Section titled “Related”Built by Sanikant. Set in Google Sans Flex (SIL Open Font License). Not affiliated with Google.