정적 사이트 생성
정적 사이트 생성을 수행하려면 각 페이지에서 getStaticProps 내부에서 tRPC 쿼리를 실행해야 합니다.
이것은 서버 측 헬퍼를 사용하여 쿼리를 사전에 가져오고, 탈수화(dehydrate)한 뒤 페이지로 전달하는 방식으로 수행할 수 있습니다. 그러면 쿼리가 trpcState를 자동으로 가져와 초기 값으로 사용합니다.
getStaticProps에서 데이터 가져오기
pages/posts/[id].tsxtsximport {createServerSideHelpers } from '@trpc/react-query/server';import {prisma } from './server/context';import {appRouter } from './server/routers/_app';import {trpc } from './utils/trpc';import {GetStaticPaths ,GetStaticPropsContext ,InferGetStaticPropsType ,} from 'next';importsuperjson from 'superjson';export async functiongetStaticProps (context :GetStaticPropsContext <{id : string }>,) {consthelpers =createServerSideHelpers ({router :appRouter ,ctx : {},transformer :superjson , // optional - adds superjson serialization});constid =context .params ?.id as string;// prefetch `post.byId`awaithelpers .post .byId .prefetch ({id });return {props : {trpcState :helpers .dehydrate (),id ,},revalidate : 1,};}export constgetStaticPaths :GetStaticPaths = async () => {constposts = awaitprisma .post .findMany ({select : {id : true,},});return {paths :posts .map ((post ) => ({params : {id :post .id ,},})),// https://nextjs.org/docs/pages/api-reference/functions/get-static-paths#fallback-blockingfallback : 'blocking',};};export default functionPostViewPage (props :InferGetStaticPropsType <typeofgetStaticProps >,) {const {id } =props ;constpostQuery =trpc .post .byId .useQuery ({id });if (postQuery .status !== 'success') {// won't happen since we're using `fallback: "blocking"`return <>Loading...</>;}const {data } =postQuery ;return (<><h1 >{data .title }</h1 ><em >Created {data .createdAt .toLocaleDateString ('en-us')}</em ><p >{data .text }</p ><h2 >Raw data:</h2 ><pre >{JSON .stringify (data , null, 4)}</pre ></>);}
pages/posts/[id].tsxtsximport {createServerSideHelpers } from '@trpc/react-query/server';import {prisma } from './server/context';import {appRouter } from './server/routers/_app';import {trpc } from './utils/trpc';import {GetStaticPaths ,GetStaticPropsContext ,InferGetStaticPropsType ,} from 'next';importsuperjson from 'superjson';export async functiongetStaticProps (context :GetStaticPropsContext <{id : string }>,) {consthelpers =createServerSideHelpers ({router :appRouter ,ctx : {},transformer :superjson , // optional - adds superjson serialization});constid =context .params ?.id as string;// prefetch `post.byId`awaithelpers .post .byId .prefetch ({id });return {props : {trpcState :helpers .dehydrate (),id ,},revalidate : 1,};}export constgetStaticPaths :GetStaticPaths = async () => {constposts = awaitprisma .post .findMany ({select : {id : true,},});return {paths :posts .map ((post ) => ({params : {id :post .id ,},})),// https://nextjs.org/docs/pages/api-reference/functions/get-static-paths#fallback-blockingfallback : 'blocking',};};export default functionPostViewPage (props :InferGetStaticPropsType <typeofgetStaticProps >,) {const {id } =props ;constpostQuery =trpc .post .byId .useQuery ({id });if (postQuery .status !== 'success') {// won't happen since we're using `fallback: "blocking"`return <>Loading...</>;}const {data } =postQuery ;return (<><h1 >{data .title }</h1 ><em >Created {data .createdAt .toLocaleDateString ('en-us')}</em ><p >{data .text }</p ><h2 >Raw data:</h2 ><pre >{JSON .stringify (data , null, 4)}</pre ></>);}
react-query는 기본적으로 마운트될 때 클라이언트에서 데이터를 다시 가져옵니다. getStaticProps에서 가져온 데이터만 사용하려면 쿼리 옵션의 refetchOnMount와 refetchOnWindowFocus를 false로 설정해야 합니다.
예를 들어 호출 횟수가 제한된 서드파티 API를 사용해 API 요청 수를 최소화해야 할 때 이 방식이 더 적합할 수 있습니다.
쿼리별로 다음과 같이 수행할 수 있습니다:
tsximport {trpc } from './utils/trpc';constdata =trpc .example .useQuery (// if your query takes no input, make sure that you don't// accidentally pass the query options as the first argumentundefined ,{refetchOnMount : false,refetchOnWindowFocus : false },);
tsximport {trpc } from './utils/trpc';constdata =trpc .example .useQuery (// if your query takes no input, make sure that you don't// accidentally pass the query options as the first argumentundefined ,{refetchOnMount : false,refetchOnWindowFocus : false },);
또는 앱 전체의 모든 쿼리가 동일한 방식으로 동작해야 하는 경우 전역으로 설정할 수 있습니다:
utils/trpc.tstsximport {httpBatchLink } from '@trpc/client';import {createTRPCNext } from '@trpc/next';importsuperjson from 'superjson';import type {AppRouter } from './api/trpc/[trpc]';export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [httpBatchLink ({url : `${getBaseUrl ()}/api/trpc`,}),],// Change options globallyqueryClientConfig : {defaultOptions : {queries : {refetchOnMount : false,refetchOnWindowFocus : false,},},},};},});
utils/trpc.tstsximport {httpBatchLink } from '@trpc/client';import {createTRPCNext } from '@trpc/next';importsuperjson from 'superjson';import type {AppRouter } from './api/trpc/[trpc]';export consttrpc =createTRPCNext <AppRouter >({config (config ) {return {links : [httpBatchLink ({url : `${getBaseUrl ()}/api/trpc`,}),],// Change options globallyqueryClientConfig : {defaultOptions : {queries : {refetchOnMount : false,refetchOnWindowFocus : false,},},},};},});
앱에 정적 쿼리와 동적 쿼리가 혼합되어 있는 경우 이 접근 방식에 주의해야 합니다.