React Custom Tool
In this example, we will create a custom tool with React and a custom property editor with React.
Each custom tool is built in its own custom.js file which is then passed to unlayer.init
. In this case, we'll need our custom.js file to use React.
1. Importing React
The first step to create a custom tool using React is to make sure we can access React in our bundle.
We recommend reusing Unlayer's React for better performance and avoiding version conflicts. We have the following libraries available globally:
unlayer.React
unlayer.ReactDOM
If you still need a different version of React, you can bundle it with your custom.js code.
You can access Unlayer's React by calling window.unlayer.React
.
2. Webpack Configuration
If you are using a bundler like webpack
to bundle your custom.js file, then you can add this to your webpack.config.js
file:
externals: {
'react': 'window.unlayer.React',
'react-dom': 'window.unlayer.ReactDOM'
}
Once this is added, you can import React in your custom.js file just like you would do it normally.
import React, { Component } from 'react';
3. Register your Tool
We'll need to create a custom.js file that includes the JavaScript to create our custom tool. Inside your custom tool script, you can use JSX for the viewer and exporter components.
If you want to import other components into the custom tool code, you can add JSX to the Unlayer’s viewer component.
For exporters, make sure to convert JSX to string using ReactDOMServer.renderToStaticMarkup(). Here is the code example for the same:
custom.js
import * as ReactDOMServer from 'react-dom/server';
const React = window.unlayer.React;
const Viewer = () => {
return <div>I am a custom tool.</div>;
};
unlayer.registerTool({
name: 'my_tool',
label: 'My Tool',
icon: 'fa-smile',
supportedDisplayModes: ['web', 'email'],
options: {},
values: {},
renderer: {
Viewer: Viewer, // this is your React component
exporters: {
web: function (values) {
return ReactDOMServer.renderToStaticMarkup(<Viewer />);
},
email: function (values) {
return ReactDOMServer.renderToStaticMarkup(<Viewer />);
},
},
head: {
css: function (values) {},
js: function (values) {},
},
},
});
4. Bundle Your Custom Tool
Use a module bundler like Webpack or Vite to bundle your custom tool code into a standalone JavaScript file. Organize your tool code in a dedicated directory for maintainability.
5. Host the Custom Tool
After bundling, upload the output JavaScript file to a publicly accessible URL (e.g., https://yourdomain.com/custom-tool.js
).
6. Add customJS
to Builder Configuration
Use the customJS
option inside the options
property of the EmailEditor
component to load your custom tool at runtime.
Preview
Here's a live running preview of our custom tool. Drag and drop the custom tool with a smiley face :)
React Tool with Custom Property Editor
Let's update our React custom tool to use a React custom property editor now. In this example, we will create a custom color picker.
You can also use our built-in property editors to save time, check out the full list of available built-in property editors.
1. Register your Tool
custom.js
import * as ReactDOMServer from 'react-dom/server';
const React = window.unlayer.React;
// Custom Color Picker
const MyColorPicker = (props) => {
const { label, value, updateValue, data } = props;
return (
<div>
<div>My React Color Picker</div>
<input
className="color-value"
defaultValue={value}
onChange={(e) => updateValue(e.target.value)}
/>
<button className="red" onClick={() => updateValue('#f00')}>
Red
</button>
<button className="green" onClick={() => updateValue('#0f0')}>
Green
</button>
<button className="blue" onClick={() => updateValue('#00f')}>
Blue
</button>
</div>
);
};
unlayer.registerPropertyEditor({
name: 'my_color_picker',
Widget: MyColorPicker,
});
// Custom Tool Viewer
const Viewer = ({ values }) => {
return <div style={{ color: values.textColor }}>I am a custom tool.</div>;
};
unlayer.registerTool({
name: 'my_tool',
label: 'My Tool',
icon: 'fa-smile',
supportedDisplayModes: ['web', 'email'],
options: {
default: {
title: null,
},
text: {
title: 'Text',
position: 1,
options: {
textColor: {
label: 'Color',
defaultValue: '#ff0000',
widget: 'my_color_picker',
},
},
},
},
values: {},
renderer: {
Viewer: Viewer,
exporters: {
web: function (values) {
return ReactDOMServer.renderToStaticMarkup(<Viewer values={values} />);
},
email: function (values) {
return ReactDOMServer.renderToStaticMarkup(<Viewer values={values} />);
},
},
head: {
css: function (values) {},
js: function (values) {},
},
},
});
2. Bundle Your Custom Tool
Use a module bundler like Webpack or Vite to bundle your custom tool code into a standalone JavaScript file. Organize your tool code in a dedicated directory for maintainability.
3. Host the Custom Tool
After bundling, upload the output JavaScript file to a publicly accessible URL (e.g., https://yourdomain.com/custom-tool.js
).
4. Add customJS
to Builder Configuration
Use the customJS
option in the EmailEditor
component to load your custom tool at runtime.
Preview
Here's a live running preview of our custom tool with built-in editor. Drag and drop the custom tool with a smiley face, and then select it on the canvas to play with the color picker.