@ebitex/content-sdk

中文文档
1.1.292发布于 2026/11/10Apache-2.0TypeScriptES Module零依赖近 30 天下载 4085

The client for the ebitex Content Delivery API: typed endpoints, React rendering, sitemaps, live preview and locale addressing, so a site does not maintain its own.

原始使用文档
文档目录5 节
  1. Why use this instead of calling the API yourself
  2. Install
  3. Quick start
  4. Media from the asset library
  5. Know the visitor's audiences

@ebitex/content-sdk

Consume published ebitex Content from your own site: a typed client for the Content Delivery API and React utilities that render a delivered page by dispatching each Presentation to a component you provide.

Two entry points:

  • @ebitex/content-sdk — the clients. createDeliveryClient is one method per endpoint; createContentClient adds site/locale/context resolution, a resolve strategy, caching and cancellation, and resolveLocation(location) to call on every router change. No React.
  • @ebitex/content-sdk/react — <ContentProvider>, <Experience>, <RenderPresentation>, <PresentationList>, <RichText>, <Resolve>, and a guiding fallback for every Presentation that cannot be rendered. React is a peer dependency, never bundled.

Why use this instead of calling the API yourself

A site that writes its own fetch code against the Delivery API owns everything below, and none of it shows until something breaks. This package is the maintained version of all of it:

  • Every endpoint, typed, kept in step with the API: path resolution, components, streams and facets, media and response parsing.
  • Sitemaps. buildSitemapDocuments (@ebitex/content-sdk/sitemap) shards at the protocol limits, writes the index and emits hreflang alternates, so you do not join URLs by hand.
  • Live preview and click-to-edit. @ebitex/content-sdk/preview is the receiver, overlay and pins. It needs the annotated responses of a preview session, which a client that parses only the fields it renders throws away.
  • Locale addressing. Addresses arrive already carrying their language under the path-prefix and locale-host strategies. A client that adds its own prefix doubles it.
  • Caching and references. A cache with the right keys, and resolve handling so a delivered Presentation is never a hollow reference.

Moving a hand-written client over can be done a step at a time, keeping your own renderers: see Replace a hand-written client. For .NET, use Ebitex.Content.Delivery.

A browser-safe delivery key (one with an allowed-origins or allowed-IP-ranges restriction) may ship in a bundle. A key with neither restriction is a server-side key and must never reach a browser. Create either in Content → Delivery.

Install

npm install @ebitex/content-sdk

Quick start

import { createContentClient } from '@ebitex/content-sdk'
import { ContentProvider, Experience, renderersFromGlob } from '@ebitex/content-sdk/react'

const content = createContentClient({ apiKey: import.meta.env.VITE_CONTENT_DELIVERY_KEY })
const renderers = renderersFromGlob(import.meta.glob('./presentations/*.tsx'))

export function App() {
  const location = useLocation()
  const navigate = useNavigate()
  return (
    <ContentProvider client={content} renderers={renderers} markdown={Markdown}>
      <Experience path={location.pathname} onRedirect={(to) => navigate(to, { replace: true })} />
    </ContentProvider>
  )
}
// presentations/hero.tsx — one file per Template, named by its externalId, default export
import type { PresentationRenderer } from '@ebitex/content-sdk/react'

const Hero: PresentationRenderer<{ headline: string }, { theme: string }> = ({ settings, component }) => (
  <section data-theme={settings.theme}>
    <h1>{component.content.headline}</h1>
  </section>
)
export default Hero

A Template with no renderer, an unpublished reference, a binding that needs server-side resolution — each renders a panel naming the reason and the fix, so a missing piece is visible, never silent.

Media from the asset library

An image, video or document picked from your asset library arrives as an expanded reference. A field may allow several kinds, and they all share one shape. isAssetValue recognizes the reference (by its Contract's externalId: ebitex-image, ebitex-video or ebitex-document), and the content's own kind then narrows what file holds:

import { isAssetValue } from '@ebitex/content-sdk'

function Media({ value }: { value: unknown }) {
  if (!isAssetValue(value)) return null
  const { content } = value
  switch (content.kind) {
    case 'image':
      return <img src={content.file.url} width={content.file.width} height={content.file.height} alt={content.alt ?? content.name} />
    case 'video':
      // `file.url` is an HLS manifest: hand it to a player that plays HLS.
      return content.file.posterUrl ? <img src={content.file.posterUrl} alt={content.name} /> : null
    case 'document':
      return <a href={content.file.url}>{content.name}</a>
  }
}

file is already resolved to one locale: the rendition for the locale you asked for, falling back along your locale tree to the default. A private asset's URL is signed and expires, so render it and let it go rather than storing it.

Full guide and reference: developers.ebitex.io.

Worked examples: the ebitex samples repository has two complete Northwind Coffee sites built on this package, one static and one server-rendered, each with the content model it expects.

Know the visitor's audiences

Personalized and restricted content depends on which audiences a visitor is in. Give the client an audience option and it does the whole flow: it asks which audiences your content uses, asks Audience which of them the visitor is in, keeps the signed answer in memory, renews it, and sends it with every read.

import { createContentClient } from '@ebitex/content-sdk'

const content = createContentClient({
  apiKey: import.meta.env.VITE_DELIVERY_KEY,
  audience: { apiKey: import.meta.env.VITE_AUDIENCE_DELIVERY_KEY },
})

A Forms submission, a sign-in link followed in another tab, the tab coming back after a pause and a stale token each refresh the answer by themselves, and <Experience> re-reads when it changes. useAudienceChange() re-renders your own component when the visitor's audiences change, and useSignIn() runs the emailed-link sign-in. On a server, make one client per request with content.forVisitor({ visitor, consent }). Audiences are never sent in the context; Content refuses them there.

An Audience delivery key is its own kind (a Content delivery key does not work). One with an allowed-origins list is browser-safe and the list is checked on every request. visitor and consent are optional: without them, or without consent granted on that device, the context alone decides. It never throws into a page: when Audience cannot answer, the visitor holds no audiences and onError hears about it.

版本与发布记录

@ebitex/content-sdk 共发布 65 个版本,首次发布于 2026/08/29;过去 12 个月发布了 65 个版本。

版本发布日期距今
1.1.292latest2026/11/103 天前
1.1.2822026/11/049 天前
1.1.2742026/10/3014 天前
1.1.2722026/10/3014 天前
1.1.2692026/10/2915 天前
1.1.2682026/10/2915 天前

关于 @ebitex/content-sdk 的常见问题

@ebitex/content-sdk 是什么?

The client for the ebitex Content Delivery API: typed endpoints, React rendering, sitemaps, live preview and locale addressing, so a site does not maintain its own.

如何安装 @ebitex/content-sdk?

在项目目录运行 npm install @ebitex/content-sdk,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 content-sdk-apply、content-sdk-codegen,可以用 npx content-sdk-apply 直接运行。

@ebitex/content-sdk 支持 TypeScript 吗?

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

@ebitex/content-sdk 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@ebitex/content-sdk 可以商用吗?

@ebitex/content-sdk 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@ebitex/content-sdk 的下载量有多少?

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

@ebitex/content-sdk 还在维护吗?

最新版本 1.1.292 发布于 2026/11/10(3 天前);至今共发布 65 个版本,其中过去 12 个月发布了 65 个;首次发布于 2026/08/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。