Remix

Remix Client Data

Ethan Glover

I've always been a little annoyed that browser state is treated as a second class citizen in JS frameworks. In order to use powerful browser tools like Cache API and IndexedDB in React you need escape hatch APIs like useEffect.

That's why I was very happy to see Remix working on what they're calling “Client Data”.

Client loaders are just like React Router loaders receiving the request and params for the next location. They also have a loader function that they can call to get the data from the server. This enables a client loader to be able to return data from the server, the client, or both.

- Client Data RFC

So let's give this a shot. First we can create a basic API call. There's many advantages to separating Request creation from actually calling the API. First, if you want to ignore the default fetch function and customize Request headers, or if you have no need from response.json(), it's very easy to opt out of the default call. Second, we can use Cache API.

1export const TYPICODE_BASE_URL = 'https://jsonplaceholder.typicode.com';

Then we can fetch this data server side with the usual Remix loader.

1export async function loader() {

Finally, we can use the client loader.

1export async function clientLoader({ serverLoader }: ClientLoaderFunctionArgs) {

Regardless of which the data comes from, they're both available on useLoaderData.

1const { data, success } = useLoaderData<typeof loader>();

In this scenario, on the initial load the server loader will be called to get initial data. On subsequent calls, the server loader is not called, and instead only client loader is called. It checks if the data is in cache. If it is, it simply returns cached data. If it's not, it will make a call to the server loader.

And because this blog is written in Remix you can try these fun buttons to get an idea for how this works. (Don't forget to try deleting data from Cache API).

Getting data from API
Getting data from Cache

The question is now, why? Why not just depend on the built in caching of Remix? I think this opens up a lot of possibilities, there's a lot to play with here. We can now use browser state such as local storage, Cache API, and IndexedDB within the same paradigm. Keeping control over how we handle our data, and use browser API's to do it.