How to Handle Loading State in Remix: Simple Guide
useTransition hook to detect navigation progress and conditionally render a loading indicator. This approach keeps the UI responsive by showing feedback during data loading or page transitions.Why This Happens
When you navigate between routes or submit forms in Remix, the UI might not show any feedback that something is loading. This happens because Remix does not automatically display a loading state, so users may think the app is frozen or slow.
Developers often forget to handle this state explicitly, causing confusion.
import { useLoaderData } from "@remix-run/react"; export default function Posts() { const posts = useLoaderData(); return ( <div> <h1>Posts</h1> <ul> {posts.map(post => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }
The Fix
Use Remix's useTransition hook to detect when a navigation or form submission is in progress. Then, conditionally render a loading message or spinner to inform users that the app is working.
This improves user experience by providing immediate feedback.
import { useLoaderData, useTransition } from "@remix-run/react"; export default function Posts() { const posts = useLoaderData(); const transition = useTransition(); const isLoading = transition.state === "loading" || transition.state === "submitting"; return ( <div> <h1>Posts</h1> {isLoading ? ( <p>Loading posts...</p> ) : ( <ul> {posts.map(post => ( <li key={post.id}>{post.title}</li> ))} </ul> )} </div> ); }
Prevention
Always plan for loading states in your Remix components that fetch data or handle navigation. Use useTransition to detect loading and show feedback.
Keep loading indicators simple and accessible, using semantic HTML and ARIA roles if needed.
Consider adding global loading UI in your root layout for consistent experience.
Related Errors
Developers sometimes confuse useLoaderData with loading state, expecting it to handle loading UI automatically.
Another common mistake is not checking transition.state properly, causing loading indicators to never show or stay forever.