Static Site Generation

tip

Reference project: https://github.com/trpc/trpc/tree/main/examples/next-prisma-todomvc

Static site generation requires executing tRPC queries inside getStaticProps on each page.

Fetch data in getStaticProps

  1. /**
  2. * Given we're this file something like `pages/posts/[id].tsx`
  3. */
  4. import { createSSGHelpers } from '@trpc/react/ssg';
  5. import {
  6. GetStaticPaths,
  7. GetStaticPropsContext,
  8. InferGetStaticPropsType,
  9. } from 'next';
  10. import { prisma } from 'server/context';
  11. import { appRouter } from 'server/routers/_app';
  12. import superjson from 'superjson';
  13. import { trpc } from 'utils/trpc';
  14. export async function getStaticProps(
  15. context: GetStaticPropsContext<{ id: string }>,
  16. ) {
  17. const ssg = await createSSGHelpers({
  18. router: appRouter,
  19. ctx: {},
  20. transformer: superjson, // optional - adds superjson serialization
  21. });
  22. const id = context.params?.id as string;
  23. // prefetch `post.byId`
  24. await ssg.fetchQuery('post.byId', {
  25. id,
  26. });
  27. return {
  28. props: {
  29. trpcState: ssg.dehydrate(),
  30. id,
  31. },
  32. revalidate: 1,
  33. };
  34. }
  35. export const getStaticPaths: GetStaticPaths = async () => {
  36. const posts = await prisma.post.findMany({
  37. select: {
  38. id: true,
  39. },
  40. });
  41. return {
  42. paths: posts.map((post) => ({
  43. params: {
  44. id: post.id,
  45. },
  46. })),
  47. // https://nextjs.org/docs/basic-features/data-fetching#fallback-blocking
  48. fallback: 'blocking',
  49. };
  50. };
  51. export default function PostViewPage(
  52. props: InferGetStaticPropsType<typeof getStaticProps>,
  53. ) {
  54. const { id } = props;
  55. const postQuery = trpc.useQuery(['post.byId', { id }]);
  56. if (postQuery.status !== 'success') {
  57. // won't happen since we're using `fallback: "blocking"`
  58. return <>Loading...</>;
  59. }
  60. const { data } = postQuery;
  61. return (
  62. <>
  63. <h1>{data.title}</h1>
  64. <em>Created {data.createdAt.toLocaleDateString()}</em>
  65. <p>{data.text}</p>
  66. <h2>Raw data:</h2>
  67. <pre>{JSON.stringify(data, null, 4)}</pre>
  68. </>
  69. );
  70. }