A custom loading screen displays a branded animation or shimmer skeleton while your app fetches data from the backend. Use a Stack widget with Conditional Visibility controlled by a Page State isLoading boolean. Trigger the boolean on page load, run your Backend Query, then hide the loading overlay when data arrives. This creates a polished user experience instead of a blank screen.
Building a Custom Loading Screen for Data Fetching
Unlike a splash screen that shows on app startup, a loading screen appears while a page fetches data from Firestore or an API. Without one, users see a blank or partially rendered page for several seconds. This tutorial shows you how to build a branded loading overlay that automatically hides when your data is ready.
Prerequisites
- A FlutterFlow project with at least one page that uses a Backend Query
- Basic understanding of Page State variables in FlutterFlow
- A Lottie animation JSON file or icon for the loading indicator (optional)
Step-by-step guide
Add a Page State boolean variable called isLoading
Add a Page State boolean variable called isLoading
Open the page where you want the loading screen. In the right panel, go to Page State and click Add Field. Name it isLoading, set the type to Boolean, and set the default value to true. This variable controls whether the loading overlay is visible. It starts as true so the loading screen shows immediately when the page opens.
Expected result: A boolean Page State variable isLoading with default value true appears in the Page State panel.
Build the page layout using a Stack widget
Build the page layout using a Stack widget
Wrap your page content in a Stack widget. The first child of the Stack is your actual content (Column with your data-bound widgets). The second child is the loading overlay — a Container set to full width and full height with a solid background color (use your Theme background color). Center a Column inside it containing your loading indicator: either a CircularProgressIndicator widget or a LottieAnimation widget with your custom animation file.
Expected result: The Stack shows the loading overlay on top of your content area.
Set Conditional Visibility on the loading overlay Container
Set Conditional Visibility on the loading overlay Container
Select the loading overlay Container in the widget tree. In the Properties Panel, scroll to Conditional Visibility. Set the condition to Page State → isLoading equals true. Now the overlay only appears when isLoading is true. When isLoading becomes false, the overlay disappears and reveals the content underneath.
Expected result: The loading overlay Container only shows when the isLoading Page State variable is true.
Configure the On Page Load action to fetch data and toggle loading state
Configure the On Page Load action to fetch data and toggle loading state
Open the Action Flow Editor for your page's On Page Load trigger. Add your Backend Query action (Query Collection or API Call). After the Backend Query action completes, add an Update Page State action: set isLoading to false. This sequence ensures the loading overlay hides only after data is available. If you have multiple queries, wait for all of them before setting isLoading to false.
Expected result: When the page loads, the loading overlay shows while data fetches, then disappears when the Backend Query completes.
Create a reusable loading Component for other pages
Create a reusable loading Component for other pages
Select your loading overlay Container and right-click → Extract to Component. Name it LoadingOverlay. Add a Component Parameter called isVisible (Boolean, required). Inside the Component, set Conditional Visibility to use the isVisible parameter. Now you can drop this LoadingOverlay Component into any page's Stack and bind isVisible to that page's isLoading state.
Expected result: A reusable LoadingOverlay Component that you can add to any page with a single drag and parameter binding.
Complete working example
1PAGE STRUCTURE:2 Stack3 ├── Column (main content)4 │ ├── Text (heading, bound to query result)5 │ ├── ListView (data list, bound to query result)6 │ └── Button (action)7 └── Container (loading overlay)8 ├── Conditional Visibility: isLoading == true9 ├── Width: double.infinity10 ├── Height: double.infinity11 ├── Color: Theme Background12 └── Column (mainAxisAlignment: center)13 ├── LottieAnimation (loading.json, autoPlay: true, repeat: true)14 └── Text ("Loading...", style: bodyMedium)1516PAGE STATE:17 isLoading: Boolean = true1819ON PAGE LOAD ACTION FLOW:20 1. Backend Query: Query Collection (your_collection)21 → Store result in Page State or local variable22 2. Update Page State:23 → isLoading = false2425NOTES:26 - The loading overlay Container covers the entire Stack27 - Content behind it renders but is hidden by the overlay28 - When isLoading flips to false, overlay disappears instantly29 - For fade transition, use AnimatedContainer in Custom WidgetCommon mistakes when creating a Custom Loading Screen for Your FlutterFlow App
Why it's a problem: Placing the loading indicator inside the Backend Query widget
How to avoid: Place the loading indicator OUTSIDE and ABOVE the query-bound widget in the Stack, controlled by Conditional Visibility on a Page State boolean.
Why it's a problem: Forgetting to set isLoading default to true
How to avoid: Set the default value of the isLoading Page State variable to true so the overlay is visible from the first frame.
Why it's a problem: Not handling Backend Query errors in the loading flow
How to avoid: Add an On Error branch in the Action Flow that sets isLoading to false and shows an error message or retry button.
Best practices
- Use a Lottie animation with your brand colors instead of a generic spinner for a polished feel
- Show shimmer skeleton screens that match your content layout for perceived faster loading
- Always handle the error case — set isLoading to false and show an error state if the query fails
- Extract your loading overlay into a reusable Component for consistency across all pages
- Keep loading animations small (under 100KB Lottie files) to avoid adding to the load time
- Set isLoading default to true so the overlay is visible immediately on page open
- Add a timeout fallback — if loading exceeds 10 seconds, show a retry button
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to create a custom loading screen in FlutterFlow that shows a branded Lottie animation while a Backend Query fetches data. Explain how to use Stack, Conditional Visibility, and Page State to toggle between loading and content states.
Create a page with a Stack. First child is a Column with a heading and ListView. Second child is a full-screen Container with a centered CircularProgressIndicator. I will add Conditional Visibility manually.
Frequently asked questions
What is the difference between a splash screen and a loading screen?
A splash screen shows once on app startup before Flutter initializes. A loading screen shows on any page while data is being fetched from a backend. They serve different purposes and are built differently.
Can I use a GIF instead of a Lottie animation for loading?
Yes. Use an Image widget with the GIF file as the asset. However, Lottie animations are smaller in file size, scalable, and support dynamic color changes.
How do I show a shimmer skeleton loading effect?
Replace the spinner with Container widgets styled to match your content layout (grey rectangles for text lines, grey squares for images). Use a Custom Widget with the shimmer package for the animated gradient effect.
Does the loading screen affect app performance?
Minimally. The Stack renders both layers but the loading overlay is a lightweight Container. Keep Lottie files under 100KB and avoid complex animations for best performance.
Can I show different loading screens for different pages?
Yes. Create multiple loading Components with different animations or skeleton layouts, and use the appropriate one on each page based on the content being loaded.
Can RapidDev help build advanced loading experiences?
Yes. RapidDev can create custom shimmer skeletons matching your exact layout, animated transitions between loading and content states, and error handling with retry logic.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation