Setup & Usage Guide
Quick start
1. Add your editor element
<div class="my-editor">
<p>Start typing here…</p>
</div>
2. Add the loader script
Place this script tag anywhere on the page (before or after the element):
<script
src="https://cdn.readyeditor.io/releases/<version>/js/readyeditor.loader.min.js"
data-api-key="YOUR_API_KEY"
data-selector=".my-editor"
data-load-css="1"
data-plugins="auto"
data-require-sri="1"
></script>
Replace <version> with the release pinned to your project (visible in the dashboard) and YOUR_API_KEY with your project API key.
The loader calls /api/v1/editor/init, loads the correct assets, and calls ReadyEditor.init() automatically. No additional JavaScript is required.
Textarea integration
The textarea bridge is a separate script (readyeditor.textarea.bridge.min.js) that is not auto-loaded by the loader. You must include it explicitly. It hides the original <textarea>, inserts an editor <div> in its place, and syncs content back on form submit.
<form>
<textarea name="content" class="js-my-editor">
<p>Initial content</p>
</textarea>
<button type="submit">Save</button>
</form>
<!-- 1. Loader — with data-auto-init="0" so we control timing -->
<script
src="https://cdn.readyeditor.io/releases/<version>/js/readyeditor.loader.min.js"
data-api-key="YOUR_API_KEY"
data-load-css="1"
data-plugins="auto"
data-auto-init="0"
></script>
<!-- 2. Textarea bridge — must be loaded before calling attachTextareas() -->
<script src="https://cdn.readyeditor.io/releases/<version>/js/readyeditor.textarea.bridge.min.js"></script>
<!-- 3. Initialize once loader resolves, then attach to textareas -->
<script>
window.ReadyEditorLoader.init({
apiKey: 'YOUR_API_KEY',
loadCss: true,
plugins: 'auto',
}).then(function() {
ReadyEditor.attachTextareas({
selector: 'textarea.js-my-editor',
editorOptions: { apiKey: 'YOUR_API_KEY' }
});
});
</script>
Note:
data-selectoris omitted from the loader tag here because the bridge creates its own<div>elements and passes the selector toReadyEditor.init()internally. The bridge keeps the<textarea>value in sync with editor content so standard form submissions work without any extra code.
Configuration options
Loader tag attributes
| Attribute | Default | Description |
|---|---|---|
data-api-key |
— | Your project API key (required) |
data-selector |
.ready-editor |
CSS selector for editor elements |
data-load-css |
1 |
Load editor CSS automatically (0 to disable) |
data-plugins |
auto |
auto (all entitled), none, or comma-separated list |
data-disable-plugins |
— | Comma-separated list of plugins to suppress |
data-toolbar-preset |
full |
full, basic, or minimal |
data-toolbar-groups |
— | CSV allowlist of toolbar groups |
data-toolbar-hide-groups |
— | CSV blocklist of toolbar groups |
data-toolbar-overflow-groups |
— | CSV list of groups always pinned into the "More" dropdown |
data-toolbar-overflow |
on |
Set to off to disable the overflow mechanism (toolbar wraps instead) |
data-require-sri |
1 |
Enforce SRI integrity on loaded assets |
data-auto-init |
1 |
Set to 0 to skip automatic initialization |
data-init-endpoint |
/api/v1/editor/init |
Override the init endpoint URL |
JS API (when data-auto-init="0")
window.ReadyEditorLoader.init({
apiKey: 'YOUR_API_KEY',
initEndpoint: '/api/v1/editor/init',
selector: '.my-editor',
plugins: 'auto',
loadCss: true,
requireSri: true,
});
Strict CSP (no secrets in HTML attributes)
If your CSP forbids putting secrets in HTML attributes, load the loader with data-auto-init="0" and call the JS API from your own bundle:
<script
src="https://cdn.readyeditor.io/releases/<version>/js/readyeditor.loader.min.js"
integrity="sha256-..."
crossorigin="anonymous"
data-auto-init="0"
></script>
<script src="/assets/readyeditor-init.js" defer></script>
// /assets/readyeditor-init.js
window.ReadyEditorLoader.init({
apiKey: window.__READYEDITOR_API_KEY__, // injected server-side
selector: '.my-editor',
loadCss: true,
requireSri: true,
});
Reading and writing content
// Get HTML content
var instance = ReadyEditor.getInstance('.my-editor');
var html = instance.getContent();
// Set HTML content
instance.setContent('<p>Hello, World!</p>');
Multiple editors on one page
Pass a selector that matches multiple elements:
<div class="my-editor" id="editor-body">…</div>
<div class="my-editor" id="editor-notes">…</div>
ReadyEditor.init({
selector: '.my-editor',
apiKey: 'YOUR_API_KEY',
onChange: function(instance) {
console.log('Changed:', instance.element.id, instance.getContent());
}
});
onChange callback
ReadyEditor.init({
selector: '.my-editor',
apiKey: 'YOUR_API_KEY',
onChange: function(instance) {
// Debounced auto-save
clearTimeout(instance._saveTimer);
instance._saveTimer = setTimeout(function() {
saveToServer(instance.getContent());
}, 500);
}
});
Styling the editor
The loader applies these CSS classes you can target:
.readyeditor-container { border: 1px solid #ddd; border-radius: 4px; }
.readyeditor-toolbar { background: #f8f9fa; padding: 6px; }
.readyeditor-root { padding: 12px; min-height: 200px; }
.readyeditor-btn.readyeditor-btn-active { background: #0d6efd; color: #fff; }
Browser compatibility
ReadyEditor requires:
contentEditable(all modern browsers)document.execCommand()(supported in all current browsers, though deprecated in the spec)fetch(all modern browsers; polyfillable)- ES5+ JavaScript
Tested in Chrome, Firefox, Safari, and Edge.