import db from '#/lib/db';
import { Grid } from '#/ui/codehike';

export const demo = db.demo.find({ where: { slug: 'cached-routes' } });

# {demo.name}

<Grid>

# !!col

Mark a route segment as _cacheable_ by adding the `use cache` directive to the top of the `layout.tsx` or `page.tsx` file.

# !!col

```tsx app/page.tsx
// !mark
'use cache';

export default async function Page() {
  // ...
}
```

</Grid>

<Grid>

# !!col

#### On the client

- The router first checks the client cache for a valid cache entry before making a new request to the server.
- Cache entries in the server response update the client cache.

# !!col

<Image
  className="border border-gray-800"
  src="/visuals/cacheable-routes-client-cache.png"
  alt="Client Cache"
  width="1800"
  height="912"
/>

</Grid>

<Grid>

# !!col

#### On the server

- The renderer first checks the server cache for a valid cache entry before rendering a new result and updating the server cache.

# !!col

<Image
  className="border border-gray-800"
  src="/visuals/cacheable-routes-server-cache.png"
  alt="Server Cache"
  width="1800"
  height="1192"
/>

</Grid>

<Grid>

# !!col

#### Prerendering

- A cacheable route segment can be prerendered ahead of time, either at build time or during background revalidation.
- The prerendered result is distributed across a global content delivery network (CDN).
- At runtime, the CDN serves the closest static result to the client.
- `layout.tsx` and `page.tsx` are independently cacheable. This means a `layout.tsx` can be prerendered, while its `page.tsx` can be dynamically rendered at request time.

# !!col

<Image
  className="border border-gray-800"
  src="/visuals/cacheable-routes-prerendering.png"
  alt="Prerendering"
  width="1800"
  height="1752"
/>

</Grid>

### Demo

- An artificial one second delay is added to the `page.tsx` to make the difference more obvious.

  ```tsx app/page.tsx
  'use cache';

  export default async function Page() {
    // !mark
    await new Promise((resolve) => setTimeout(resolve, 1000));

    const products = db.product.findMany();
    // ...
  }
  ```

- Since the whole route is cacheable, this delay only happens the first time the function runs, during prerendering.

### Notes

- This demo uses the experimental `use cache` directive and describes caching behavior once stable.
