BlockNote Docs特性导出邮件导出

邮件导出

可以将 BlockNote 文档导出为兼容邮件的 HTML,且完全在客户端完成。

此功能由 @blocknote/xl-email-exporter 提供。xl- 系列包 是完全开源的,但采用了 copyleft 许可证。商业许可证 用于闭源专有产品,包含在 商业订阅 中。

首先,安装 @blocknote/xl-email-exporter 包:

npm install @blocknote/xl-email-exporter

然后,创建 ReactEmailExporter 类的实例。它提供以下方法:

import {
  ReactEmailExporter,
  reactEmailDefaultSchemaMappings,
} from "@blocknote/xl-email-exporter";

// 创建导出器
const exporter = new ReactEmailExporter(
  editor.schema,
  reactEmailDefaultSchemaMappings,
);

// 将区块转换为 react-email 文档
const html = await exporter.toReactEmailDocument(editor.document);

// 使用 react-email 写入文件:
await ReactEmail.render(html, `filename.html`);

请参见下面的完整示例

自定义邮件输出

toReactEmailDocument 接受一个可选的 options 参数,允许你自定义:

  • preview:设置邮件预览文本(可以是字符串或字符串数组)
  • header:在邮件顶部添加内容(必须是 React-Email 兼容组件)
  • footer:在邮件底部添加内容(必须是 React-Email 兼容组件)
  • head:向 Head 组件 注入元素
  • container:自定义容器组件(将包裹邮件内容,包括头部和底部)
  • bodyStyles:自定义正文样式(一个 CSSProperties 对象),提供此对象会完全覆盖默认样式

示例用法:

import React from "react";
import {
  ReactEmailExporter,
  reactEmailDefaultSchemaMappings,
} from "@blocknote/xl-email-exporter";
import { BlockNoteEditor } from "@blocknote/core";
import { Text, Container } from "@react-email/components";

const editor = BlockNoteEditor.create();

// ---cut---
const exporter = new ReactEmailExporter(
  editor.schema,
  reactEmailDefaultSchemaMappings,
);

const html = await exporter.toReactEmailDocument(editor.document, {
  preview: "这是邮件内容的预览文本",
  header: <Text>头部</Text>,
  footer: <Text>底部</Text>,
  head: <title>我的邮件</title>,
  container: ({ children }) => <Container>{children}</Container>,
  // 以下是默认设置的正文样式
  bodyStyles: {
    fontFamily:
      "'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif",
    fontSize: "16px",
    lineHeight: "1.5",
    color: "#333",
  },
});

自定义映射 / 自定义 Schema

ReactEmailExporter 构造函数接受 schemamappings 参数。 映射定义了如何将 BlockNote 的 schema 元素(区块、内联内容或样式)转换为 React-Email 元素。 如果你在编辑器中使用了自定义 schema,或者想覆盖默认 BlockNote 元素转换为 React Email 的行为,可以传入你自己的 mappings

例如,当你的 schema 有一个 extraBlock 类型时:

import { ReactEmailExporter, reactEmailDefaultSchemaMappings } from "@blocknote/xl-email-exporter";
import { Text } from "@react-email/components";

new ReactEmailExporter(schema, {
    blockMapping: {
        ...reactEmailDefaultSchemaMappings.blockMapping,
        myCustomBlock: (block, exporter) => {
            return <Text>我的自定义区块</Text>;
        },
    },
    inlineContentMapping: reactEmailDefaultSchemaMappings.inlineContentMapping,
    styleMapping: reactEmailDefaultSchemaMappings.styleMapping,
});

导出器选项

ReactEmailExporter 构造函数还接受一个可选的 options 参数。 虽然转换过程在客户端完成,默认配置使用了服务器托管的代理来解决文件解析:

const defaultOptions = {
  // 一个用于解析外部资源的函数,避免 CORS 问题
  // 默认为调用 BlockNote 托管的服务器端代理进行文件解析
  resolveFileUrl: corsProxyResolveFileUrl,
  // 邮件中用于高亮、背景和字体颜色等的颜色配置。
  colors: COLORS_DEFAULT, // @blocknote/core 中的默认颜色
};

自定义样式

想调整邮件的默认样式?你可以使用 reactEmailDefaultSchemaMappingsWithStyles 来创建带有自定义样式的映射。

import {
  ReactEmailExporter,
  reactEmailDefaultSchemaMappingsWithStyles,
} from "@blocknote/xl-email-exporter";
import { Text } from "@react-email/components";

const { blockMapping, inlineContentMapping, styleMapping } =
  reactEmailDefaultSchemaMappingsWithStyles({
    textStyles: {
      paragraph: {
        style: {
          fontSize: 16,
          lineHeight: 1.5,
          margin: 3,
          minHeight: 24,
        },
      },
    },
  });

new ReactEmailExporter(schema, {
  // 你依然可以使用默认区块映射,也可以覆盖它
  blockMapping: {
    ...blockMapping,
    audio: (block, exporter) => {
      return <Text>音频区块</Text>;
    },
  },
  inlineContentMapping,
  styleMapping,
});