Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 34 additions & 0 deletions .github/workflows/test_e2e_deploy_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,40 @@ jobs:
retention-days: 5
if-no-files-found: error

# Runs last in setup so the steps above overlap with npm propagation.
- name: wait-for-published-next
env:
# The spec that comes after `next@` when the deploy tests install
# it: a dist-tag, an exact version, or a tarball URL.
NEXT_VERSION_SPEC: ${{ steps.version.outputs.value }}
POLL_TIMEOUT_SECONDS: 900
POLL_INTERVAL_SECONDS: 15
run: |
set -euo pipefail
if [[ "$NEXT_VERSION_SPEC" == http* ]]; then
echo "next@$NEXT_VERSION_SPEC is a tarball URL, skipping npm availability check"
exit 0
fi
deadline=$((SECONDS + POLL_TIMEOUT_SECONDS))
attempt=1
while true; do
if resolved="$(pnpm view "next@$NEXT_VERSION_SPEC" version)"; then
echo "next@$NEXT_VERSION_SPEC is available on npm (resolved to $resolved, attempt $attempt)"
break
fi
if (( SECONDS >= deadline )); then
echo "::error::Timed out after ${POLL_TIMEOUT_SECONDS}s waiting for next@$NEXT_VERSION_SPEC to become available on npm"
exit 1
fi
echo "next@$NEXT_VERSION_SPEC is not available on npm yet (attempt $attempt), retrying in ${POLL_INTERVAL_SECONDS}s"
sleep "$POLL_INTERVAL_SECONDS"
attempt=$((attempt + 1))
done
test-deploy-webpack:
name: Run Deploy Tests (Webpack)
needs: setup
Expand Down
2 changes: 1 addition & 1 deletion contributing/core/developing.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ $ pnpm unpack-next path/to/project

## Developing the Dev Overlay

The dev overlay is a feature of Next.js that allows you to see the internal state of the app including the errors. To learn more about contributing to the dev overlay, see the [Dev Overlay README.md](../../packages/next/src/client/components/react-dev-overlay/README.md).
The dev overlay is a feature of Next.js that allows you to see the internal state of the app including the errors. To learn more about contributing to the dev overlay, see the [Dev Overlay README.md](../../packages/next/src/next-devtools/README.md).

## `NODE_ENV` vs `__NEXT_DEV_SERVER`

Expand Down
2 changes: 1 addition & 1 deletion docs/01-app/02-guides/caching-without-cache-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const dynamic = 'auto'
<details>
<summary>This is an advanced option that should only be used if you specifically need to override the default behavior.</summary>

By default, Next.js **will cache** any `fetch()` requests that are reachable **before** any Request-time APIs are used and **will not cache** `fetch` requests that are discovered **after** Request-time APIs are used.
A `fetch` request that sets no `cache` option is fetched once during `next build` if it is reachable **before** any Request-time APIs are used, because the route is prerendered up to that point. Requests discovered **after** a Request-time API run on every request.

`fetchCache` allows you to override the default `cache` option of all `fetch` requests in a layout or page.

Expand Down
4 changes: 2 additions & 2 deletions docs/01-app/02-guides/upgrading/version-16.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ export default nextConfig

### Turbopack File System Caching

Turbopack stores compiler artifacts on disk between runs, for significantly faster compile times across restarts. Filesystem caching is enabled by default for both `next dev` and `next build`. See [`turbopackFileSystemCache`](/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache) to configure or disable it.
Turbopack stores compiler artifacts on disk between runs, for significantly faster compile times across restarts. Filesystem caching is enabled by default for both `next dev` and `next build`, through `experimental.turbopackFileSystemCacheForDev` and `experimental.turbopackFileSystemCacheForBuild`. See [Turbopack FileSystem Caching](/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache) to configure or disable either one.

## Async Request APIs (Breaking change)

Expand Down Expand Up @@ -1074,7 +1074,7 @@ const nextConfig = {
},
}

export default nextConfig
module.exports = nextConfig
```

Evaluate if AMP is still necessary for your use case. Most performance benefits can now be achieved through Next.js's built-in optimizations and modern web standards.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const nextConfig = {
cacheComponents: true,
}

export default nextConfig
module.exports = nextConfig
```

Then add `'use cache: private'` to your function along with a `cacheLife` configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const nextConfig = {
cacheComponents: true,
}

