#Cache

1 messages · Page 1 of 1 (latest)

jolly wedge
#
import { cookies } from "next/headers";

export default async function Page() {
  const cookieStore = cookies();
  const userToken = cookieStore.get("token")?.value ?? "sin token";

  const res = await fetch("https://api.example.com/data", {
    next: { revalidate: 60 },
  });
  const data = await res.json();

  return (
    <main>
      <h1>Con revalidate 60s</h1>
      <p>Token usuario: {userToken}</p>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </main>
  );
}

what will happen there? can you explain to me, also by time

hidden frostBOT
#

Hi @jolly wedge. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In your code:

import { cookies } from "next/headers";

export default async function Page() {
  const cookieStore = cookies();
  const userToken = cookieStore.get("token")?.value ?? "sin token";

  const res = await fetch("<https://api.example.com/data",> {
    next: { revalidate: 60 },
  });
  const data = await res.json();

  return (
    <main>
      <h1>Con revalidate 60s</h1>
      <p>Token usuario: {userToken}</p>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </main>
  );
}

What happens here?

  • You are reading a cookie (token) from the request using cookies() from next/headers.
  • You are fetching data from an external API and setting next: { revalidate: 60 }, which means you want the data to be cached and revalidated every 60 seconds.

How does caching and revalidation work here?

However, when you use cookies() in a Server Component or page, Next.js opts the route into dynamic rendering. This means that the page will be rendered on every request, and the fetch will not use the persistent Data Cache as it would in a static context. Instead, the fetch will be executed on every request, and the revalidate option will be ignored. This is expected behavior and is documented by the Next.js team:

In Next, using cookies() on a page opts it into dynamic rendering, which means each request will hit the server. This is explained here.
You can still opt into fetch caching by passing explicit cache configuration options to your fetch. More on fetch caching can be found here
(source)

Timeline

#
  • At any time: Each request to this page will:
    • Read the latest cookies from the request.
    • Fetch fresh data from the API (ignoring the cache, even with revalidate: 60).
    • Render the page with the latest data and cookie value.

If you did not use cookies()

  • The fetch would be cached for 60 seconds.
  • The first request would fetch and cache the data.
  • Requests within the next 60 seconds would serve cached data.
  • After 60 seconds, the next request would serve stale data and trigger a background revalidation (stale-while-revalidate), updating the cache for subsequent requests
    (source).

Summary

  • With cookies(): No caching, always dynamic, revalidate is ignored.
  • Without cookies(): Caching and revalidation work as expected with revalidate: 60.

If you need caching with cookies, you must design your data fetching to not depend on per-request values, or use other strategies such as API routes or client-side fetching.


References integrated above.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@jolly wedge Kapa.ai is still learning and improving, please let me know how I did by reacting below.

jolly wedge
#

@hidden frost so if i use cookies for something, and i also do fetch (without cookies), there's no possibility of cache for that fetch?

hidden frostBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

If you use the cookies() API in your page or component, the entire route is opted into dynamic rendering, which means that all fetch requests in that route will be treated as dynamic and will not use the persistent Data Cache—even if those fetches do not depend on cookies themselves. This is documented in the Next.js docs and confirmed in multiple GitHub issues:

In Next, using cookies() on a page opts it into dynamic rendering, which means each request will hit the server.
GitHub Issue: cookies break caching/memoization

So, even if your fetch does not use cookies, as long as cookies() is called anywhere in the route, the fetch will not be cached by Next.js's Data Cache. The revalidate option will also be ignored in this context.

Summary:
No, if you use cookies() in your route, there is no possibility for server-side fetch caching for any fetch in that route, regardless of whether the fetch itself uses cookies or not.
Next.js Caching Docs: Dynamic APIs

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@jolly wedge Kapa.ai is still learning and improving, please let me know how I did by reacting below.

jolly wedge
#

@

#

@hidden frost what if i do passing explicit cache configuration options to the fetch? also show me the code snippet.

hidden frostBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

Even if you pass explicit cache configuration options (such as cache: 'force-cache' or next: { revalidate: 60 }) to your fetch call, using cookies() in your route will still opt the entire route into dynamic rendering. This means that the fetch will not be cached by Next.js's Data Cache, and the cache options will be ignored. This is confirmed in the official documentation and GitHub issues:

In Next, using cookies() on a page opts it into dynamic rendering, which means each request will hit the server. This is explained here.

You can still opt into fetch caching by passing explicit cache configuration options to your fetch. More on fetch caching can be found here.

— However, the presence of cookies() will still force dynamic rendering and prevent caching, regardless of fetch options.
GitHub Issue: cookies break caching/memoization

Example Code

import { cookies } from "next/headers";

export default async function Page() {
  const cookieStore = cookies();

  // Even with explicit cache options, this will NOT be cached
  const res = await fetch("<https://api.example.com/data",> {
    cache: "force-cache",
    next: { revalidate: 60 },
  });
  const data = await res.json();

  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

Result:
The fetch will be executed on every request, and the cache options will be ignored because cookies() is used in the route. There is no way to enable server-side fetch caching in this scenario, according to the current Next.js documentation and issue discussions.

#

If you need caching, you must avoid using cookies() in the same route segment as your cached fetch, or restructure your code so that the fetch and cookie access are separated into different route segments or API endpoints
Next.js Caching Docs: Dynamic APIs.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: