@joai/sdk

中文文档
14.0.2发布于 2026/11/01MITTypeScriptES Module

JoAi public API SDK — build with your AI agents

原始使用文档
文档目录3 节
  1. Managed content editor
  2. Session storage
  3. Editing behavior

@joai/sdk

The React entry point contains reusable building blocks for editable content on client websites. The components stay domain-neutral: sites provide identifiers, copy, styling hooks, and rendered fields; the SDK owns session handoff and the editing lifecycle.

Managed content editor

import { ManagedContentEditor } from '@joai/react'

<ManagedContentEditor
  config={{
    contentId: 'content-id',
    publicSlug: 'website-content',
    sessionStorageKey: 'website-content-session',
    team: 'team-slug',
  }}
  initialContent={content}
  title="Inhalte bearbeiten"
  labels={{
    edit: 'Bearbeiten',
    save: 'Entwurf speichern',
    saving: 'Wird gespeichert …',
    publish: 'Veröffentlichen',
    publishing: 'Wird veröffentlicht …',
    cancel: 'Abbrechen',
    toolbar: 'Inhaltseditor',
    unsaved: 'Nicht gespeicherte Änderungen',
  }}
  messages={{
    conflict: 'Der Inhalt wurde zwischenzeitlich geändert. Deine Eingaben bleiben erhalten. Bitte prüfe sie und versuche es erneut.',
    loadError: 'Der Inhalt konnte nicht geladen werden.',
    publishError: 'Die Änderungen konnten nicht veröffentlicht werden.',
    published: 'Die Änderungen wurden veröffentlicht.',
    saveError: 'Der Entwurf konnte nicht gespeichert werden.',
    saved: 'Der Entwurf wurde gespeichert.',
    sessionExpired: 'Deine Sitzung ist abgelaufen.',
    unsavedNavigation: 'Du hast nicht gespeicherte Änderungen. Seite wirklich verlassen?',
  }}
  imagePickerLabels={{
    applyCrop: 'Zuschnitt übernehmen',
    back: 'Zurück',
    choose: 'Bild auswählen',
    close: 'Schließen',
    cropDescription: 'Passe Bildausschnitt und Zoom vor dem Hochladen an.',
    cropTitle: 'Bild zuschneiden',
    dimensionsTooLarge: 'Die Bildabmessungen sind zu groß.',
    dimensionsTooSmall: 'Die Bildabmessungen sind zu klein.',
    drop: 'Bild hier ablegen',
    empty: 'Noch keine Bilder vorhanden.',
    field: 'Bearbeitbares Bild',
    invalidType: 'Bitte wähle eine Bilddatei.',
    libraryDescription: 'Wähle ein vorhandenes Bild oder lade ein neues hoch.',
    libraryTitle: 'Bildmediathek',
    loadError: 'Bilder konnten nicht geladen werden.',
    loading: 'Bilder werden geladen …',
    positionHorizontal: 'Horizontale Position',
    positionVertical: 'Vertikale Position',
    processing: 'Bild wird vorbereitet …',
    retry: 'Erneut versuchen',
    tooLarge: 'Das Bild ist zu groß.',
    upload: 'Bild hochladen',
    uploadError: 'Das Bild konnte nicht hochgeladen werden.',
    uploading: 'Wird hochgeladen …',
    zoom: 'Zoom',
  }}
  reauthenticateLabel="Anmeldung erneuern"
  sessionExpiredMessage="Deine Sitzung ist abgelaufen. Deine lokalen Änderungen bleiben erhalten."
  confirmCancel={() => window.confirm('Nicht gespeicherte Änderungen verwerfen?')}
  confirmLeave={() => window.confirm('Du hast nicht gespeicherte Änderungen. Seite wirklich verlassen?')}
  confirmPublish={() => window.confirm('Änderungen jetzt veröffentlichen?')}
>
  {children}
</ManagedContentEditor>

Use EditableContent, EditableImage, and useContentValue from @joai/react inside the editor. Pass server-fetched public content as initialContent to avoid a client-side loading state for visitors.

Configure each image field as a reusable, domain-neutral building block. Images are compressed to WebP at up to 2560 × 2560 pixels by default, while animated GIF and SVG files retain their original format. Cropping is opt-in per field:

<EditableImage
  field="heroImage"
  label="Titelbild"
  maxSourceBytes={40 * 1024 * 1024}
  maxUploadBytes={5 * 1024 * 1024}
  processing={{
    crop: { aspectRatio: 16 / 9, outputWidth: 1920 },
    compression: { maxWidth: 1920, maxHeight: 1080, mimeType: 'image/webp', quality: 0.84 },
    dimensions: { minWidth: 1280, minHeight: 720, maxPixels: 50_000_000 },
  }}
/>

Set compression: false or dimensions: false to disable only that stage, or processing={false} to upload the original image without client-side decoding, validation, cropping, or compression.

Session storage

useContentSession and createSessionTokenStore are exported for custom shells. A custom SessionTokenStore can be injected when a host needs a different persistence mechanism. The URL fragment containing the one-time handoff token is removed before it is exchanged and persisted.

The managed editor automatically adds platform=app to its reauthentication return URL so JoAi returns a one-time handoff token. Override reauthenticateUrl only when a host has a dedicated login callback.

createContentDraftStore uses sessionStorage by default. ManagedContentEditor wires it automatically so unsaved values survive refreshes and expired-session reauthentication without being shared across browser sessions.

Editing behavior

  • Cancel restores the currently loaded version.
  • Save is disabled when there are no local changes.
  • A dirty publish saves and publishes with one request.
  • Network failures keep local edits available for retry.
  • Refresh, close, and link/navigation attempts warn while edits are unsaved.
  • Editable text and image fields are visibly labelled in edit mode.
  • The image library supports loading, empty, error, byte/dimension validation, cropping, compression, keyboard, focus, and drag-and-drop states.
  • Expired authorization offers a sign-in action and restores locally persisted edits afterwards.
  • Version conflicts load the latest version while preserving local edits.
  • Public content cache entries are invalidated after authenticated mutations.

版本与发布记录

@joai/sdk 共发布 84 个版本,首次发布于 2026/03/26;过去 12 个月发布了 84 个版本。

版本发布日期距今
14.0.2latest2026/11/011 天前
14.0.12026/11/012 天前
14.0.02026/10/312 天前
13.1.32026/10/313 天前
13.1.22026/10/313 天前
13.1.12026/10/304 天前

关于 @joai/sdk 的常见问题

@joai/sdk 是什么?

JoAi公共API SDK -构建与您的AI代理

如何安装 @joai/sdk?

在项目目录运行 npm install @joai/sdk,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@joai/core(^5.4.7)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@joai/sdk 支持 TypeScript 吗?

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

@joai/sdk 支持 ESM 还是 CommonJS?

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

@joai/sdk 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@joai/sdk 可以商用吗?

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

@joai/sdk 还在维护吗?

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