#tRPC inside getServerSideProps

35 messages · Page 1 of 1 (latest)

cerulean steeple
#

how you sending or passing params? are you using subroute [slug].js?

worthy tusk
cerulean steeple
#

did you solved? if not do you any have any reproducible code so we can check and debug

inland ermine
#

I don’t think it is necessary to use trpc on the server

#

useQuery is meant to run on the browser

#

if you really want to trpc requests on the server use createProxySSGHelpers() to get the client

worthy tusk
worthy tusk
worthy tusk
#

And its the strangest thing; tRPC is already running on "the same conditions" as the getServerSideProps - its running backend - but I guess all the extra client-cache-etc-etc-wrappings on tRPC, makes it harder to do any direct calls.

worthy tusk
#

I found a solution;

for me, i could do this in getServerSideProps:

const posts = await postsRouter.createCaller({prisma}).posts({ page: 1, pageSize: 7 * 12 } );

that will actually deliver data in getServerSideProps - yes it will stahl the pageload, like any server-side-programming-language has been doing for the last 20+ years - but if thats what you need, its what you need 🙂 also can be used in `/api/à

inland ermine
#

the name is just bad

halcyon pumice
#

all useSomething type functions in the react space follow Rules of Hooks and work only in React Components in the browser, getServerSideProps runs in the server, so technically you can just query the db directly, you don't have to send a request to the trpc endpoint

const posts = await prisma.posts.takeMany({take: 7 * 12})
worthy tusk
worthy tusk
halcyon pumice
#
const getPosts = (args) => prisma.posts.takeMany(args)

trpc.query('posts', args => getPosts)

const getServerSideProps = async () => {
  const posts = getPosts()
}

just extract it

#

there, 1 implementation

worthy tusk
halcyon pumice
#

if that works then great, sounds like a fine solution

#

though if you want to have it in the cache as well, you can use the solution outlined above, like seen here:

import { createProxySSGHelpers } from '@trpc/react-query/ssg';
import { GetServerSidePropsContext, InferGetServerSidePropsType } from 'next';
import { createContext } from 'server/context';
import { appRouter } from 'server/routers/_app';
import superjson from 'superjson';
import { trpc } from 'utils/trpc';
export async function getServerSideProps(
  context: GetServerSidePropsContext<{ id: string }>,
) {
  const ssg = createProxySSGHelpers({
    router: appRouter,
    ctx: await createContext(),
    transformer: superjson,
  });
  const id = context.params?.id as string;
  /*
   * Prefetching the `post.byId` query here.
   * `prefetch` does not return the result and never throws - if you need that behavior, use `fetch` instead.
   */
  await ssg.post.byId.prefetch({ id });
  // Make sure to return { props: { trpcState: ssg.dehydrate() } }
  return {
    props: {
      trpcState: ssg.dehydrate(),
      id,
    },
  };
}
export default function PostViewPage(
  props: InferGetServerSidePropsType<typeof getServerSideProps>,
) {
  const { id } = props;
  // This query will be immediately available as it's prefetched.
  const postQuery = trpc.post.byId.useQuery({ id });
  const { data } = postQuery;
  return (
    <>
      <h1>{data.title}</h1>
      <em>Created {data.createdAt.toLocaleDateString()}</em>
      <p>{data.text}</p>
      <h2>Raw data:</h2>
      <pre>{JSON.stringify(data, null, 4)}</pre>
    </>
  );
}
worthy tusk
#

It does indeed - it deliver the exact interface which the client side would have been exposed to; giving the option to have the call either on clientside or serverside.

worthy tusk
#

Because you do not get the data, inside getServerSideProps - and therefore you cannot make decisions based on it.

halcyon pumice
#

if you have access to the session ofc you can

worthy tusk
#

I cant see how that would be relevant to the problem at hand ?

halcyon pumice
#

get userId or something from the session, get the user load into cache, if it's an admin also load posts into cache otherwise redirect to somewhere

worthy tusk
#

Think the process through.

  1. load the user from the database with trpc. Its a prefetch. You wont know it on one call to getServerSideProps
  2. next load to a page, you now know the user, THEN you can react to the userId, in another getServerSideProps.
#

And yes, you can take this example, and then wrap it into something where you say "but then you cache it at the login".

Then take any other example - where you need waterfall data loading - where the data you deliver, depends on the data you first fetch - on the same page call - and it wont work with SSG.

halcyon pumice
#

are you trying to static generate or prevent waterfall? These are different goals

#

If I'm statically generating the page, then yeah, I won't know who requested the page. But then I also don't (shouldn't) have ifs and elses since it's a static page. If it's server side props, which I render per request, ofc I will know who it is if they are logged in

#

you have a session you can look into

worthy tusk
worthy tusk