It's possible to export BlockNote documents to email, completely client-side.
This feature is provided by the @blocknote/xl-email-exporter
. xl-
packages
are fully open source, but released under a copyleft license. A commercial
license for usage in closed source, proprietary products comes as part of the
Business subscription.
First, install the @blocknote/xl-email-exporter
packages:
npm install @blocknote/xl-email-exporter
Then, create an instance of the ReactEmailExporter
class. This exposes the following methods:
import {
ReactEmailExporter,
reactEmailDefaultSchemaMappings,
} from "@blocknote/xl-email-exporter";
// Create the exporter
const exporter = new ReactEmailExporter(
editor.schema,
reactEmailDefaultSchemaMappings,
);
// Convert the blocks to a react-email document
const html = await exporter.toReactEmailDocument(editor.document);
// Use react-email to write to file:
await ReactEmail.render(html, `filename.html`);
See the full example below:
Customizing the Email output
toReactEmailDocument
takes an optional options
parameter, which allows you to customize:
- preview: Set the preview text for the email (can be a string or an array of strings)
- header: Add content to the top of the email (must be a React-Email compatible component)
- footer: Add content to the bottom of the email (must be a React-Email compatible component)
- head: Inject elements into the Head element
Example usage:
import { Text } from "@react-email/components";
const html = await exporter.toReactEmailDocument(editor.document, {
preview: "This is a preview of the email content",
header: <Text>Header</Text>,
footer: <Text>Footer</Text>,
head: <title>My email</title>,
});
Custom mappings / custom schemas
The ReactEmailExporter
constructor takes a schema
and mappings
parameter.
A mapping defines how to convert a BlockNote schema element (a Block, Inline Content, or Style) to a React-Email element.
If you're using a custom schema in your editor, or if you want to overwrite how default BlockNote elements are converted to React Email, you can pass your own mappings
:
For example, use the following code in case your schema has an extraBlock
type:
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>My custom block</Text>;
},
},
inlineContentMapping: reactEmailDefaultSchemaMappings.inlineContentMapping,
styleMapping: reactEmailDefaultSchemaMappings.styleMapping,
});
Exporter options
The ReactEmailExporter
constructor takes an optional options
parameter.
While conversion happens on the client-side, the default setup uses a server hosted proxy to resolve files:
const defaultOptions = {
// a function to resolve external resources in order to avoid CORS issues
// by default, this calls a BlockNote hosted server-side proxy to resolve files
resolveFileUrl: corsProxyResolveFileUrl,
// the colors to use in the email for things like highlighting, background colors and font colors.
colors: COLORS_DEFAULT, // defaults from @blocknote/core
};