Pirulax
Pirulax3h ago

How to use `localLink` (`unstable_localLink`)

This is more of a guide, rather than a question since I've found no docs on how to use this function to fix SSR related issues. So, based on https://orpc.unnoq.com/docs/best-practices/optimize-ssr I've managed to cook something that has fixed my issues with the headers not passed to the requests on initial SSR of "use client" components (nextjs). So, in my trpc/server/index.ts (usually server.ts) I added the following:
globalThis.$getTRPCServerSideTerminatingLink = () => unstable_localLink({
router: appRouter,
createContext: createContext,
transformer,
})
globalThis.$getTRPCServerSideTerminatingLink = () => unstable_localLink({
router: appRouter,
createContext: createContext,
transformer,
})
In trpc/client.ts:
declare global {
/** HACK: For SSR we wan't to use a `localLink` directly instead of going over HTTP so that headers are properly forwarded (Otherwise auth won't work) */
var $getTRPCServerSideTerminatingLink: (() => TRPCLink<AppRouter>) | undefined;
}
declare global {
/** HACK: For SSR we wan't to use a `localLink` directly instead of going over HTTP so that headers are properly forwarded (Otherwise auth won't work) */
var $getTRPCServerSideTerminatingLink: (() => TRPCLink<AppRouter>) | undefined;
}
and also:
export const TRPCWithReactQueryProvider = ({ children, queryClient }: TRPCWithReactQueryProviderProps) => {
const qc = queryClient ?? getQueryClient();

const links: TRPCLink<AppRouter>[] = [];

/** Add terminating link */
if (isServer) {
const link = globalThis.$getTRPCServerSideTerminatingLink?.();
if (link) {
links.push(link);
} else {
throw new Error('No server-side `terminating link` found on globalThis');
}
} else {
links.push(
httpBatchLink<AppRouter>({
url: '/api/trpc',
transformer,
}),
);
}

const [trpcClient] = useState(() =>
createTRPCProxyClient<AppRouter>({
links
}),
);

// ....
};
export const TRPCWithReactQueryProvider = ({ children, queryClient }: TRPCWithReactQueryProviderProps) => {
const qc = queryClient ?? getQueryClient();

const links: TRPCLink<AppRouter>[] = [];

/** Add terminating link */
if (isServer) {
const link = globalThis.$getTRPCServerSideTerminatingLink?.();
if (link) {
links.push(link);
} else {
throw new Error('No server-side `terminating link` found on globalThis');
}
} else {
links.push(
httpBatchLink<AppRouter>({
url: '/api/trpc',
transformer,
}),
);
}

const [trpcClient] = useState(() =>
createTRPCProxyClient<AppRouter>({
links
}),
);

// ....
};
I also had to add imports to instrumentation.ts (See the orpc docs), and to my very root layout (Just make sure it's not use client!) Question: Is this is safe to do on the server side? (As in, does localLink do any kind of caching or something that could leak data between users?)
Optimize Server-Side Rendering (SSR) for Fullstack Frameworks - oRPC
Optimize SSR performance in Next.js, SvelteKit, and other frameworks by using oRPC to make direct server-side API calls, avoiding unnecessary network requests.
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?