Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Create a Custom Terms of Service Screen for Your FlutterFlow App

Create a terms of service screen using a SingleChildScrollView with a RichText widget for formatted legal content. Add an I Agree checkbox bound to Page State that enables a Continue button via Conditional property. On acceptance, update the user's Firestore document with tosAccepted and tosAcceptedAt fields. Gate app access by checking this field on home page load and redirecting unaccepted users back to the TOS page.

What you'll learn

  • How to build a scrollable formatted text page using RichText and SingleChildScrollView
  • How to create an I Agree checkbox that enables the Continue button
  • How to store TOS acceptance in Firestore with a timestamp
  • How to gate app access on TOS acceptance with an On Page Load check
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read15-20 minFlutterFlow Free+March 2026RapidDev Engineering Team
TL;DR

Create a terms of service screen using a SingleChildScrollView with a RichText widget for formatted legal content. Add an I Agree checkbox bound to Page State that enables a Continue button via Conditional property. On acceptance, update the user's Firestore document with tosAccepted and tosAcceptedAt fields. Gate app access by checking this field on home page load and redirecting unaccepted users back to the TOS page.

Building a Terms of Service Screen in FlutterFlow

App stores and regulations often require users to accept terms of service before using your app. This tutorial builds a professional TOS screen with scrollable formatted text, a checkbox agreement, and Firestore tracking. You will also learn how to prevent users from accessing the app without accepting.

Prerequisites

  • A FlutterFlow project with Firebase or Supabase authentication configured
  • A users collection in Firestore with a document per user
  • Your terms of service text ready (or placeholder text for testing)
  • Basic understanding of Page State and Action Flow in FlutterFlow

Step-by-step guide

1

Create the TOS page with a SingleChildScrollView layout

Add a new page called TermsOfServicePage. Set the page scaffold body to a Column. Inside the Column, add a SingleChildScrollView as the first child (set it to Expanded so it fills available space). Inside the scroll view, add a Padding widget (16px all sides), then a RichText widget. The RichText lets you format headings in bold, body text in regular weight, and numbered lists — all within one text block. Below the SingleChildScrollView (still inside the outer Column), add a Divider, then a Row for the checkbox and button.

Expected result: A page layout with scrollable text area on top and a fixed checkbox/button row pinned at the bottom.

2

Format the legal text using RichText with styled spans

Select the RichText widget. In the Properties Panel, click Edit Rich Text. Add text spans for each section: set section headings like '1. Acceptance of Terms' to Bold weight and a larger font size (18px). Set body paragraphs to Regular weight at your Body Medium size (14px). Add line breaks between sections. For numbered items, type the numbers manually as part of the text. Use your Theme typography styles for consistent formatting.

Expected result: The TOS text displays with proper heading and body formatting inside the scrollable area.

3

Add the I Agree checkbox and conditionally enabled Continue button

Add a Page State variable called hasAgreed (Boolean, default false). Below the Divider, add a Row. First child: a Checkbox widget bound to hasAgreed via On Changed → Update Page State. Next to it: a Text widget saying 'I have read and agree to the Terms of Service'. Second row item: a Button with text 'Continue'. On the Button, set the Conditional property so it is enabled only when hasAgreed is true. When disabled, the button appears greyed out and is not tappable.

Expected result: The Continue button is greyed out until the user checks the I Agree checkbox.

4

Save TOS acceptance to the user's Firestore document

On the Continue button's On Tap action, add an Update Document action targeting the current user's document in the users collection. Set two fields: tosAccepted to true and tosAcceptedAt to the current timestamp (use Global Properties → Current Time). After the update succeeds, add a Navigate action with Replace Route to your home page. Using Replace Route prevents the user from pressing Back and returning to the TOS screen.

Expected result: Tapping Continue saves acceptance to Firestore and navigates to the home page without back-navigation to TOS.

5

Gate app access by checking TOS acceptance on home page load

On your home page, open the On Page Load action flow. Add a Conditional Action: check if currentUser.tosAccepted equals true. If false (user has not accepted), add a Navigate action to TermsOfServicePage with Replace Route. If true, continue loading the page normally. This ensures users who skip the TOS (e.g., via deep link) are always redirected to accept before using the app.

Expected result: Users who have not accepted TOS are redirected to the TOS page on every home page load attempt.

Complete working example

FlutterFlow TOS Screen Setup
1PAGE: TermsOfServicePage
2
3PAGE STATE:
4 hasAgreed: Boolean = false
5
6WIDGET TREE:
7 Column
8 Expanded
9 SingleChildScrollView
10 Padding (16px all)
11 RichText
12 Span: "Terms of Service" (Bold, 24px)
13 Span: "\nLast updated: March 2026\n\n" (Regular, 12px, grey)
14 Span: "1. Acceptance of Terms\n" (Bold, 18px)
15 Span: "By accessing this app...\n\n" (Regular, 14px)
16 Span: "2. User Obligations\n" (Bold, 18px)
17 Span: "You agree to...\n\n" (Regular, 14px)
18 Divider
19 Padding (16px horizontal, 12px vertical)
20 Column
21 Row
22 Checkbox (bound to hasAgreed)
23 Text: "I have read and agree to the Terms"
24 Button: "Continue"
25 Enabled: hasAgreed == true
26 On Tap:
27 1. Update Document: users/{uid}
28 tosAccepted = true
29 tosAcceptedAt = Current Time
30 2. Navigate (Replace Route): HomePage
31
32HOME PAGE ON PAGE LOAD:
33 1. Conditional: currentUser.tosAccepted != true
34 Navigate (Replace Route): TermsOfServicePage

Common mistakes when creating a Custom Terms of Service Screen for Your FlutterFlow App

Why it's a problem: Using a plain Text widget for long legal content

How to avoid: Use a RichText widget inside a SingleChildScrollView. RichText supports mixed formatting within one text block, and SingleChildScrollView enables scrolling.

Why it's a problem: Using Navigate To instead of Replace Route after TOS acceptance

How to avoid: Use Navigate with Replace Route so the TOS page is removed from the stack. The home page becomes the new root.

Why it's a problem: Hardcoding TOS text directly in the widget tree

How to avoid: Store TOS content in a Firestore document and fetch it via Backend Query. Update the text in Firestore without touching the app.

Best practices

  • Store TOS content in Firestore so you can update it without republishing the app
  • Record the acceptance timestamp alongside the boolean for legal audit trails
  • Use Replace Route navigation after acceptance to prevent back-button return to TOS
  • Check TOS acceptance on the home page On Page Load to catch all entry points
  • Include a version field on the TOS document and re-prompt acceptance when the version changes
  • Add a link to the TOS page in your app's settings screen for users to review later
  • Keep the checkbox and button visible at the bottom without scrolling — only the text should scroll

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I need to build a terms of service screen in FlutterFlow with formatted scrollable text, an I Agree checkbox that enables a Continue button, Firestore acceptance tracking with timestamp, and a home page check that redirects unaccepted users. Provide the full widget tree and action flow.

FlutterFlow Prompt

Create a new page called TermsOfServicePage with a Column layout. Add a scrollable text area at the top taking most of the screen, a divider, then a row with a checkbox and a button at the bottom.

Frequently asked questions

Do I legally need a terms of service screen?

Both Apple App Store and Google Play Store require apps to have accessible terms of service. While the legal specifics depend on your jurisdiction, having a TOS screen is a best practice for any published app.

How do I update the TOS without requiring a new app version?

Store the TOS text in a Firestore document. Update the text there, and the app fetches the new version automatically. Add a version field to re-prompt acceptance when major changes occur.

Can I make the checkbox disabled until the user scrolls to the bottom?

Yes, but it requires a Custom Widget with a ScrollController that detects when the user reaches the bottom and then enables the checkbox via a callback. The built-in ScrollView does not have this feature natively.

Should I show TOS before or after account creation?

Best practice is to show TOS during sign-up before creating the account. This way you have consent before storing any user data. Alternatively, show it immediately after first login.

How do I handle TOS acceptance for existing users after an update?

Add a tosVersion field to the user document. When you update TOS, increment the version in Firestore. On home page load, compare the user's accepted version to the current version and redirect to TOS if outdated.

Can RapidDev help with legal compliance in my app?

RapidDev can build the technical infrastructure for TOS, privacy policy, and consent management in your FlutterFlow app. For the legal text itself, consult a lawyer.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.