The project used TanStack router to handle client routing:
npm install @tanstack/react-router
TanStack router is fully type-safe React router with built-in data fetching, stale-while revalidate caching and first-class search-param APIs.
The main entry point is defined inside __root.tsx
. It uses createRootRoute
and contains the shared layout and providers:
export const Route = createRootRoute({
component: RootComponent,
});
function RootComponent() {
return (
<div className="max-w-xl mx-auto pt-12 bg-theme-background">
<Outlet />
</div>
);
}
Using pglite on the client requires wrapping the root component with PgliteProvider
(from @electric-sql/pglite-react
):
pnpm add @electric-sql/pglite-react
Furthermore, we also define a custom context provider to access the Pglite
service with drizzle (for building queries).
We use loader
to provide the Pglite
service to the root component:
export const Route = createRootRoute({
component: RootComponent,
loader: () => RuntimeClient.runPromise(Pglite),
});
function RootComponent() {
const { client } = Route.useLoaderData();
return (
<PGliteProvider db={client}>
<div className="max-w-xl mx-auto pt-12 bg-theme-background">
<Outlet />
</div>
</PGliteProvider>
);
}
We define the provider for drizzle in a separate use-pglite-drizzle.ts
file:
import { Context } from "effect";
import { createContext, useContext } from "react";
import { Pglite } from "~/services/pglite";
export const PgliteDrizzleContext = createContext<
Context.Tag.Service<typeof Pglite>["orm"] | null
>(null);
export const usePgliteDrizzle = () => {
const orm = useContext(PgliteDrizzleContext);
if (orm === null) {
throw new Error(
"usePgliteDrizzle must be used within PgliteDrizzleProvider"
);
}
return orm;
};
We then provide this as well inside __root.tsx
:
export const Route = createRootRoute({
component: RootComponent,
loader: () => RuntimeClient.runPromise(Pglite),
});
function RootComponent() {
const { client, orm } = Route.useLoaderData();
return (
<PgliteDrizzleContext.Provider value={orm}>
<PGliteProvider db={client}>
<div className="max-w-xl mx-auto pt-12 bg-theme-background">
<Outlet />
</div>
</PGliteProvider>
</PgliteDrizzleContext.Provider>
);
}
With this configuration we can access both client
and orm
everywhere inside the application.