@contensis/canvas-react

中文文档
1.3.2发布于 2026/02/13ISCTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 6496

Render canvas content with React

原始使用文档

@contensis/canvas-react

Render content curated in a Contensis canvas field in your React projects.

Installation

Install with your project's preferred package manager

npm install --save @contensis/canvas-react
yarn add --save @contensis/canvas-react

Usage

Render canvas content with React

import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import { RenderContextProvider, Renderer } from '@contensis/canvas-react';
import * as CanvasData from './canvas-data';

// Our React App
const App = () => {
  const [data] = useState(CanvasData.data); // Demo data

  return (
    <div className="content">
      <RenderContextProvider>
        <Renderer data={data} />
      </RenderContextProvider>
    </div>
  );
};

const element = document.getElementById('root') as HTMLElement;
ReactDOM.createRoot(element).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

You can override the default rendering for content blocks by adding your own render components when creating the canvas renderer

import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import { Block, Image, ImageBlock, RenderBlockProps, RenderContextProvider, Renderer, Table, TableBlock } from '@contensis/canvas-react';
import * as CanvasData from './canvas-data';

const MyImage = (props: RenderBlockProps<ImageBlock>) => {
    // Embelish the image markup if a caption is included
    const caption = props.block?.value?.caption;
    // Set a className for the image in all cases
    return !!caption ? (
        <figure className="figure" style={{ display: 'block' }}>
            <Image {...props} className="figure-img img-fluid" />
            <figcaption className="figure-caption text-end">{caption}</figcaption>
        </figure>
    ) : (
        <Image {...props} className="img-fluid" />
    );
};

const MyTable = (props: RenderBlockProps<TableBlock>) => {
    // Set CSS className on tables
    return <Table {...props} className="table table-striped" />;
};

// Component wrapping a Renderer for simple usage
const SimpleRenderer = ({ data }: { data: Block[] }) => {
    return (
        <RenderContextProvider
            blocks={{
                _image: MyImage,
                _table: MyTable
            }}
        >
            <Renderer data={data} />
        </RenderContextProvider>
    );
};

// Our React App
const App = () => {
    const [data] = useState(CanvasData.data); // Demo data

    return (
        <div className="content">
            <SimpleRenderer data={data} />
        </div>
    );
};

const element = document.getElementById('root') as HTMLElement;
ReactDOM.createRoot(element).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

We can do the same for any Component fields present in the Canvas data

import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import { Block, Image, RenderContextProvider, Renderer, Table } from '@contensis/canvas-react';
import * as CanvasData from './canvas-data';

type Book = { cover: string; name: string };

// Render a "book" component within the canvas data
const MyBookComponent = (props: RenderBlockProps<ComponentBlock<Book>) => {
  const book = props.block?.value;
  if (!book) return null;
  return (
    <div className="card mb-3">
      <div className="row g-0">
        <div className="col-md-8">
          <div className="card-body">
            <h5 className="card-title">{book.name}</h5>
            <p className="card-text">{book.name}</p>
          </div>
        </div>
        <div className="col-md-4">
          <img src={book.cover} className="img-fluid rounded-start" />
        </div>
      </div>
    </div>
  );
}

// Component wrapping a customised Renderer for use in our app
const SimpleRenderer = ({ data }: { data: Block[] }) => {
    return (
        <RenderContextProvider
            components={{
                book: MyBookComponent,
            }}
        >
            <Renderer data={data} />
        </RenderContextProvider>
    );
};

// Our React App
const App = () => {
    const [data] = useState(CanvasData.data); // Demo data

    return (
        <div className="content">
            <SimpleRenderer data={data} />
        </div>
    );
};

const element = document.getElementById('root') as HTMLElement;
ReactDOM.createRoot(element).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

You try this out with the React example project

版本与发布记录

@contensis/canvas-react 共发布 11 个版本,首次发布于 2023/12/02;过去 12 个月发布了 1 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.3.2latest2026/02/138 个月前
1.3.02025/09/091.2 年前
1.2.02024/09/262 年前
1.1.02024/07/052 年前
1.0.62024/05/282 年前
1.0.52024/05/022 年前

关于 @contensis/canvas-react 的常见问题

@contensis/canvas-react 是什么?

Render canvas content with React

如何安装 @contensis/canvas-react?

在项目目录运行 npm install @contensis/canvas-react,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>16.8.0)、react-dom(>16.8.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@contensis/canvas-react 支持 TypeScript 吗?

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

@contensis/canvas-react 支持 ESM 还是 CommonJS?

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

@contensis/canvas-react 可以商用吗?

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

@contensis/canvas-react 的下载量有多少?

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

@contensis/canvas-react 还在维护吗?

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