Created
April 27, 2025 11:05
-
-
Save mmikhan/f9f42c9d4d53b635564d989fab96ef29 to your computer and use it in GitHub Desktop.
Manual dehydration on a T3 app through the `useAuthQuery` hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { auth } from "@/server/auth"; | |
import { createQueryClient } from "@/trpc/query-client"; | |
import { HydrationBoundary, dehydrate } from "@tanstack/react-query"; // Import dehydrate and HydrationBoundary | |
import { headers } from "next/headers"; | |
import Link from "next/link"; | |
import { cache } from "react"; | |
import StateView from "./state"; | |
// Cache the QueryClient per request in RSC | |
const getQueryClient = cache(() => createQueryClient()); | |
export default async function DashboardPage() { | |
const queryClient = getQueryClient(); | |
const reqHeaders = await headers(); | |
await queryClient.prefetchQuery({ | |
queryKey: ["polarCustomerState"], | |
queryFn: () => auth.api.polarCustomerState({ headers: reqHeaders }), | |
}); | |
// Manually dehydrate the state *after* prefetching | |
const dehydratedState = dehydrate(queryClient); | |
// Optional: Keep the log to verify server state if needed | |
// console.log("Server Prefetch Result:", JSON.stringify(queryClient.getQueryData(["polarCustomerState"]), null, 2)); | |
return ( | |
// Use HydrationBoundary and pass the dehydrated state explicitly | |
<HydrationBoundary state={dehydratedState}> | |
<div className="relative flex min-h-[100dvh] flex-col items-center justify-center gap-4 bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white"> | |
<h1 className="font-bold text-4xl">Dashboard</h1> | |
{/* Link to the Polar Customer Portal */} | |
<Link | |
href="/api/auth/portal" // Directly targets the API endpoint | |
className="text-blue-400 underline hover:text-blue-300" | |
target="_blank" // Optional: open in a new tab | |
rel="noopener noreferrer" // Security measure for target="_blank" | |
> | |
Manage Subscription | |
</Link> | |
{/* Render the client component that will display the state */} | |
<StateView /> | |
<Link | |
href="/" | |
className="absolute top-4 left-4 text-gray-300 text-sm hover:text-gray-100" | |
> | |
Back to Home | |
</Link> | |
</div> | |
</HydrationBoundary> | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use client"; | |
import { useAuthQuery } from "@/lib/auth-hooks"; // Import the hook | |
export default function StateView() { | |
const { | |
data: state, | |
isLoading, | |
error, | |
} = useAuthQuery({ | |
queryKey: ["polarCustomerState"], | |
// Add queryFn back for background updates and stale refetches | |
queryFn: async () => { | |
const response = await fetch("/api/auth/state"); | |
if (!response.ok) { | |
// Try to parse error details if available | |
let errorBody = "Failed to fetch state client-side"; | |
try { | |
const errJson = await response.json(); | |
errorBody = errJson.message || errorBody; | |
} catch (e) { | |
// Ignore if response is not JSON | |
} | |
throw new Error(errorBody); | |
} | |
return await response.json(); | |
}, | |
}); | |
// Display loading state (should be brief or skipped due to hydration) | |
if (isLoading) { | |
return <p className="text-gray-400">Loading customer state...</p>; | |
} | |
// Display error state | |
if (error) { | |
return <p className="text-red-400">Error loading state: {error.message}</p>; | |
} | |
// Display the fetched data | |
return ( | |
<pre className="mt-4 max-w-lg overflow-auto rounded bg-gray-800 p-4 text-left text-sm"> | |
{state ? JSON.stringify(state, null, 2) : "No state data available."} | |
</pre> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment