Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
90dd39d
Update 06-partial-prerendering.mdx
MichalMoravik Jul 4, 2025
034d3d2
ISR: fixing the docs example and its explanation
MichalMoravik Jul 6, 2025
55d7f51
Update Time-based revalidation section to be more clear on its workings
MichalMoravik Jul 6, 2025
f058c35
Being more clear for the on-demand revalidation
MichalMoravik Jul 6, 2025
bb2a7e4
Updating on-demand revalidation with even more clarification
MichalMoravik Jul 6, 2025
662c17d
Merge branch 'canary' into patch-3
MichalMoravik Jul 6, 2025
5a556e2
Merge branch 'canary' into patch-3
MichalMoravik Jul 7, 2025
40f599d
Merge branch 'canary' into patch-3
MichalMoravik Jul 8, 2025
b2fb652
Merge branch 'canary' into patch-3
MichalMoravik Jul 9, 2025
7345d84
Adding the 404 dynamicParams note to the 6th description point, remov…
MichalMoravik Jul 10, 2025
4aee5c5
Merge branch 'canary' into patch-3
MichalMoravik Jul 15, 2025
730f336
ISR guide update - removing some parts from the code example and stre…
MichalMoravik Jul 15, 2025
0032b51
Merge branch 'canary' into patch-3
MichalMoravik Jul 16, 2025
eba3c55
Merge branch 'canary' into patch-3
MichalMoravik Jul 17, 2025
f4cadb3
Merge branch 'canary' into patch-3
MichalMoravik Jul 23, 2025
52a2c7d
Merge branch 'canary' into patch-3
MichalMoravik Jul 26, 2025
977032c
Merge branch 'canary' into patch-3
MichalMoravik Aug 2, 2025
3688595
Merge branch 'canary' into patch-3
icyJoseph Aug 4, 2025
2990af2
Merge branch 'canary' into patch-3
MichalMoravik Aug 5, 2025
9080b50
Merge branch 'canary' into patch-3
icyJoseph Aug 5, 2025
b4d535f
Merge branch 'canary' into patch-3
icyJoseph Aug 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/01-app/01-getting-started/06-partial-prerendering.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
}
```

```jsx filename="/app/dashboard/layout.js" switcher
```jsx filename="/app/dashboard/layout.jsx" switcher
export const experimental_ppr = true

export default function Layout({ children }) {
Expand Down
46 changes: 20 additions & 26 deletions docs/01-app/02-guides/incremental-static-regeneration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ interface Post {
// request comes in, at most once every 60 seconds.
export const revalidate = 60

// We'll prerender only the params from `generateStaticParams` at build time.
// If a request comes in for a path that hasn't been generated,
// Next.js will server-render the page on-demand.
export const dynamicParams = true // or false, to 404 on unknown paths

export async function generateStaticParams() {
const posts: Post[] = await fetch('https://api.vercel.app/blog').then((res) =>
res.json()
Expand Down Expand Up @@ -67,16 +62,11 @@ export default async function Page({
}
```

```jsx filename="app/blog/[id]/page.js" switcher
```jsx filename="app/blog/[id]/page.jsx" switcher
// Next.js will invalidate the cache when a
// request comes in, at most once every 60 seconds.
export const revalidate = 60

// We'll prerender only the params from `generateStaticParams` at build time.
// If a request comes in for a path that hasn't been generated,
// Next.js will server-render the page on-demand.
export const dynamicParams = true // or false, to 404 on unknown paths

export async function generateStaticParams() {
const posts = await fetch('https://api.vercel.app/blog').then((res) =>
res.json()
Expand All @@ -100,6 +90,15 @@ export default async function Page({ params }) {
}
```

Here's how this example works:

1. During `next build`, all known blog posts are generated
2. All requests made to these pages (e.g. `/blog/1`) are cached and instantaneous
3. After 60 seconds has passed, the next request will still return the cached (now stale) page
4. The cache is invalidated and a new version of the page begins generating in the background
5. Once generated successfully, the next request will return the updated page and cache it for subsequent requests
6. If `/blog/26` is requested, and it exists, the page will be generated on-demand. This behavior can be changed by using a different [dynamicParams](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) value. However, if the post does not exist, then 404 is returned.

</AppOnly>

<PagesOnly>
Expand All @@ -125,10 +124,7 @@ export const getStaticPaths: GetStaticPaths = async () => {
params: { id: String(post.id) },
}))

// We'll prerender only these paths at build time.
// { fallback: 'blocking' } will server-render pages
// on-demand if the path doesn't exist.
return { paths, fallback: false }
return { paths, fallback: 'blocking' }
}

export const getStaticProps: GetStaticProps<Props> = async ({
Expand Down Expand Up @@ -167,9 +163,7 @@ export async function getStaticPaths() {
params: { id: post.id },
}))

// We'll prerender only these paths at build time.
// { fallback: false } means other routes should 404.
return { paths, fallback: false }
return { paths, fallback: 'blocking' }
}

export async function getStaticProps({ params }) {
Expand All @@ -195,16 +189,16 @@ export default function Page({ post }) {
}
```

</PagesOnly>

Here's how this example works:

1. During `next build`, all known blog posts are generated (there are 25 in this example)
1. During `next build`, all known blog posts are generated
2. All requests made to these pages (e.g. `/blog/1`) are cached and instantaneous
3. After 60 seconds has passed, the next request will still show the cached (stale) page
3. After 60 seconds has passed, the next request will still return the cached (now stale) page
4. The cache is invalidated and a new version of the page begins generating in the background
5. Once generated successfully, Next.js will display and cache the updated page
6. If `/blog/26` is requested, Next.js will generate and cache this page on-demand
5. Once generated successfully, the next request will return the updated page and cache it for subsequent requests
6. If `/blog/26` is requested, and it exists, the page will be generated on-demand. This behavior can be changed by using a different [fallback](https://nextjs.org/docs/pages/api-reference/functions/get-static-paths#fallback-false) value. However, if the post does not exist, then 404 is returned.

</PagesOnly>

## Reference

Expand Down Expand Up @@ -237,7 +231,7 @@ Here's how this example works:

### Time-based revalidation

This fetches and displays a list of blog posts on `/blog`. After an hour, the cache for this page is invalidated on the next visit to the page. Then, in the background, a new version of the page is generated with the latest blog posts.
This fetches and displays a list of blog posts on /blog. After an hour has passed, the next visitor will still receive the cached (stale) version of the page immediately for a fast response. Simultaneously, Next.js triggers regeneration of a fresh version in the background. Once the new version is successfully generated, it replaces the cached version, and subsequent visitors will receive the updated content.

```tsx filename="app/blog/page.tsx" switcher
interface Post {
Expand Down Expand Up @@ -289,7 +283,7 @@ We recommend setting a high revalidation time. For instance, 1 hour instead of 1

For a more precise method of revalidation, invalidate pages on-demand with the `revalidatePath` function.

For example, this Server Action would get called after adding a new post. Regardless of how you retrieve your data in your Server Component, either using `fetch` or connecting to a database, this will clear the cache for the entire route and allow the Server Component to fetch fresh data.
For example, this Server Action would get called after adding a new post. Regardless of how you retrieve your data in your Server Component, either using `fetch` or connecting to a database, this will immediately clear the cache for the entire route. Unlike time-based revalidation, the next request after on-demand revalidation won't return stale data but will serve the updated version right away and cache it for subsequent requests.

```ts filename="app/actions.ts" switcher
'use server'
Expand Down
Loading