createRouteData

createRouteData allows you to manage async data fetching.
tsx
const data = createRouteData(getStudents);
tsx
const data = createRouteData(getStudents);


Usage

Fetching data from an API

createRouteData is a primitive for managing async data fetching. It is a light wrapper over createResource that is a router away so it can handle data refetching. The simplest way to use it is to fetch data from an API.

tsx
import { createRouteData } from "solid-start";
 
export function routeData() {
return createRouteData(async () => {
const response = await fetch("https://hogwarts.deno.dev/students");
return (await response.json());
});
}
tsx
import { createRouteData } from "solid-start";
 
export function routeData() {
return createRouteData(async () => {
const response = await fetch("https://hogwarts.deno.dev/students");
return (await response.json());
});
}

Fetching data with a key

Often though we want to be able to set a key for our routeData both to act as a parameter and to allow easy invalidation. The fetcher function does not reactively track, so you must use this option if you wish the route data to update. A "falsy" value turns off data fetching.

tsx
import { createRouteData, RouteDataArgs } from "solid-start";
 
export function routeData({ params } : RouteDataArgs) {
return createRouteData(
async key => {
const response = await fetch(`https://hogwarts.deno.dev/${key[0]}/${key[1]}`);
return (await response.json());
},
{ key: () => ["students", params.id] }
);
}
tsx
import { createRouteData, RouteDataArgs } from "solid-start";
 
export function routeData({ params } : RouteDataArgs) {
return createRouteData(
async key => {
const response = await fetch(`https://hogwarts.deno.dev/${key[0]}/${key[1]}`);
return (await response.json());
},
{ key: () => ["students", params.id] }
);
}

Reactive Keys

The array returned by the key function can track signals and automatically refetch data when the key changes. One use case for this is refetching data based on when a query param changes (since query param changes don't actually register as a changed route). Consider the following example which implements basic pagination using an after query param:

tsx
import { createRouteData, RouteDataArgs } from "solid-start";
 
export function routeData({ params, location } : RouteDataArgs) {
return createRouteData(
async ([, after]) => {
const response = await fetch(`https://hogwarts.deno.dev/students?after${after}`);
return (await response.json());
},
{ key: () => ["students", location.query['after']] }
);
}
tsx
import { createRouteData, RouteDataArgs } from "solid-start";
 
export function routeData({ params, location } : RouteDataArgs) {
return createRouteData(
async ([, after]) => {
const response = await fetch(`https://hogwarts.deno.dev/students?after${after}`);
return (await response.json());
},
{ key: () => ["students", location.query['after']] }
);
}

Setting the reconcile key

createRouteData uses a Solid Store under the hood to store its data. This means that when data is refetched it attempts to diff the data to trigger only the finest-grained updates. By default, it is configured to key data to id. If your backend uses a different field you can set it:

tsx
import { createRouteData } from "solid-start";
 
export function routeData() {
return createRouteData(
async () => {
const response = await fetch("https://hogwarts.deno.dev/students");
return (await response.json());
},
{
reconcileOptions: {
key: "_id"
}
}
);
}
tsx
import { createRouteData } from "solid-start";
 
export function routeData() {
return createRouteData(
async () => {
const response = await fetch("https://hogwarts.deno.dev/students");
return (await response.json());
},
{
reconcileOptions: {
key: "_id"
}
}
);
}

Reference

createRouteData(fetcher, options)

Call createRouteData().

tsx
import { createRouteData } from "solid-start";
 
export function routeData() {
const data = createRouteData(getStudents);
 
data() // null, data is not yet loaded, triggers Suspense
data.loading // true, data is loading
data.latest // null, data is not yet loaded
}
tsx
import { createRouteData } from "solid-start";
 
export function routeData() {
const data = createRouteData(getStudents);
 
data() // null, data is not yet loaded, triggers Suspense
data.loading // true, data is loading
data.latest // null, data is not yet loaded
}

Options

  • key (string | Array, default: true): Parameters for the route data to key by. A falsy value prevents fetching.
  • initialValue (unknown, default undefined): Initial value of the routeData.
  • deferStream (boolean, default false): Prevent streaming render from flushing until complete.
  • reconcileOptions:
    • key (string, default "id"): The property to use as a key for data diffing.
    • merge (boolean, default false): When true diff deep merges unrecognized values instead of replacing them.

Returns

A Solid Resource. An accessor that returns the data loaded by the fetcher. The accessor additionally has these reactive properties:

  • state ("unresolved" | "pending" | "ready" | "refreshing" | "errored"): Current state of the route data.
  • loading (boolean): Indicates if it is loading.
  • error (unknown): Contains the error if it is currently errored.
  • latest (unknown): A way of reading the current value without triggering Suspense.