정적 사이트 생성
비공식 베타 번역
이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →
정적 사이트 생성은 각 페이지의 getStaticProps 내부에서 tRPC 쿼리를 실행해야 합니다.
이는 server-side helpers를 사용하여 쿼리를 미리 가져오고, 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,},},},};},});
애플리케이션에 정적 쿼리와 동적 쿼리가 혼합되어 있다면 이 방식 사용 시 주의가 필요합니다.