Statisk sidgenerering
Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →
Referensprojekt: https://github.com/trpc/examples-next-prisma-todomvc
Statisk sidgenerering kräver att tRPC-frågor körs inuti getStaticProps på varje sida.
Detta kan göras med hjälp av server-side helpers för att förhämtas frågor, dehydrera dem och skicka till sidan. Frågorna kommer sedan automatiskt att använda trpcState som initialt värde.
Hämta data i 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';import superjson from 'superjson';export async function getStaticProps(context: GetStaticPropsContext<{ id: string }>,) {const helpers = createServerSideHelpers({router: appRouter,ctx: {},transformer: superjson, // optional - adds superjson serialization});const id = context.params?.id as string;// prefetch `post.byId`await helpers.post.byId.prefetch({ id });return {props: {trpcState: helpers.dehydrate(),id,},revalidate: 1,};}export const getStaticPaths: GetStaticPaths = async () => {const posts = await prisma.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 function PostViewPage(props: InferGetStaticPropsType<typeof getStaticProps>,) {const { id } = props;const postQuery = 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';import superjson from 'superjson';export async function getStaticProps(context: GetStaticPropsContext<{ id: string }>,) {const helpers = createServerSideHelpers({router: appRouter,ctx: {},transformer: superjson, // optional - adds superjson serialization});const id = context.params?.id as string;// prefetch `post.byId`await helpers.post.byId.prefetch({ id });return {props: {trpcState: helpers.dehydrate(),id,},revalidate: 1,};}export const getStaticPaths: GetStaticPaths = async () => {const posts = await prisma.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 function PostViewPage(props: InferGetStaticPropsType<typeof getStaticProps>,) {const { id } = props;const postQuery = 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></>);}
Observera att react-querys standardbeteende är att hämta data på nytt på klientsidan när den monteras. Om du enbart vill hämta data via getStaticProps måste du ställa in refetchOnMount och refetchOnWindowFocus till false i frågealternativen.
Detta kan vara att föredra om du vill minimera antalet förfrågningar till ditt API, vilket kan vara nödvändigt om du till exempel använder ett tredjeparts-API med begränsningar.
Detta kan göras per fråga:
tsxconst data = 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 },);
tsxconst data = 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 },);
Eller globalt om alla frågor i din applikation ska bete sig likadant:
utils/trpc.tstsximport { httpBatchLink } from '@trpc/client';import { createTRPCNext } from '@trpc/next';import superjson from 'superjson';import type { AppRouter } from './api/trpc/[trpc]';export const trpc = 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';import superjson from 'superjson';import type { AppRouter } from './api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(config) {return {links: [httpBatchLink({url: `${getBaseUrl()}/api/trpc`,}),],// Change options globallyqueryClientConfig: {defaultOptions: {queries: {refetchOnMount: false,refetchOnWindowFocus: false,},},},},},});
Var försiktig med detta tillvägagångssätt om din applikation innehåller en blandning av statiska och dynamiska frågor.