Creating a custom node
Custom extensions useEmailNode, which extends TipTap’s Node with one extra required
method: renderToVueEmail(). Use parseHTML() to recognize pasted or imported HTML,
renderHTML() to control how the node appears in the editor, and renderToVueEmail() to
control how it is exported by composeVueEmail.
renderToVueEmail() is a plain function that returns VNodes, built with h() from Vue. It
receives the node’s content already rendered as children, which plain elements take as their
children ([children]).
Here’s a complete example of a custom “Callout” node that renders as a highlighted block:
callout.ts
Numbers in the styles of plain elements, like the
div above, don’t get a px unit added, so
write sizes as strings with their units. Vuemail components, like Section or Text, add px
to numbers like React Email does. Pass the children of a Vuemail component as its default slot:
h(Section, { style }, () => children).Registering the extension
Add your custom extension to the extensions array alongsideStarterKit:
Inserting custom nodes
Use the editor’sinsertContent command to programmatically insert your custom node:
toolbar.vue
Complete example
Here’s the full editor setup with the custom Callout extension, a toolbar, and a bubble menu:toolbar.vue
my-editor.vue
Wrapping existing TipTap extensions
BothEmailNode and EmailMark provide a .from() method that wraps an existing TipTap
extension with email serialization support. This is useful when you want to reuse a community
TipTap extension and add email export support without rewriting it.
Configure and extend
BothEmailNode and EmailMark support TipTap’s standard customization methods:
Examples
See custom extensions in action with a runnable example:Custom Extensions
Custom Callout node with EmailNode.create, toolbar insertion, and bubble menu.