서버 사이드 렌더링
비공식 베타 번역
이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →
애플리케이션에 SSR을 적용하려면 _app.tsx에서 ssr: true를 설정하기만 하면 됩니다. 다만 몇 가지 추가 고려 사항이 있습니다.
서버 사이드 렌더링 단계에서 쿼리를 올바르게 실행하고 캐싱 동작을 사용자 정의하려면 _app.tsx 내부에 추가 로직을 포함해야 할 수 있습니다:
pages/_app.tsxtsximport { withTRPC } from '@trpc/next';import { AppType } from 'next/dist/shared/lib/utils';import React from 'react';import superjson from 'superjson';import type { AppRouter } from './api/trpc/[trpc]';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default withTRPC<AppRouter>({config(config) {if (typeof window !== 'undefined') {// during client requestsreturn {transformer: superjson, // optional - adds superjson serializationurl: '/api/trpc',};}// during SSR below// optional: use SSG-caching for each rendered page (see caching section for more details)const ONE_DAY_SECONDS = 60 * 60 * 24;ctx?.res?.setHeader('Cache-Control',`s-maxage=1, stale-while-revalidate=${ONE_DAY_SECONDS}`,);// The server needs to know your app's full url// On render.com you can use `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}/api/trpc`const url = process.env.VERCEL_URL? `https://${process.env.VERCEL_URL}/api/trpc`: 'http://localhost:3000/api/trpc';return {transformer: superjson, // optional - adds superjson serializationurl,/*** Set custom request headers on every request from tRPC* @see http://localhost:3000/docs/v9/header* @see http://localhost:3000/docs/v9/ssr*/headers() {if (ctx?.req) {// To use SSR properly, you need to forward the client's headers to the server// This is so you can pass through things like cookies when we're server-side rendering// If you're using Node 18, omit the "connection" headerconst {// eslint-disable-next-line @typescript-eslint/no-unused-varsconnection: _connection,...headers} = ctx.req.headers;return {...headers,// Optional: inform server that it's an SSR request'x-ssr': '1',};}return {};},};},ssr: true,})(MyApp);
pages/_app.tsxtsximport { withTRPC } from '@trpc/next';import { AppType } from 'next/dist/shared/lib/utils';import React from 'react';import superjson from 'superjson';import type { AppRouter } from './api/trpc/[trpc]';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default withTRPC<AppRouter>({config(config) {if (typeof window !== 'undefined') {// during client requestsreturn {transformer: superjson, // optional - adds superjson serializationurl: '/api/trpc',};}// during SSR below// optional: use SSG-caching for each rendered page (see caching section for more details)const ONE_DAY_SECONDS = 60 * 60 * 24;ctx?.res?.setHeader('Cache-Control',`s-maxage=1, stale-while-revalidate=${ONE_DAY_SECONDS}`,);// The server needs to know your app's full url// On render.com you can use `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}/api/trpc`const url = process.env.VERCEL_URL? `https://${process.env.VERCEL_URL}/api/trpc`: 'http://localhost:3000/api/trpc';return {transformer: superjson, // optional - adds superjson serializationurl,/*** Set custom request headers on every request from tRPC* @see http://localhost:3000/docs/v9/header* @see http://localhost:3000/docs/v9/ssr*/headers() {if (ctx?.req) {// To use SSR properly, you need to forward the client's headers to the server// This is so you can pass through things like cookies when we're server-side rendering// If you're using Node 18, omit the "connection" headerconst {// eslint-disable-next-line @typescript-eslint/no-unused-varsconnection: _connection,...headers} = ctx.req.headers;return {...headers,// Optional: inform server that it's an SSR request'x-ssr': '1',};}return {};},};},ssr: true,})(MyApp);
FAQ
Q: 클라이언트 헤더를 서버에 수동으로 전달해야 하는 이유는 무엇인가요? tRPC가 자동으로 처리해주지 않는 이유는?
SSR 수행 시 클라이언트 헤더를 서버에 전달하지 않는 경우는 드물지만, 헤더에 동적으로 내용을 추가해야 할 수 있습니다. 따라서 tRPC는 헤더 키 충돌 등에 대한 책임을 지지 않기로 했습니다.
Q: Node 18에서 SSR을 사용할 때 connection 헤더를 삭제해야 하는 이유는?
connection 헤더를 제거하지 않으면 데이터 가져오기가 TRPCClientError: fetch failed로 실패합니다. connection은 금지된 헤더 이름이기 때문입니다.
Q: SSR을 사용하면서 getServerSideProps 및 getStaticProps를 함께 사용할 수 있나요?
SSR을 활성화하면 tRPC가 서버 측에서 모든 쿼리를 프리페치하기 위해 getInitialProps를 사용합니다. 이로 인해 페이지에서 getServerSideProps를 사용할 때 이런 문제가 발생할 수 있으며, 이 문제 해결은 저희 통제 범위를 벗어납니다. 다만 SSG Helpers를 사용하면 getStaticProps나 getServerSideProps에서 쿼리를 프리페치할 수 있습니다.