Show pending indicators in your application
-- 2 min read
Don't you hate it when you click a button or link then it seems like nothing happened so you click it a few more times then the UI just changes? It is a terrible user experience due to lack of communication.
Showing feedback to a user when there is a transition engages a user and reassures them that their input was registered and is being processed. Let's see how we can implement a global loading state in a Remix application. This is how the end result will look like. I have throttled the network to slow 3G to show the loading states.
Implementation
All we need to do is to check if there is a transition going on in your application and display a loading animation. We do this in Remix in the root route (root.jsx). Remix handles routing so we just need to ask it if there is a navigation underway. We will use the useNavigation() hook for that.
// app/root.jsx
import { useNavigation } from "@remix-run/react";
// import { LoadingAnimation } from "some-place";
export function Layout({ children }) {
let navigation = useNavigation();
// Check whether there is a navigation going on and it was not caused by a form
let isLoading = navigation.state === 'loading' && !navigation.formMethod;
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{isLoading
? <div className="w-full fixed z-10 grid place-items-center inset-0 bg-black/50">
<span className="w-14 h-14 md:w-16 md:h-16"><LoadingAnimation /></span>
</div>
: null
}
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}
When a user clicks a link and the browser has to download the required assets and data, a loading animation will be shown instead of being unresponsive.
That's it! 👋🏾 Engage your users using pending indicators