next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Docs: Usage of Cache Components with Page-Level Authorization

Open delasy opened this issue 3 weeks ago • 5 comments

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:

  1. when user opens a product page and I need to verify that this product exists or return notFound.
  2. 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

delasy avatar Nov 30 '25 16:11 delasy

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

icyJoseph avatar Dec 01 '25 10:12 icyJoseph

Also take a look at https://nextjs.org/docs/app/api-reference/directives/use-cache-private

Kvintus avatar Dec 01 '25 13:12 Kvintus

@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?

delasy avatar Dec 01 '25 19:12 delasy

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.

icyJoseph avatar Dec 01 '25 21:12 icyJoseph

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.

delasy avatar Dec 05 '25 11:12 delasy