tRPCttRPC
Powered by
PirulaxP
tRPC•6mo ago•
4 replies
Pirulax

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
trpc/server/index.ts
(usually
server.ts
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
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
instrumentation.ts
(See the orpc docs), and to my very root
layout
layout
(Just make sure it's not
use client
use client
!)

Question:
Is this is safe to do on the server side? (As in, does
localLink
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.
Optimize Server-Side Rendering (SSR) for Fullstack Frameworks - oRPC
tRPCJoin
Move Fast & Break Nothing. End-to-end typesafe APIs made easy.
5,015Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

Why use unstable_httpBatchStreamLink in React server components?
BeBoREBBeBoRE / ❓-help
3y ago
pipe/unstable_pipe
BarakondaBBarakonda / ❓-help
3y ago
trpc + unstable_cache (Next)
LedrubLLedrub / ❓-help
2y ago
Unable to mock unstable_batchStreamLink network response
Jordan (UNCVRD)JJordan (UNCVRD) / ❓-help
3y ago