export default nextConfig
module.exports = nextConfig
```

Then add `'use cache: remote'` to the functions or components where you've determined remote caching is justified. The handler implementation is configured via [`cacheHandlers`](/docs/app/api-reference/config/next-config-js/cacheHandlers), though hosting providers should typically provide this automatically. If you're self-hosting, see the `cacheHandlers` configuration reference to set up your cache storage.
Expand Down
53 changes: 36 additions & 17 deletions docs/01-app/03-api-reference/01-directives/use-cache.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export async function MyComponent() {
// Function level
export async function getData() {
'use cache'
const data = await fetch('/api/data')
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return data
}
```
Expand All @@ -87,7 +88,10 @@ async function Component({ userId }: { userId: string }) {
const getData = async (filter: string) => {
'use cache'
// Cache key includes both userId (from closure) and filter (argument)
return fetch(`/api/users/${userId}/data?filter=${filter}`)
const res = await fetch(
`https://api.example.com/users/${userId}/data?filter=${filter}`
)
return res.json()
}

return getData('active')
Expand Down Expand Up @@ -201,10 +205,10 @@ While `use cache` is designed primarily to include uncached data in the static s

With the default in-memory handler, runtime cache behavior depends on your hosting environment:

| Environment | Runtime Caching Behavior |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Serverless** | Cache entries typically don't persist across requests (each request can be a different instance), or during revalidation. Build-time caching works normally. |
| **Self-hosted** | Cache entries persist across requests. Control cache size with [`cacheMaxMemorySize`](/docs/app/api-reference/config/next-config-js/incrementalCacheHandlerPath). |
| Environment | Runtime Caching Behavior |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Serverless** | Cache entries typically don't persist across requests (each request can be a different instance), or during revalidation. Build-time caching works normally. |
| **Self-hosted** | Cache entries persist across requests. Control cache size with [`cacheMaxMemorySize`](/docs/app/api-reference/config/next-config-js/cacheMaxMemorySize). |

For example, in a serverless environment, a cached function shared by two pages executes on each static shell revalidation, whereas in self-hosted or environments with persistent memory, the cached output is reused if it's still fresh.

Expand Down Expand Up @@ -296,7 +300,8 @@ import { cacheLife } from 'next/cache'
async function getData() {
'use cache'
cacheLife('hours') // Use built-in 'hours' profile
return fetch('/api/data')
const res = await fetch('https://api.example.com/data')
return res.json()
}
```

Expand All @@ -310,7 +315,8 @@ If you omit `cacheLife`, the `default` profile applies and the lifetime is no lo
async function getData() {
'use cache'
// Implicitly uses the 'default' profile
return fetch('/api/data')
const res = await fetch('https://api.example.com/data')
return res.json()
}
```

Expand All @@ -326,7 +332,8 @@ import { cacheTag } from 'next/cache'
async function getProducts() {
'use cache'
cacheTag('products')
return fetch('/api/products')
const res = await fetch('https://api.example.com/products')
return res.json()
}
```

Expand Down Expand Up @@ -371,7 +378,8 @@ Any components imported and nested in `page` file are part of the cache output a
'use cache'

async function Users() {
const users = await fetch('/api/users')
const res = await fetch('https://api.example.com/users')
const users = await res.json()
// loop through users
}

Expand All @@ -388,7 +396,8 @@ export default async function Page() {
'use cache'

async function Users() {
const users = await fetch('/api/users')
const res = await fetch('https://api.example.com/users')
const users = await res.json()
// loop through users
}

Expand All @@ -413,7 +422,10 @@ You can use `use cache` at the component level to cache any fetches or computati
export async function Bookings({ type = 'haircut' }: BookingsProps) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
const response = await fetch(
`https://api.example.com/bookings?type=${encodeURIComponent(type)}`
)
const data = await response.json()
return data
}
return //...
Expand All @@ -428,7 +440,10 @@ interface BookingsProps {
export async function Bookings({ type = 'haircut' }) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
const response = await fetch(
`https://api.example.com/bookings?type=${encodeURIComponent(type)}`
)
const data = await response.json()
return data
}
return //...
Expand All @@ -443,7 +458,8 @@ Since you can add `use cache` to any asynchronous function, you aren't limited t
export async function getData() {
'use cache'

const data = await fetch('/api/data')
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return data
}
```
Expand All @@ -452,7 +468,8 @@ export async function getData() {
export async function getData() {
'use cache'

const data = await fetch('/api/data')
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return data
}
```
Expand Down Expand Up @@ -485,7 +502,8 @@ async function CacheComponent({
children: ReactNode
}) {
'use cache'
const cachedData = await fetch('/api/cached-data')
const res = await fetch('https://api.example.com/cached-data')
const cachedData = await res.json()
return (
<div>
{header}
Expand Down Expand Up @@ -513,7 +531,8 @@ async function CacheComponent({
children, // children: another slot for nested composition
}) {
'use cache'
const cachedData = await fetch('/api/cached-data')
const res = await fetch('https://api.example.com/cached-data')
const cachedData = await res.json()
return (
<div>
{header}
Expand Down
4 changes: 2 additions & 2 deletions docs/01-app/03-api-reference/02-components/image.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ An integer between `1` and `100` that sets the quality of the optimized image. H
<Image quality={75} />
```

If you’ve configured [qualities](#qualities) in `next.config.js`, the value must match one of the allowed entries.
If you’ve configured [qualities](#qualities) in `next.config.js`, a value outside that list is coerced to the closest allowed entry. For example, with `qualities: [50, 75, 100]`, a `quality` of `80` is served as `75`. Development logs a warning so you can add the value to the allowlist.

> **Good to know**: If the original image is already low quality, setting a high quality value will increase the file size without improving appearance.

Expand Down Expand Up @@ -1069,7 +1069,7 @@ export default function MyImage() {
}
```

When using `fill`, the parent element must have `position: relative` or `display: block`. This is necessary for the proper rendering of the image element in that layout mode.
When using `fill`, the parent element must be positioned, with `position: relative`, `fixed`, or `absolute`. The image itself uses `position: absolute`, so it sizes against the nearest positioned ancestor.

```jsx
<div style={{ position: 'relative' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ export default async function sitemap(props) {
}
```

Your generated sitemaps will be available at `/.../sitemap/[id]`. For example, `/product/sitemap/1.xml`.
Your generated sitemaps will be available at `/.../sitemap/[id].xml`. For example, `/product/sitemap/1.xml`.

See the [`generateSitemaps` API reference](/docs/app/api-reference/functions/generate-sitemaps) for more information.

Expand All @@ -413,6 +413,8 @@ type Sitemap = Array<{
alternates?: {
languages?: Languages<string>
}
images?: string[]
videos?: Videos[]
}>
```

Expand Down
2 changes: 1 addition & 1 deletion docs/01-app/03-api-reference/04-functions/cacheLife.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const nextConfig = {
cacheComponents: true,
}

export default nextConfig
module.exports = nextConfig
```

`cacheLife` can only be used within a cache directive scope.
Expand Down
28 changes: 21 additions & 7 deletions docs/01-app/03-api-reference/04-functions/cacheTag.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const nextConfig = {
cacheComponents: true,
}

export default nextConfig
module.exports = nextConfig
```

The `cacheTag` function takes one or more string values.
Expand All @@ -44,7 +44,8 @@ import { cacheTag } from 'next/cache'
export async function getData() {
'use cache'
cacheTag('my-data')
const data = await fetch('/api/data')
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return data
}
```
Expand All @@ -55,7 +56,8 @@ import { cacheTag } from 'next/cache'
export async function getData() {
'use cache'
cacheTag('my-data')
const data = await fetch('/api/data')
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return data
}
```
Expand Down Expand Up @@ -118,7 +120,10 @@ export async function Bookings({ type = 'haircut' }: BookingsProps) {
cacheTag('bookings-data')

async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
const response = await fetch(
`https://api.example.com/bookings?type=${encodeURIComponent(type)}`
)
const data = await response.json()
return data
}

Expand All @@ -134,7 +139,10 @@ export async function Bookings({ type = 'haircut' }) {
cacheTag('bookings-data')

async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
const response = await fetch(
`https://api.example.com/bookings?type=${encodeURIComponent(type)}`
)
const data = await response.json()
return data
}

Expand All @@ -156,7 +164,10 @@ interface BookingsProps {
export async function Bookings({ type = 'haircut' }: BookingsProps) {
async function getBookingsData() {
'use cache'
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
const response = await fetch(
`https://api.example.com/bookings?type=${encodeURIComponent(type)}`
)
const data = await response.json()
cacheTag('bookings-data', data.id)
return data
}
Expand All @@ -170,7 +181,10 @@ import { cacheTag } from 'next/cache'
export async function Bookings({ type = 'haircut' }) {
async function getBookingsData() {
'use cache'
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
const response = await fetch(
`https://api.example.com/bookings?type=${encodeURIComponent(type)}`
)
const data = await response.json()
cacheTag('bookings-data', data.id)
return data
}
Expand Down
2 changes: 1 addition & 1 deletion docs/01-app/03-api-reference/04-functions/fetch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ fetch(url, { signal })
## Troubleshooting

### Fetch default `auto no store` and `cache: 'no-store'` not showing fresh data in development
### Fetch default `auto no cache` and `cache: 'no-store'` not showing fresh data in development

Next.js caches `fetch` responses in Server Components across Hot Module Replacement (HMR) in local development for faster responses and to reduce costs for billed API calls.

Expand Down
Loading
Loading