メインコンテンツへスキップ
バージョン: 9.x

サーバーサイドレンダリング

非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

アプリケーションでSSRを有効にするには、_app.tsxssr: trueを設定するだけですが、追加の考慮事項があります。

サーバーサイドレンダリングのステップでクエリを適切に実行し、キャッシュの動作をカスタマイズするには、_app.tsx内に追加のロジックを加える必要があるかもしれません:

pages/_app.tsx
tsx
import { 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 requests
return {
transformer: superjson, // optional - adds superjson serialization
url: '/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 serialization
url,
/**
* 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" header
const {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
connection: _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.tsx
tsx
import { 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 requests
return {
transformer: superjson, // optional - adds superjson serialization
url: '/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 serialization
url,
/**
* 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" header
const {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
connection: _connection,
...headers
} = ctx.req.headers;
return {
...headers,
// Optional: inform server that it's an SSR request
'x-ssr': '1',
};
}
return {};
},
};
},
ssr: true,
})(MyApp);

よくある質問

Q: クライアントのヘッダーをサーバーに手動で転送する必要があるのはなぜですか? tRPCが自動で転送しないのはなぜですか?

SSR実行時にクライアントのヘッダーをサーバーに転送したくないケースは稀ですが、ヘッダーに動的に要素を追加したい場合があるからです。そのためtRPCは、ヘッダーキーの衝突などの責任を負いたくありません。

Q: Node 18でSSRを使用する際、なぜconnectionヘッダーを削除する必要があるのですか?

connectionヘッダーを削除しない場合、データ取得がTRPCClientError: fetch failedで失敗します。これはconnection禁止ヘッダー名だからです。

Q: SSRを使用中にgetServerSidePropsgetStaticPropsを使うことはできますか?

SSRを有効にすると、tRPCはサーバー上ですべてのクエリをプリフェッチするためにgetInitialPropsを使用します。これにより、ページでgetServerSidePropsを使用するとこのような問題が発生し、解決は私たちの手に負えません。ただし、SSGヘルパーを使用してgetStaticPropsgetServerSidePropsでクエリをプリフェッチすることはできます。