feat(web): preload user identity query at root route
Quentin Gliech
and
Claude Opus 4.6 (1M context)
created 1 month ago
Fire the UserIdentity query in the root route's beforeLoad so it's
already in the Apollo cache before any component calling useAuth()
renders.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change summary
webui2/src/lib/auth.tsx | 14 +++++++-------
webui2/src/routes/__root.tsx | 5 +++++
2 files changed, 12 insertions(+), 7 deletions(-)
Detailed changes
@@ -1,12 +1,12 @@
// auth.tsx — current user hook for the webui.
//
-// Fetches the user identity from git config via GraphQL. Apollo handles
-// deduplication and caching, so no Provider/Context is needed.
+// The UserIdentity query is preloaded in the root route loader and consumed
+// via useSuspenseQuery, so useAuth() always returns a resolved user.
import { gql } from "@apollo/client";
-import { useQuery } from "@apollo/client/react";
+import { useSuspenseQuery } from "@apollo/client/react";
-const USER_IDENTITY_QUERY = gql`
+export const USER_IDENTITY_QUERY = gql`
query UserIdentity {
repository {
userIdentity {
@@ -32,9 +32,9 @@ export interface AuthUser {
login: string | null;
}
-export function useAuth(): { user: AuthUser | null; loading: boolean } {
- const { data, loading } = useQuery<{ repository: { userIdentity: AuthUser | null } }>(
+export function useAuth(): { user: AuthUser } {
+ const { data } = useSuspenseQuery<{ repository: { userIdentity: AuthUser } }>(
USER_IDENTITY_QUERY,
);
- return { user: data?.repository?.userIdentity ?? null, loading };
+ return { user: data.repository.userIdentity };
}
@@ -5,12 +5,17 @@ import { Shell } from "@/components/layout/shell";
import { Button } from "@/components/ui/button";
import { ButtonLink } from "@/components/ui/button-link";
import type { preloadQuery } from "@/lib/apollo";
+import { USER_IDENTITY_QUERY } from "@/lib/auth";
export interface RouterContext {
preloadQuery: typeof preloadQuery;
}
export const Route = createRootRouteWithContext<RouterContext>()({
+ async loader({ context }) {
+ const ref = context.preloadQuery(USER_IDENTITY_QUERY);
+ await context.preloadQuery.toPromise(ref);
+ },
component: Shell,
errorComponent: ErrorPage,
});