Docs: Usage of Cache Components with Page-Level Authorization
What is the documentation issue?
I don't use global / middleware-based authorization (middleware.ts/proxy.ts). instead I'm using page-level authorization on every page.
I tried migrating to Next.js v16 with Cache Components and almost every page fails with this error:
○ Compiling /test ...
Error: Route "/test": Uncached data was accessed outside of <Suspense>. This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route
at ForgotPassword (src/app/test/page.tsx:20:19)
18 |
19 | export default async function ForgotPassword() {
> 20 | await connection();
| ^
21 | await withGuest();
22 |
23 | return <div>Forgot Password</div>;
GET /test 200 in 4.0s (compile: 3.4s, render: 556ms)
so I open the "Learn more" page and I really can't find anything that would help me here. I don't really understand how am I supposed to migrate to Cache Components with Page-Level Authorization
Is there any context that might help us understand?
super simplified example code to reproduce the issue:
import * as React from "react";
import { Metadata } from "next";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { connection } from "next/server";
export const metadata: Metadata = {
title: "Forgot Password",
};
export async function withGuest() {
const cookiesStore = await cookies();
if (cookiesStore.get("AUTH_SESSION") !== undefined) {
return redirect("/");
}
}
export default async function ForgotPassword() {
await connection();
await withGuest();
return <div>Forgot Password</div>;
}
there are more examples:
- when user opens a product page and I need to verify that this product exists or return notFound.
- when I need to run analytics tracking on server side when user opens a page
Does the docs page already exist? Please link to it.
https://nextjs.org/docs/messages/blocking-route
There's a couple of implications here, but to get unblocked you can start with:
- https://nextjs.org/docs/app/getting-started/cache-components#runtime-data
- https://nextjs.org/docs/app/getting-started/cache-components#with-runtime-data
Also take a look at https://nextjs.org/docs/app/api-reference/directives/use-cache-private
@icyJoseph I checked all links and read the entire documentation for cache components - I didn't find anything that could actually help.
@Kvintus with private cache I get this error:
Error: Route "/test": Uncached data was accessed outside of <Suspense>. This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route
at ForgotPassword (src/app/test/page.tsx:18:16)
16 | }
17 |
> 18 | export default async function ForgotPassword() {
| ^
19 | "use cache: private";
20 | await withGuest();
21 |
I'm just wondering, is that anti-pattern what I'm doing? whole my life I thought page-level authorization should be always preferred instead of global / middleware-based authorization. and here we are with migration to cache components being blocked by page-level authorization.
is it advised to start switching to cache components for everyone?
It's just that in this case you'd need to wrap the access in a Suspense boundary, and yes I know that'll 200 and such. In the links I posted, you see this pattern.
async function ForgotPassword() {
await withGuest();
return <div>Forgot Password</div>;
}
export default async function Page(props) {
return (
<Suspense>
<ForgotPassword />
</Suspense>
)
}
That'll redirect users away. And ideally everyone should at least try out cache components, this feedback is important.
I'm guessing that wrapping the component in Suspense would completely defeat the purpose of server-side validation. and while doing so would "unblock" me and let me move forward with Cache Components, I'd rather wait for a proper solution and hold off on using Cache Components for now.