# @contentful/optimization-nextjs 中文文档

规范地址：https://npmcn.com/package/%40contentful/optimization-nextjs/

版本：2\.1\.3
npm 元数据更新时间：2026-11-06T12:30:43.583Z
中文译文更新时间：2026-11-10T22:38:19.776Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40contentful/optimization-nextjs
原文对照：https://npmcn.com/package/%40contentful/optimization-nextjs/?lang=original
项目主页：https://github.com/contentful/optimization#readme
源码仓库：https://github.com/contentful/optimization

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：927 kB，87 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：2 个
- peer 依赖：next \>=13\.0\.0，react \>=18\.3\.1，react-dom \>=18\.3\.1
- 首次发布：2026-06-25T09:53:33.031Z
- 最新版本发布：2026-11-06T12:30:43.317Z
- 近 30 天下载量：2512（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：16（近 12 个月 16 个）

## 中文简介

Next.js 内容优化适配器

## 安装

```sh
npm install @contentful/optimization-nextjs
```

也可以使用：`pnpm add @contentful/optimization-nextjs`、`yarn add @contentful/optimization-nextjs`、`bun add @contentful/optimization-nextjs`

## README

[![Contentful Logo](https://raw.githubusercontent.com/contentful/optimization/optimization-nextjs-v2.1.3/contentful-icon.png "Contentful")](https://www.contentful.com/developers/docs/personalization/)

# 内容个性化分析

### Next.js SDK 适应器

[读取](https://github.com/contentful/optimization/blob/optimization-nextjs-v2.1.3/packages/web/frameworks/nextjs-sdk/README.md) • 妇女 [指南](https://contentful.github.io/optimization/documents/Documentation.Guides.html) • 妇女 [参考文献](https://contentful.github.io/optimization) • 妇女 [捐款](https://github.com/contentful/optimization/blob/optimization-nextjs-v2.1.3/CONTRIBUTING.md)

`@contentful/optimization-nextjs` 是 Next.js 应用程序的稀疏适配器。 它组成了节点 服务器帮助器, React Web root, 和边缘安全核心通过器; 这不是一个新的优化 运行时间。 包根有意没有运行时间导出 。 导入文件之一 子路径这样服务器,客户端,路由器,和边缘边界保持清晰.

> \[大
> 
> 从v1升级? 跟着 [v1-v2 迁移指南](https://contentful.github.io/optimization/documents/Documentation.Guides.migrating-optimization-sdk-packages-from-v1-to-v2.html) 在更改软件包版本之前.

## 这个软件包提供了什么

| 运行时间 | 导入路径 | 责任 |
| --- | --- | --- |
| App 路由器服务器 | `@contentful/optimization-nextjs/app-router/server` | 服务器绑定、请求模式和明确的交接助手 |
| App 路由器客户端 | `@contentful/optimization-nextjs/app-router/client` | App 路由器客户端组件的客户端绑定 |
| 缓存中间软件 | `@contentful/optimization-nextjs/cache-middleware` | 下一个代理或中间软件 公用配置缓存重写 |
| 页面路由器 | `@contentful/optimization-nextjs/pages-router` | Pages 路由器客户端绑定和反应根 |
| 页面服务器 | `@contentful/optimization-nextjs/pages-router/server` | 页面路由器 `getServerSideProps` 请求移交 |
| 边缘 | `@contentful/optimization-nextjs/edge` | 边际运行时间请求和公转交接工具 |
| 客户端 | `@contentful/optimization-nextjs/client` | 路由器中性 React SDK 提供者、 钩子、 根 |
| 示马斯 | `@contentful/optimization-nextjs/api-schemas` | 共享 API 类型、 计划、 结构守护 |
| 服务器 | `@contentful/optimization-nextjs/server` | 节点 SDK 配置、 请求绑定、 包装 |
| 请求处理器 | `@contentful/optimization-nextjs/request-handler` | 下一个中件/ 代理请求上下文转发 |
| 跟踪 | `@contentful/optimization-nextjs/tracking-attributes` | 安全部门改革 `data-ctfl-*` 跟踪属性 |

## 安装

```sh
pnpm add @contentful/optimization-nextjs contentful
```

Next.js,React,和React DOM是应用程序拥有的同级依赖关系. 适配器使用运行时间 已经由您的应用程序安装, 而不是安装自己的副本 。 这个 `contentful` 软件包是 用于获取实例的管理条目的应用程序拥有的 CDA 客户端.

约束 `OptimizationProvider` 处理 React Web 内容 SDK 上下文,浏览器交接, 水分化模式, 和有管理的进取预置子树。 使用约束 `OptimizationRoot` 路线 根,因为它增加了初始的页面事件线条通过 `routeKey`, (中文(简体) ), `buildPagePayload`,或 `initialPagePayload`。不要将这些页面活动道具传递给 `OptimizationProvider`。 。 。 .

对于手动服务器和边缘请求,通过 `profileId` 经验连续性或全经验 `Profile` 结束 `profile` 为"洞察力"送货.

## 请求地点

设定 `api.location` 在普通的 App 路由器、 Pages 路由器、 服务器或 Edge SDK 配置中. 客户端绑定在初始化期间将它传给他们拥有的 React Web 运行时间 :

```ts
const optimization = bindNextjsAppRouterServerOptimization({
  spaceId: 'space-id',
  api: { location: { countryCode: 'DE', city: 'Berlin' } },
})
```

用于特定请求地点 `experienceOptions.location` 现有人工请求 帮助: App 路由器 `createRequestHandoff()`,页路由器 `createRequestHandoff(context, options)`, (中文(简体) ), 边缘 `createEdgeRequestHandoff()`,或 `/server` 请求帮助者,例如 `bindNextjsOptimizationRequest()`。例如,在手动 App 路由器流中:

```ts
const handoff = await optimization.createRequestHandoff({
  cache: { scope: 'private-request' },
  hydration: 'preserve-server',
  pagePayload: { properties: { route: '/products' } },
  request: incomingRequest,
  experienceOptions: { location: { countryCode: 'FR', city: 'Paris' } },
})
```

请求值取代整个配置的默认值 。 使用 `experienceOptions: { location: {} }` 用于明确的空默认,而不是 API 地理定位。 活动 `context.location` 优先排序 超过匹配请求字段。 位置适用于经验突变;可信任的交接文件 Get retrach 不应用它。 服务器位置不是以后浏览器的永久配置锁定 请求; 配置浏览器 `api.location` 当运行时间需要相同的默认时,则单独进行. 空位置无法清除现有的配置文件位置 。 见 [位置输入和简介更新](https://contentful.github.io/optimization/documents/Documentation.Concepts.Profile_synchronization_between_client_and_server.html#location-inputs-and-profile-updates)。 。 。 .

## 应用路由器设置

使用明确的 `/app-router/server` 财务报告和审定财务报表 `/app-router/client` 输入点使每个模块有一个 运行时间和类型表面. `bindNextjsAppRouterServerOptimization()` 返回时 `NextjsAppRouterServerOptimization`· ; `bindNextjsAppRouterClientOptimization()` 返回时 `NextjsAppRouterClientOptimization`。 。 。 .

### 要求个性化快速启动

将服务器SDK装入一次只装在服务器模块中. 被窝住 `optimization.request` 家庭就是我们 个人化请求的默认表面 :

```tsx
import 'server-only'
import { bindNextjsAppRouterServerOptimization } from '@contentful/optimization-nextjs/app-router/server'
import { contentfulClient } from './contentful'
import { getAppConsent } from './consent'

export const optimization = bindNextjsAppRouterServerOptimization({
  spaceId: 'space-id',
  environment: 'master',
  locale: 'en-US',
  contentful: { client: contentfulClient },
  consent: {
    server: ({ cookies }) => (getAppConsent(cookies) ? { events: true, persistence: true } : false),
    clientDefaults: { consent: false, persistenceConsent: false },
  },
})

export const {
  NextAppAutoPageTracker: RequestNextAppAutoPageTracker,
  OptimizationProvider: RequestOptimizationProvider,
  OptimizationRoot: RequestOptimizationRoot,
  OptimizedEntry: RequestOptimizedEntry,
} = optimization.request
```

配置请求处理器, 因此 Server 组件接收静态请求上下文 。 下一个.js 16 用途 `proxy.ts` 带有 `proxy` 输出。 下一个.js 13至15个用途 `middleware.ts` 带有 `middleware` 导出; 处理器正文相同 :

```ts
import { createNextjsOptimizationContextHandler } from '@contentful/optimization-nextjs/request-handler'

export const proxy = createNextjsOptimizationContextHandler()
```

在请求边界外保留公共 shell 内容 。 把请求的运行时间,跟踪器,和 内部个性化岛屿 `Suspense`; 跟踪器读取 Next.js 搜索参数。 根预选 并向浏览器交接提供管理下的基线 :

```tsx
import { AppShell } from '@/components/AppShell'
import { Hero } from '@/components/Hero'
import {
  RequestNextAppAutoPageTracker,
  RequestOptimizationRoot,
  RequestOptimizedEntry,
} from '@/lib/optimization'
import { Suspense } from 'react'

const heroEntryId = 'hero-entry-id'

function PersonalizedContentFallback() {
  return <section aria-busy="true">Loading featured content…</section>
}

export default function Page() {
  return (
    <AppShell>
      <Suspense fallback={<PersonalizedContentFallback />}>
        <RequestOptimizationRoot prefetchManagedEntries={[heroEntryId]}>
          <RequestNextAppAutoPageTracker />
          <RequestOptimizedEntry entryId={heroEntryId}>
            {(resolvedHero) => <Hero entry={resolvedHero} />}
          </RequestOptimizedEntry>
        </RequestOptimizationRoot>
      </Suspense>
    </AppShell>
  )
}
```

请求家庭创造了一个 `private-request` 移交、使用 `preserve-server` 默认水分化, 并让所有四个请求组件共享相同的请求初始化. 为SDK管理 条目中,它开始请求初始化和内容基线获取,然后解决 之后的选定变体。 它获得URL,路由密钥,初始页面有效载荷, 信头,以及来自已转发的请求上下文的 cookie 。 应用程序不需要自己的反应缓存, 请求 shell 、 重复等待 、 URL 解析 、 或 页面加载 .

### 选择谁拥有条目获取

两种获取工作流程都解决了请求选择的内容:

| 所有权 | 条目来源 | 使用时间 |
| --- | --- | --- |
| **注册** | `baselineEntry` | 您的应用程序拥有内容客户端、 查询、 缓存或数据层 . |
| **SDK 管理** | `entryId` 或者说 `managedEntry` | 服务器绑定配置 `contentful: { client }` 而SDK拥有基准读取. |

对于应用软件的取取,加载条目并直接通过:

```tsx
const hero = await getHeroEntry({ locale: 'en-US', include: 10 })

return (
  <RequestOptimizedEntry baselineEntry={hero}>
    {(resolvedHero) => <Hero entry={resolvedHero} />}
  </RequestOptimizedEntry>
)
```

只有SDK管理的取取程序在请求初始化和内容之间直接重叠 读取。 App自有的取回程序仍然使用同样的请求选择的解析程序 基线.

仍然需要代理或中间软件边界,因为它转发了已消毒的请求 URL. 保留任何 `Suspense` 或者说 `connection()` 您的 Next.js 渲染和缓存所需的边界 组件设置; 请求模式删除 SDK 请求管道, 而不是 Next.js 渲染要求 .

设定 `request.hydration` 在服务器绑定器上,只有当一个路由需要另一个固定的水合模式或 一个基于 `requestUrl` 财务报告和审定财务报表 `routeKey`设置 `request.trustedRequestHandoff` 改为 `true` 只有在请求处理器配置到服务器 SDK 并获得同意后才能转发 信任的页面和配置文件上下文 .

### 客户端组件

绑定 App 路由器客户端表面 `"use client"` 模块。 它没有私人要求的家庭或 手动服务器交接 API :

```tsx
'use client'

import { bindNextjsAppRouterClientOptimization } from '@contentful/optimization-nextjs/app-router/client'

export const clientOptimization = bindNextjsAppRouterClientOptimization({
  spaceId: 'space-id',
  environment: 'master',
  locale: 'en-US',
  consent: {
    clientDefaults: { consent: false, persistenceConsent: false },
  },
})
```

服务器绑定器使用 `contentful` 在服务器功能路径中省略该客户端的序列 客户端道具。 保留任何只浏览器的Contentful获取明确应用的自控.

绑定的服务器 `OptimizedEntry` 完全接受一个来源:手动 `baselineEntry`,管理 `entryId` 可选 `entryQuery`,或一个 `managedEntry` 对象为 `contentType`, (中文(简体) ), `slug`选项 `slugField`选择 `entryQuery`。 。 。 . `slugField` 默认为 `slug`。成功的弹道检查 制作并跟踪取入的条目 `sys.id`无效的源组合 `Bound Next.js OptimizedEntry requires exactly one source: baselineEntry, entryId, or managedEntry.`

### 静态、公共和分析表面

使用顶级服务器成员, 不 `optimization.request`对于可缓存的静态路线, 应用型公共布局, 和只分析路线。 这些成员使用明确的投入,并且 未读 `next/headers` 或打电话 `cookies()`。 。 。 .

使用 `createPublicPermutationHandoff()` 由 App 路由器提供的 app 自主公共布局 缓存组件, Pages 路由器 ISR, CDN 路由, 或 Edge 运行时路由处理器 。 这个 应用程序提供选定的优化和公共布置维度。 提出请求 配置文件必须使用 `private-request` 缓存范围 .

```tsx
const handoff = optimization.createPublicPermutationHandoff({
  permutationKey: permutation.slug,
  cacheVersion: permutation.cacheVersion,
  locale: permutation.locale,
  entryIds: permutation.entryIds,
  selectedOptimizations: permutation.selectedOptimizations,
  hydration: 'preserve-server',
  initialPageEvent: 'emit',
})
```

使用顶级 `OptimizationAnalyticsRoot` 仅用于分析路径。 个人化内容 在服务器上,附加跟踪属性 `@contentful/optimization-nextjs/tracking-attributes`,然后通过 `analytics-only` 交给 树根.

### 手动请求

使用顶级 `createRequestHandoff()` 只有在高级管弦乐需要明确控制时 请求、页载荷或交接。 把交接权传给顶层根:

```tsx
import { cookies, headers } from 'next/headers'
import { optimization } from '@/lib/optimization'

const { OptimizationRoot } = optimization

export default async function Page() {
  const handoff = await optimization.createRequestHandoff({
    cache: { scope: 'private-request' },
    hydration: 'preserve-server',
    pagePayload: { properties: { route: '/products' } },
    request: {
      cookies: await cookies(),
      headers: new Headers(await headers()),
      url: 'https://example.com/products',
    },
  })

  return (
    <OptimizationRoot
      handoff={handoff}
      prefetchManagedEntries={[
        { contentType: 'productPage', slug: 'featured', entryQuery: { locale: 'en-US' } },
      ]}
      routeKey="/products"
      buildPagePayload={() => ({ properties: { route: '/products' } })}
    >
      {/* route content */}
    </OptimizationRoot>
  )
}
```

`prefetchManagedEntries` 在服务器上获取描述符并将其基线合并到 `handoff.entries`; 弹出将规范描述符嵌入下面 `managedEntry` 并存储 已获取 `sys.id` 内 `entryId`服务器 `OptimizedEntry` 只获取此渲染, 所以使用 root 当匹配的浏览器管理源必须不另取水合物时,预留.

## 页面路由器设置

使用 `/pages-router` 用于客户端根在 `_app.tsx` 财务报告和审定财务报表 `/pages-router/server` 页:1 `getServerSideProps`。服务器帮助器是分开的,因为客户端绑定是一个 `"use client"` 输入.

```tsx
import { bindNextjsPagesRouterOptimization } from '@contentful/optimization-nextjs/pages-router'

export const { OptimizationRoot, OptimizationAnalyticsRoot, OptimizedEntry } =
  bindNextjsPagesRouterOptimization({
    spaceId: 'space-id',
    environment: 'master',
    consent: {
      clientDefaults: { consent: false, persistenceConsent: false },
    },
  })
```

```tsx
import { OptimizationRoot } from '@/lib/optimization'
import type { AppProps } from 'next/app'
import { useRouter } from 'next/router'

export default function App({ Component, pageProps }: AppProps) {
  const router = useRouter()
  const routeKey = router.asPath || router.pathname

  return (
    <OptimizationRoot
      buildPagePayload={() => ({ properties: { route: routeKey } })}
      handoff={pageProps.contentfulOptimization?.handoff}
      routeKey={routeKey}
    >
      <Component {...pageProps} />
    </OptimizationRoot>
  )
}
```

```tsx
import { bindNextjsPagesRouterServerOptimization } from '@contentful/optimization-nextjs/pages-router/server'
import { contentfulClient } from './contentful'

const { createRequestHandoff } = bindNextjsPagesRouterServerOptimization({
  spaceId: 'space-id',
  contentful: { client: contentfulClient },
  environment: 'master',
  consent: {
    server: { events: true, persistence: true },
  },
})

export async function getServerSideProps(context) {
  const handoff = await createRequestHandoff(context, {
    cache: { scope: 'private-request' },
    hydration: 'preserve-server',
    pagePayload: { properties: { route: context.resolvedUrl } },
    prefetchManagedEntries: [
      { contentType: 'productPage', slug: context.params.slug, entryQuery: { locale: 'en-US' } },
    ],
  })

  return { props: { contentfulOptimization: { handoff } } }
}
```

Pages 路由器服务器预选接受ID或内容类型/slug描述符并附加其基线 到浏览器交接。 绑定客户端 `OptimizedEntry` 财务报告和审定财务报表 `/client` `useOptimizedEntry` 接受 `baselineEntry`, (中文(简体) ), `entryId` 可选 `entryQuery`,或下面的内容类型/slug描述符 `managedEntry`相匹配的弹道源使用交接基线及其实际 `sys.id`。 。 。 .

## 首页决定前的工作

两个客户端都接受 `beforeInitialPage` 当浏览器身份或自定义操作时 必须在绑定内容根的初始页面决定前完成。 这个决定是根的 选择发送第一个浏览器页面事件或跳过它,因为一个应用的交接器已经拥有了 路径 :

```tsx
'use client'

import { bindNextjsAppRouterClientOptimization } from '@contentful/optimization-nextjs/app-router/client'

export const clientOptimization = bindNextjsAppRouterClientOptimization({
  spaceId: 'space-id',
  environment: 'master',
  beforeInitialPage: {
    run: async ({ identify }) => {
      await identify({ userId: visitor.id })
    },
    onError: reportBeforeInitialPageError,
  },
})

export const { RequestOptimizationRoot: ClientRequestOptimizationRoot } = clientOptimization

export function OptimizationApp({ children, routeKey }) {
  return (
    <clientOptimization.OptimizationRoot
      routeKey={routeKey}
      buildPagePayload={() => ({ properties: { route: routeKey } })}
    >
      {children}
    </clientOptimization.OptimizationRoot>
  )
}
```

直接 App 客户端 `OptimizationRoot` 需要这些明确的路径输入。 对于 App 路由器 请求家族,在服务器绑定器中注入初始页面前的客户端请求根 相反:

```tsx
import 'server-only'

import { bindNextjsAppRouterServerOptimization } from '@contentful/optimization-nextjs/app-router/server'
import { ClientRequestOptimizationRoot } from './optimization-client'

export const optimization = bindNextjsAppRouterServerOptimization(serverConfig, {
  request: { OptimizationRoot: ClientRequestOptimizationRoot },
})

export const { OptimizationRoot: RequestOptimizationRoot } = optimization.request
```

`RequestOptimizationRoot` 属于 App 客户端在初始页面工作前的结果; 结果 没有这项工作,就保留了现有的成员.

注射时 `RequestOptimizationRoot` 来源 `routeKey` 财务报告和审定财务报表 `buildPagePayload` 从 App 路由器 状态并替换请求家族的默认根。 不带就挂 `RequestNextAppAutoPageTracker`; 被注入的根拥有直接的初始页面决定, 然后再使用 路由改变。 组件引用跨越服务器构成边界, 但调用 保留在其客户端模块中,不输入服务器配置或飞行数据.

App服务器请求家族可以接受其页面事件,并将所有权放入交接. 这个 浏览器请求 root 应用交接器; 在其自定义的活运行时间存在后, 它引用 `beforeInitialPage`,标记尝试 路由,然后为以后的路由更改发出消息.

Pages路由器客户端绑定器在其仅限客户端的模块中使用相同的选项:

```tsx
import { bindNextjsPagesRouterOptimization } from '@contentful/optimization-nextjs/pages-router'

export const optimization = bindNextjsPagesRouterOptimization({
  spaceId: 'space-id',
  environment: 'master',
  beforeInitialPage: {
    run: ({ identify }) => identify({ userId: visitor.id }),
  },
})
```

客户端绑定器抓取回调,并仅转发到绑定内容根. 回电 接收器安全 `identify`, (中文(简体) ), `screen`,以及 `track` 方法。 。 。 它没有转交给约束方 `OptimizationProvider` 或者说 `OptimizationAnalyticsRoot`,而注入提供者不接受. 对于 Pages 路由器请求,服务器助手可以接受该页面事件并记录其所有权于 交接通过页面道具。 浏览器根应用该交接器后, 它的活的拥有 运行时间存在, 它引用 `beforeInitialPage`,使一个直接页面尝试或同一程序交接 ưμ㼯a.

这个 `NextjsClientOptimizationConfigWithoutBeforeInitialPage` 财务报告和审定财务报表 `NextjsClientOptimizationConfigWithBeforeInitialPage` 分支来源于 `NextjsBoundRootConfig`,选定分支则确定绑定根的页面道具。 无 `beforeInitialPage`中,包括 `initialPagePayload`与 `beforeInitialPage`,绑定根需要 `routeKey` 懒惰的 `buildPagePayload` 和拒绝 `initialPagePayload`拓宽时键入的变量 `NextjsClientOptimizationConfig` 使用此更严格的初始页前根合同,直到 配置在绑定前会缩小 .

调用返回的工作完成或监视器过期后, 根会读取最新的路径 以及一个直接页面尝试的有效载荷构建器。 成功应用的同路交接方式 直接决定a `skip`否则,它试图 `emit`。尝试到达终端后 结果,现有的页面发送器将生成一个未排放的初始 `skip` 标记尝试路线, 然后使用其常态 `emit` 用于后期路由更改的路径。 首页前的根是唯一的 页面所有者在其子树。 直接 App 根,注入 App 请求根,因此Pages 根 不挂载单独的 `NextAppAutoPageTracker`, (中文(简体) ), `RequestNextAppAutoPageTracker`,或 `NextPagesAutoPageTracker` 在这条路上.

何时 `maxWaitMs` 被省略,默认为3,000毫秒。 它接受积极的有限价值. `0`, (中文(简体) ), 负值, `NaN`, (中文(简体) ), `Infinity`,以及 `-Infinity` 同步掷出 `TypeError('beforeInitialPage.maxWaitMs must be a positive finite number.')` 在供应商之前, 回调、 页面或 `onError` 运行.

序为最上相. 归还属于 最初的工作。 火灾和遗忘的工作是后来的活动, 监督停止等待 不取消回调代码或飞行中请求。 虽然根仍然被挂起, 是一样的 sive owned runtime is current, callback 失败或监视器过期仍导致直接页面 尝试。 如果根卸载或运行时间被替换,则只替换未发送的本地页面和准备状态 继续被压制.

在直接页面尝试开始后, 路由更改既不取消, 也不启动 竞相尝试。 根会安顿下来,并标出捕捉到的路线,然后允许 页面排放。 仅在飞行中尝试时观察到的航道没有释放;航道变化 准备就绪后正常发射 现有录入期限可先输入回溯内容,而且 默认非活性行为在初始版工作过后保持倒计时冻结 成功 .

保留 `beforeInitialPage` 在只包含客户的模块中配置 。 App路由器服务器配置继承,以及 用于 Pages 路由器服务器绑定器的 `beforeInitialPage?: never` 边界。 两个服务器 绑定器拒绝包含此回调的导出客户端配置变量 。 应用请求根 注入会分别通过客户端组件引用;不会削弱该配置边界. Pages 服务器绑定器既不运行回调,也不串接到传递中 页面道具。 在 App 路由器构成中,回调会保留在其客户端组件模块中,并且确实 不输入服务器组件, 请求配置、 飞行数据、 交接、 缓存状态、 ISR 或边缘 帮手.

## 边缘运行时间

使用 `/edge` 用于导出 Edge 运行时路由处理器 `runtime = 'edge'`。帮助者接受 网络标准 `Request`, (中文(简体) ), `Headers`,然后 cookie 抓图,不导入节点 SDK 或其他 仅节点APIs.

```ts
import { configureNextjsEdgeOptimization } from '@contentful/optimization-nextjs/edge'

const { createEdgeRequestHandoff } = configureNextjsEdgeOptimization({
  spaceId: 'space-id',
  environment: 'master',
  consent: {
    server: { events: true, persistence: true },
    clientDefaults: { consent: false, persistenceConsent: false },
  },
})

export const runtime = 'edge'

export async function GET(request: Request) {
  const { handoff, persist } = await createEdgeRequestHandoff({
    cache: { scope: 'private-request' },
    hydration: 'preserve-server',
    pagePayload: { properties: { route: new URL(request.url).pathname } },
    request,
  })
  const response = new Response(renderHtml({ handoff }), {
    headers: { 'content-type': 'text/html; charset=utf-8' },
  })

  persist(response)

  return response
}
```

公共边际运行时间轮廓使用 `createPublicPermutationHandoff()` 从配置中 `/edge` 帮手 将它与 App 路由器缓存组件和页面路由器 ISR 分开; 路由名称或 帮助者名称本身并不能证明 Edge 运行时执行 .

## 服务器和跟踪助手

`@contentful/optimization-nextjs/server` 暴露出低级节点公用设施,例如 `configureNextjsServerOptimization()`, (中文(简体) ), `createNextjsRequestHandoff()`, (中文(简体) ), `ServerOptimizedEntry`,以及 `getNextjsServerOptimizationData()` 用于需要直接节点请求控制的应用程序.

模拟不同内容类型的基线和变体条目,见 [条目优化和变量分辨率](https://github.com/contentful/optimization/blob/optimization-nextjs-v2.1.3/documentation/concepts/entry-personalization-and-variant-resolution.md)。 。 。 .

`@contentful/optimization-nextjs/tracking-attributes` 曝光情况 `getServerTrackingAttributes()`页:1 Next.js 环绕 React Web/Web 跟踪属性通过. 用它来 服务器/静态/上接的标记,仅由分析器浏览器根来观察.

## 请求处理器助手

`@contentful/optimization-nextjs/request-handler` 显示代理服务器和中间软件助手 请求文本转发.

```ts
import { createNextjsOptimizationContextHandler } from '@contentful/optimization-nextjs/request-handler'

export const proxy = createNextjsOptimizationContextHandler()
```

请求- 文本处理器总是转发已静态的请求上下文头 。 打电话没有 选项,它只转发请求上下文。 配置时 `sdk` 财务报告和审定财务报表 `consent`,它解决 同意, 一次执行服务器页面请求, 转发压缩 `x-ctfl-opt-server-data` 上下文为 `encodeURIComponent(JSON.stringify({ consent, pageAccepted, profileId }))`,并坚持 `ctfl-opt-aid` 编辑 `NextResponse` 当坚忍被允许的时候。 设定 `request.trustedRequestHandoff` 改为 `true` 在 App 路由器服务器上绑定, 因此请求家族使用 已转发 `profileId` 无一秒 `page()` 调用和使用 `pageAccepted` 避免重复 第一页事件。 手动管弦,通过 `trustedRequestHandoff: true` 到顶层 `createRequestHandoff()` 换句话说 仅选择此配置的请求处理器覆盖的路径; 原始客户端提供 `x-ctfl-opt-server-data` 除非路由选择使用,否则会被忽略.

使用 `createNextjsPublicPermutationCacheMiddleware()` 从 `@contentful/optimization-nextjs/cache-middleware` 当代理代码需要公开排列时 缓存键重写 。 缓存中间软件可与已有的 `NextResponse`它保存着 非 SDK 响应和请求覆盖状态,同时去除 Stale SDK 拥有 `x-ctfl-opt-*` 请求 上下文在重写前.

## 常见问题

### @contentful/optimization-nextjs 是什么？

Next\.js 内容优化适配器

### 如何安装 @contentful/optimization-nextjs？

在项目目录运行 npm install @contentful/optimization-nextjs，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：next（\>=13\.0\.0）、react（\>=18\.3\.1）、react-dom（\>=18\.3\.1）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @contentful/optimization-nextjs 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @contentful/optimization-nextjs 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @contentful/optimization-nextjs 可以商用吗？

@contentful/optimization-nextjs 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @contentful/optimization-nextjs 的下载量有多少？

根据 npm 官方下载统计，@contentful/optimization-nextjs 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,512 次，日均约 84 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @contentful/optimization-nextjs 还在维护吗？

最新版本 2\.1\.3 发布于 2026/11/06（4 天前）；至今共发布 16 个版本，其中过去 12 个月发布了 16 个；首次发布于 2026/06/25。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

