-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug: Cannot generate static page #2006
Comments
I can confirm that this is indeed a issue - a page should not opt out of normal rendering, simply because we used a prefetch. The prefetch should behave the same as any other fetch on the page, and have its result cached and tagged in the same way. This system as it is now, limits us to either dynamically serving pages always, or losing the automatic caching at fetch level and ability to use dynamic functions. Both options suck. I don't see a clear solution to this, apart from not using prefetching, which takes away a great feature of trpc. :( |
I don't understand what you mean here. This is how Next 15 works unless you're using ppr and/or dynamicIO? |
From Next.js docs
Using I wish there was a better way to do this. I badly need it (fx i used it to resolve route URLs for links used on the client, on the server). But not at the cost of making the whole website dynamic. |
The solution is called ppr which you can opt into. I am sorry but I don't understand what's t3 specific here. See this demo for example: https://github.com/juliusmarminge/next-dynamic It works the same was and also shows an error log in If you want to have more granular static generation enable PPR in your next config and wrap dynamic components in Suspense: juliusmarminge/next-dynamic#2. |
@juliusmarminge ah, I am sorry for my mistake - this is not at all an issue related to prefetching. It is an issue related to using trpc on the server (which is very, very much a T3 issue). A quick test shows that this page is not honouring the automatic setting. import dayjs from "dayjs";
import { api } from "~/trpc/server";
export const revalidate = 30;
export default async function Home() {
const hello = await api.post.hello({ text: "from tRPC" });
return <div>{dayjs().format("HH:mm:ss")}</div>;
} It opts into full dynamic, just by the virtue of using |
I think you have a misunderstanding of what the auto setting is. When you prefetch, you're initializing a data fetch which should be dynamic by default (Next 15 reverted their decision to cache by default in 15 cause of all the confused implicit cache behaviors) The issue you're referring to was that every page got dynamic cause of the dynamic provider in the root layout. This is solved. Only pages that do dynamic data fetching will be dynamic in the current setup. If you want more granularity, well then you need PPR. The reason that trpc opts you into dynamic is cause it's using diff --git a/src/server/api/trpc.ts b/src/server/api/trpc.ts
index b38d2fa..d8c7076 100644
--- a/src/server/api/trpc.ts
+++ b/src/server/api/trpc.ts
@@ -22,7 +22,7 @@ import { ZodError } from "zod";
*
* @see https://trpc.io/docs/server/context
*/
-export const createTRPCContext = async (opts: { headers: Headers }) => {
+export const createTRPCContext = async (opts: { headers?: Headers }) => {
return {
...opts,
};
diff --git a/src/trpc/server.ts b/src/trpc/server.ts
index 91e557e..587dca4 100644
--- a/src/trpc/server.ts
+++ b/src/trpc/server.ts
@@ -1,7 +1,6 @@
import "server-only";
import { createHydrationHelpers } from "@trpc/react-query/rsc";
-import { headers } from "next/headers";
import { cache } from "react";
import { createCaller, type AppRouter } from "~/server/api/root";
@@ -12,12 +11,12 @@ import { createQueryClient } from "./query-client";
* This wraps the `createTRPCContext` helper and provides the required context for the tRPC API when
* handling a tRPC call from a React Server Component.
*/
-const createContext = cache(async () => {
- const heads = new Headers(await headers());
- heads.set("x-trpc-source", "rsc");
+const createContext = cache(() => {
+ // const heads = new Headers(await headers());
+ // heads.set("x-trpc-source", "rsc");
return createTRPCContext({
- headers: heads,
+
});
}); |
@juliusmarminge okay now after reading through the explanation it makes sense on why all the page was being dynamic in the first place. Yes, I agree it was a confusion rather than an issue as we need to add From the other comments and nextjs documentation, then if we prefetch using |
@juliusmarminge Thanks for your answer, it is really helpful. Since the OP has gotten a response that satisfies their needs, i don't wish to spam this issue further. But for the sake of completeness, I'd like to ask one more question, if you'd be so kind to answer :) I have tried the solution you proposed, and it indeed starts behaving normally again.
I would like to understand this better, could you please clarify what is the downside of removing headers? You mentioned running I don't see what purpose using the |
@juliusmarminge correct me if I'm wrong here. But while trying to build the page, its showing the page as dynamic! |
Provide environment information
Describe the bug
Pages are not generated statically when prefetching in a page or directly in a layout. If we remove all prefetch (be it
await
orvoid
) then pages are generated statically.Its mostly an issue when fetching some data from a CMS, as prefetch all or each the data from CMS will be a good way to render page statically
Tried to use next 15's static page symbol after upgrading, there also no static page symbol is showing when prefetching at the page/layout
Reproduction repo
https://github.com/t3-oss/create-t3-app
To reproduce
--debug
Static generation failed due to dynamic usage on /, reason: headers
Additional information
With prefetch at page level
Without prefetch
The text was updated successfully, but these errors were encountered: