From 0b7e96f41fa1a5603ae1d6878774c3c9c28590a3 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 18 Aug 2026 10:20:11 +0200 Subject: [PATCH 1/7] test: cover dynamic APIs with i18n base path (#97367) Recreation of https://github.com/vercel/next.js/pull/96910 ### What? Adds a test for i18n basepath fallbacks. ### Why? We had this test in `vercel/vercel`: https://github.com/vercel/vercel/blob/main/packages/next/test/fixtures/00-i18n-basepath-fallback-false-404/index.test.js We're getting rid of it in favor of moving it to here in Next.js. This new test is meant to be equivalent to the original. Co-authored-by: Anthony Shew --- .../i18n-basepath-fallback-false-404.test.ts | 17 +++++++++++++++++ .../next.config.js | 7 +++++++ .../pages/404.tsx | 3 +++ .../pages/api/blog/[slug].ts | 5 +++++ .../pages/api/catchall/[...rest].ts | 5 +++++ .../pages/foo/[slug].tsx | 14 ++++++++++++++ .../pages/index.tsx | 3 +++ 7 files changed, 54 insertions(+) create mode 100644 test/e2e/i18n-basepath-fallback-false-404/i18n-basepath-fallback-false-404.test.ts create mode 100644 test/e2e/i18n-basepath-fallback-false-404/next.config.js create mode 100644 test/e2e/i18n-basepath-fallback-false-404/pages/404.tsx create mode 100644 test/e2e/i18n-basepath-fallback-false-404/pages/api/blog/[slug].ts create mode 100644 test/e2e/i18n-basepath-fallback-false-404/pages/api/catchall/[...rest].ts create mode 100644 test/e2e/i18n-basepath-fallback-false-404/pages/foo/[slug].tsx create mode 100644 test/e2e/i18n-basepath-fallback-false-404/pages/index.tsx diff --git a/test/e2e/i18n-basepath-fallback-false-404/i18n-basepath-fallback-false-404.test.ts b/test/e2e/i18n-basepath-fallback-false-404/i18n-basepath-fallback-false-404.test.ts new file mode 100644 index 000000000000..535940ec4035 --- /dev/null +++ b/test/e2e/i18n-basepath-fallback-false-404/i18n-basepath-fallback-false-404.test.ts @@ -0,0 +1,17 @@ +import { nextTestSetup } from 'e2e-utils' + +describe('i18n-basepath-fallback-false-404', () => { + const { next } = nextTestSetup({ + files: __dirname, + }) + + it.each([ + ['/docs/api/blog/first', { slug: 'first' }], + ['/docs/api/catchall/hello/world', { rest: ['hello', 'world'] }], + ])('should resolve the dynamic API route %s', async (pathname, expected) => { + const res = await next.fetch(pathname) + + expect(res.status).toBe(200) + expect(await res.json()).toEqual(expected) + }) +}) diff --git a/test/e2e/i18n-basepath-fallback-false-404/next.config.js b/test/e2e/i18n-basepath-fallback-false-404/next.config.js new file mode 100644 index 000000000000..c4943b7551b4 --- /dev/null +++ b/test/e2e/i18n-basepath-fallback-false-404/next.config.js @@ -0,0 +1,7 @@ +module.exports = { + basePath: '/docs', + i18n: { + locales: ['en', 'fr'], + defaultLocale: 'en', + }, +} diff --git a/test/e2e/i18n-basepath-fallback-false-404/pages/404.tsx b/test/e2e/i18n-basepath-fallback-false-404/pages/404.tsx new file mode 100644 index 000000000000..a5a63a6a09ea --- /dev/null +++ b/test/e2e/i18n-basepath-fallback-false-404/pages/404.tsx @@ -0,0 +1,3 @@ +export default function NotFound() { + return 'not found page' +} diff --git a/test/e2e/i18n-basepath-fallback-false-404/pages/api/blog/[slug].ts b/test/e2e/i18n-basepath-fallback-false-404/pages/api/blog/[slug].ts new file mode 100644 index 000000000000..191d77ca51ce --- /dev/null +++ b/test/e2e/i18n-basepath-fallback-false-404/pages/api/blog/[slug].ts @@ -0,0 +1,5 @@ +import type { NextApiRequest, NextApiResponse } from 'next' + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + res.json({ slug: req.query.slug }) +} diff --git a/test/e2e/i18n-basepath-fallback-false-404/pages/api/catchall/[...rest].ts b/test/e2e/i18n-basepath-fallback-false-404/pages/api/catchall/[...rest].ts new file mode 100644 index 000000000000..119d4f4f0847 --- /dev/null +++ b/test/e2e/i18n-basepath-fallback-false-404/pages/api/catchall/[...rest].ts @@ -0,0 +1,5 @@ +import type { NextApiRequest, NextApiResponse } from 'next' + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + res.json({ rest: req.query.rest }) +} diff --git a/test/e2e/i18n-basepath-fallback-false-404/pages/foo/[slug].tsx b/test/e2e/i18n-basepath-fallback-false-404/pages/foo/[slug].tsx new file mode 100644 index 000000000000..603b29eb3d5c --- /dev/null +++ b/test/e2e/i18n-basepath-fallback-false-404/pages/foo/[slug].tsx @@ -0,0 +1,14 @@ +export default function Page() { + return 'dynamic page' +} + +export function getStaticProps() { + return { props: {} } +} + +export function getStaticPaths() { + return { + paths: [{ params: { slug: 'first' } }], + fallback: false, + } +} diff --git a/test/e2e/i18n-basepath-fallback-false-404/pages/index.tsx b/test/e2e/i18n-basepath-fallback-false-404/pages/index.tsx new file mode 100644 index 000000000000..ff7159d9149f --- /dev/null +++ b/test/e2e/i18n-basepath-fallback-false-404/pages/index.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

hello world

+} From d6ae012436bd7758aa0e082e7820918791f4f4f4 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 18 Aug 2026 11:47:21 +0200 Subject: [PATCH 2/7] test: Don't wait trying to load non-existing images (#97488) These tests were timing out because they are suddenly waiting for a very long DNS timeout - https://github.com/vercel/next.js/actions/runs/32116429187/job/95655640990?pr=90300 - https://github.com/vercel/next.js/actions/runs/32116429187/job/95655640961?pr=90300 --- .../next-image-legacy/basic/basic.test.ts | 22 ++++++++++++++----- .../custom-resolver/custom-resolver.test.ts | 16 ++++++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/test/production/next-image-legacy/basic/basic.test.ts b/test/production/next-image-legacy/basic/basic.test.ts index ed79ae676f26..869ff2354c5a 100644 --- a/test/production/next-image-legacy/basic/basic.test.ts +++ b/test/production/next-image-legacy/basic/basic.test.ts @@ -1,9 +1,21 @@ import { nextTestSetup, type Playwright } from 'e2e-utils' import { retry } from 'next-test-utils' +import type { Page } from 'playwright' const emptyImage = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' +const browserOptions = { + beforePageLoad(page: Page) { + // Block all image requests to external hosts immediately so we are not introducing flakes due + // to long DNS timeouts + page.route( + /^https:\/\/(?:example\.com|arbitraryurl\.com|example\.vercel\.sh|www\.otherhost\.com)\//, + (route) => route.abort() + ) + }, +} + describe('Image Component Tests', () => { const { next } = nextTestSetup({ files: __dirname, @@ -289,7 +301,7 @@ describe('Image Component Tests', () => { describe('SSR Image Component Tests', () => { let browser: Playwright beforeAll(async () => { - browser = await next.browser('/') + browser = await next.browser('/', browserOptions) }) runTests(() => browser) @@ -337,7 +349,7 @@ describe('Image Component Tests', () => { ).toBe('intrinsic') }) it('should not pass config to custom loader prop', async () => { - const loaderBrowser = await next.browser('/loader-prop') + const loaderBrowser = await next.browser('/loader-prop', browserOptions) expect( await loaderBrowser.elementById('loader-prop-img').getAttribute('src') ).toBe('https://example.vercel.sh/success/foo.jpg?width=1024') @@ -354,7 +366,7 @@ describe('Image Component Tests', () => { describe('Client-side Image Component Tests', () => { let browser: Playwright beforeAll(async () => { - browser = await next.browser('/') + browser = await next.browser('/', browserOptions) await browser.waitForElementByCss('#clientlink').click() }) runTests(() => browser) @@ -402,7 +414,7 @@ describe('Image Component Tests', () => { describe('SSR Lazy Loading Tests', () => { let browser: Playwright beforeAll(async () => { - browser = await next.browser('/lazy') + browser = await next.browser('/lazy', browserOptions) }) lazyLoadingTests(() => browser) }) @@ -410,7 +422,7 @@ describe('Image Component Tests', () => { describe('Client-side Lazy Loading Tests', () => { let browser: Playwright beforeAll(async () => { - browser = await next.browser('/') + browser = await next.browser('/', browserOptions) await browser.waitForElementByCss('#lazylink').click() await new Promise((r) => setTimeout(r, 500)) }) diff --git a/test/production/next-image-legacy/custom-resolver/custom-resolver.test.ts b/test/production/next-image-legacy/custom-resolver/custom-resolver.test.ts index 461187763661..8d590b0260f9 100644 --- a/test/production/next-image-legacy/custom-resolver/custom-resolver.test.ts +++ b/test/production/next-image-legacy/custom-resolver/custom-resolver.test.ts @@ -1,4 +1,16 @@ import { nextTestSetup, type Playwright } from 'e2e-utils' +import type { Page } from 'playwright' + +const browserOptions = { + beforePageLoad(page: Page) { + // Block all image requests to external hosts immediately so we are not introducing flakes due + // to long DNS timeouts + page.route( + /^https:\/\/(?:customresolver\.com|arbitraryurl\.com)\//, + (route) => route.abort() + ) + }, +} describe('Custom Resolver Tests', () => { const { next } = nextTestSetup({ @@ -29,7 +41,7 @@ describe('Custom Resolver Tests', () => { describe('SSR Custom Loader Tests', () => { let browser: Playwright beforeAll(async () => { - browser = await next.browser('/') + browser = await next.browser('/', browserOptions) }) runTests(() => browser) }) @@ -37,7 +49,7 @@ describe('Custom Resolver Tests', () => { describe('Client-side Custom Loader Tests', () => { let browser: Playwright beforeAll(async () => { - browser = await next.browser('/client-side') + browser = await next.browser('/client-side', browserOptions) }) runTests(() => browser) }) From e551922083bc467f57aef24b7132885f63abd7b1 Mon Sep 17 00:00:00 2001 From: Joseph Date: Tue, 18 Aug 2026 11:52:26 +0200 Subject: [PATCH 3/7] docs: app router reference accuracy (#97477) - Adding docs/01-app/03-api-reference/05-config/01-next-config-js/cacheMaxMemorySize.mdx - Various use cache snippet fixes - Break nuance for fetch default - Point to correct turbopack cache flags --- .../caching-without-cache-components.mdx | 2 +- .../01-app/02-guides/upgrading/version-16.mdx | 4 +- .../01-directives/use-cache-private.mdx | 2 +- .../01-directives/use-cache-remote.mdx | 2 +- .../01-directives/use-cache.mdx | 53 +++++++++++++------ .../03-api-reference/02-components/image.mdx | 4 +- .../01-metadata/sitemap.mdx | 4 +- .../04-functions/cacheLife.mdx | 2 +- .../04-functions/cacheTag.mdx | 28 +++++++--- .../03-api-reference/04-functions/fetch.mdx | 2 +- .../04-functions/generate-metadata.mdx | 5 +- .../04-functions/updateTag.mdx | 2 +- .../01-next-config-js/cacheHandlers.mdx | 2 +- .../05-config/01-next-config-js/cacheLife.mdx | 6 ++- .../01-next-config-js/cacheMaxMemorySize.mdx | 36 +++++++++++++ .../05-config/01-next-config-js/images.mdx | 4 +- .../incrementalCacheHandlerPath.mdx | 2 +- .../01-next-config-js/staticGeneration.mdx | 2 +- .../05-config/01-next-config-js/taint.mdx | 14 ++--- .../05-config/01-next-config-js/turbopack.mdx | 2 +- docs/01-app/03-api-reference/06-cli/next.mdx | 30 +++++------ 21 files changed, 139 insertions(+), 69 deletions(-) create mode 100644 docs/01-app/03-api-reference/05-config/01-next-config-js/cacheMaxMemorySize.mdx diff --git a/docs/01-app/02-guides/caching-without-cache-components.mdx b/docs/01-app/02-guides/caching-without-cache-components.mdx index 5555e7d905c8..af27fcd8c5b4 100644 --- a/docs/01-app/02-guides/caching-without-cache-components.mdx +++ b/docs/01-app/02-guides/caching-without-cache-components.mdx @@ -108,7 +108,7 @@ export const dynamic = 'auto'
This is an advanced option that should only be used if you specifically need to override the default behavior. -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. diff --git a/docs/01-app/02-guides/upgrading/version-16.mdx b/docs/01-app/02-guides/upgrading/version-16.mdx index 4ca2411d98cf..0bd34e3d0298 100644 --- a/docs/01-app/02-guides/upgrading/version-16.mdx +++ b/docs/01-app/02-guides/upgrading/version-16.mdx @@ -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) @@ -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. diff --git a/docs/01-app/03-api-reference/01-directives/use-cache-private.mdx b/docs/01-app/03-api-reference/01-directives/use-cache-private.mdx index 928eac58dc86..26a7ec16475a 100644 --- a/docs/01-app/03-api-reference/01-directives/use-cache-private.mdx +++ b/docs/01-app/03-api-reference/01-directives/use-cache-private.mdx @@ -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. diff --git a/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx b/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx index 21f10da3ddad..640bf39bc00c 100644 --- a/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx +++ b/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx @@ -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. diff --git a/docs/01-app/03-api-reference/01-directives/use-cache.mdx b/docs/01-app/03-api-reference/01-directives/use-cache.mdx index e5084cc41930..75659409caf4 100644 --- a/docs/01-app/03-api-reference/01-directives/use-cache.mdx +++ b/docs/01-app/03-api-reference/01-directives/use-cache.mdx @@ -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 } ``` @@ -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') @@ -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. @@ -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() } ``` @@ -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() } ``` @@ -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() } ``` @@ -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 } @@ -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 } @@ -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 //... @@ -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 //... @@ -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 } ``` @@ -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 } ``` @@ -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 (
{header} @@ -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 (
{header} diff --git a/docs/01-app/03-api-reference/02-components/image.mdx b/docs/01-app/03-api-reference/02-components/image.mdx index d991234e6b4d..03680ec359be 100644 --- a/docs/01-app/03-api-reference/02-components/image.mdx +++ b/docs/01-app/03-api-reference/02-components/image.mdx @@ -239,7 +239,7 @@ An integer between `1` and `100` that sets the quality of the optimized image. H ``` -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. @@ -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
diff --git a/docs/01-app/03-api-reference/03-file-conventions/01-metadata/sitemap.mdx b/docs/01-app/03-api-reference/03-file-conventions/01-metadata/sitemap.mdx index dc51591188a9..f195d6beea9a 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/01-metadata/sitemap.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/01-metadata/sitemap.mdx @@ -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. @@ -413,6 +413,8 @@ type Sitemap = Array<{ alternates?: { languages?: Languages } + images?: string[] + videos?: Videos[] }> ``` diff --git a/docs/01-app/03-api-reference/04-functions/cacheLife.mdx b/docs/01-app/03-api-reference/04-functions/cacheLife.mdx index 83feeffebbb8..b04d33e7fe4a 100644 --- a/docs/01-app/03-api-reference/04-functions/cacheLife.mdx +++ b/docs/01-app/03-api-reference/04-functions/cacheLife.mdx @@ -34,7 +34,7 @@ const nextConfig = { cacheComponents: true, } -export default nextConfig +module.exports = nextConfig ``` `cacheLife` can only be used within a cache directive scope. diff --git a/docs/01-app/03-api-reference/04-functions/cacheTag.mdx b/docs/01-app/03-api-reference/04-functions/cacheTag.mdx index c8691934e8c2..49f13e6f9f84 100644 --- a/docs/01-app/03-api-reference/04-functions/cacheTag.mdx +++ b/docs/01-app/03-api-reference/04-functions/cacheTag.mdx @@ -33,7 +33,7 @@ const nextConfig = { cacheComponents: true, } -export default nextConfig +module.exports = nextConfig ``` The `cacheTag` function takes one or more string values. @@ -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 } ``` @@ -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 } ``` @@ -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 } @@ -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 } @@ -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 } @@ -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 } diff --git a/docs/01-app/03-api-reference/04-functions/fetch.mdx b/docs/01-app/03-api-reference/04-functions/fetch.mdx index 2c6439cfe3ee..fbed6cf6f87c 100644 --- a/docs/01-app/03-api-reference/04-functions/fetch.mdx +++ b/docs/01-app/03-api-reference/04-functions/fetch.mdx @@ -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. diff --git a/docs/01-app/03-api-reference/04-functions/generate-metadata.mdx b/docs/01-app/03-api-reference/04-functions/generate-metadata.mdx index 2585c0df6a6b..6eeebd8151a1 100644 --- a/docs/01-app/03-api-reference/04-functions/generate-metadata.mdx +++ b/docs/01-app/03-api-reference/04-functions/generate-metadata.mdx @@ -383,7 +383,6 @@ export const metadata = { - @@ -1124,7 +1123,7 @@ The following metadata types do not currently have built-in support. However, th | `