Framework Guides
CyteEditor provides dedicated adapter packages for popular frameworks. This guide covers the complete integration steps for each framework, from installation to a working editor.
Quick start (Vue 3 only): If you use Vue 3 and want everything in one package, install
cyte-editorinstead. It bundles the core engine, Vue 3 adapter, License SDK, and all Pro plugins. For other frameworks or fine-grained control, follow the modular setup below.
Vue 3
The official Vue 3 adapter with Composition API support and v-model:html two-way binding.
Requirements: Vue ^3.3.0
Installation
npm install @cyte-editor/core @cyte-editor/vue3
Import Styles
Import both the core styles and the adapter styles in your entry file:
import '@cyte-editor/core/style.css'
import '@cyte-editor/vue3/style.css'
Basic Usage
<template>
<div>
<CyteEditor
v-model:html="content"
placeholder="Start writing…"
locale="en-US"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { CyteEditor } from '@cyte-editor/vue3'
import '@cyte-editor/core/style.css'
import '@cyte-editor/vue3/style.css'
const content = ref('<p>Hello, CyteEditor!</p>')
</script>
Content Binding
Vue 3 uses v-model:html for two-way binding:
<CyteEditor v-model:html="content" />
You can also use the explicit form:
<CyteEditor :html="content" @update:html="content = $event" />
Toolbar Customization
Configure which toolbar items to display via the toolbar prop:
<CyteEditor
v-model:html="content"
:toolbar="['bold', 'italic', 'underline', '|', 'heading', 'align']"
/>
For full control, replace the toolbar entirely using the #toolbar scoped slot:
<CyteEditor v-model:html="content">
<template #toolbar="{ manager, activeStates, disabledStates }">
<div class="my-toolbar">
<button
:class="{ active: activeStates.bold }"
:disabled="disabledStates.bold"
@click="manager?.getEditor().chain().focus().toggleBold().run()"
>Bold</button>
</div>
</template>
</CyteEditor>
You can also extend the default toolbar with the #toolbar-prepend and #toolbar-append slots.
Vue 2
The Vue 2 adapter using Options API and :html prop with @update:html event.
Requirements: Vue ^2.7.0
Installation
npm install @cyte-editor/core @cyte-editor/vue2
Import Styles
import '@cyte-editor/core/style.css'
import '@cyte-editor/vue2/style.css'
Basic Usage
<template>
<div>
<CyteEditor
:html="content"
placeholder="Start writing…"
locale="en-US"
@update:html="content = $event"
/>
</div>
</template>
<script>
import { CyteEditor } from '@cyte-editor/vue2'
import '@cyte-editor/core/style.css'
import '@cyte-editor/vue2/style.css'
export default {
components: { CyteEditor },
data() {
return {
content: '<p>Hello, CyteEditor!</p>',
}
},
}
</script>
Content Binding
Vue 2 does not support v-model:html. Use the :html prop with the @update:html event:
<CyteEditor :html="content" @update:html="content = $event" />
Toolbar Customization
Configure which toolbar items to display via the toolbar prop:
<CyteEditor
:html="content"
:toolbar="['bold', 'italic', 'underline', '|', 'heading', 'align']"
@update:html="content = $event"
/>
For full control, replace the toolbar using the toolbar scoped slot:
<CyteEditor :html="content" @update:html="content = $event">
<template slot="toolbar" slot-scope="{ manager, activeStates, disabledStates }">
<div class="my-toolbar">
<button
:class="{ active: activeStates.bold }"
:disabled="disabledStates.bold"
@click="manager && manager.getEditor().chain().focus().toggleBold().run()"
>Bold</button>
</div>
</template>
</CyteEditor>
React
The React adapter with hooks-based API and onChange callback.
Requirements: React ^18 || ^19
Installation
npm install @cyte-editor/core @cyte-editor/react
Import Styles
import '@cyte-editor/core/style.css'
import '@cyte-editor/react/style.css'
Basic Usage
import { useState } from 'react'
import { CyteEditor } from '@cyte-editor/react'
import '@cyte-editor/core/style.css'
import '@cyte-editor/react/style.css'
export default function MyEditor() {
const [content, setContent] = useState('<p>Hello, CyteEditor!</p>')
return (
<div>
<CyteEditor
html={content}
placeholder="Start writing…"
locale="en-US"
onChange={({ html }) => setContent(html)}
/>
</div>
)
}
Content Binding
React uses the html prop and onChange callback:
<CyteEditor
html={content}
onChange={({ html }) => setContent(html)}
/>
The onChange callback receives an object with html and json properties.
Toolbar Customization
Configure which toolbar items to display via the toolbar prop:
<CyteEditor
html={content}
toolbar={['bold', 'italic', 'underline', '|', 'heading', 'align']}
onChange={({ html }) => setContent(html)}
/>
For full control, use the toolbarRender render prop:
<CyteEditor
html={content}
onChange={({ html }) => setContent(html)}
toolbarRender={({ manager, activeStates, disabledStates }) => (
<div className="my-toolbar">
<button
className={activeStates.bold ? 'active' : ''}
disabled={disabledStates.bold}
onClick={() => manager?.getEditor().chain().focus().toggleBold().run()}
>
Bold
</button>
</div>
)}
/>
Angular
The Angular adapter with standalone component support for Angular 17+.
Requirements: Angular ^17 || ^18 || ^19
Installation
npm install @cyte-editor/core @cyte-editor/angular
Import Styles
Add the styles to your global styles or component:
/* styles.css or angular.json styles array */
@import '@cyte-editor/core/style.css';
@import '@cyte-editor/angular/style.css';
Register Components
// app.module.ts
import { NgModule } from '@angular/core'
import { CyteEditorComponent } from '@cyte-editor/angular'
@NgModule({
imports: [CyteEditorComponent],
// ...
})
export class AppModule {}
Basic Usage
<!-- app.component.html -->
<cyte-editor
[html]="content"
[placeholder]="'Start writing…'"
[locale]="'en-US'"
(onChange)="onContentChange($event)"
></cyte-editor>
// app.component.ts
import { Component } from '@angular/core'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
content = '<p>Hello, CyteEditor!</p>'
onContentChange(event: { html: string }) {
this.content = event.html
}
}
Content Binding
Angular uses property binding [html] and event binding (onChange):
<cyte-editor [html]="content" (onChange)="content = $event.html"></cyte-editor>
Toolbar Customization
Configure which toolbar items to display via the toolbar input:
<cyte-editor
[html]="content"
[toolbar]="['bold', 'italic', 'underline', '|', 'heading', 'align']"
(onChange)="content = $event.html"
></cyte-editor>
For full control, provide a custom template via toolbarTemplate:
<cyte-editor
[html]="content"
[toolbarTemplate]="myToolbar"
(onChange)="content = $event.html"
></cyte-editor>
<ng-template #myToolbar let-props>
<div class="my-toolbar">
<button
[class.active]="props.activeStates['bold']"
[disabled]="props.disabledStates['bold']"
(click)="props.manager?.getEditor().chain().focus().toggleBold().run()"
>Bold</button>
</div>
</ng-template>
Svelte
The Svelte adapter compatible with both Svelte 4 and Svelte 5.
Requirements: Svelte ^4 || ^5
Installation
npm install @cyte-editor/core @cyte-editor/svelte
Import Styles
import '@cyte-editor/core/style.css'
import '@cyte-editor/svelte/style.css'
Basic Usage
<script>
import { CyteEditor } from '@cyte-editor/svelte'
import '@cyte-editor/core/style.css'
import '@cyte-editor/svelte/style.css'
let content = '<p>Hello, CyteEditor!</p>'
</script>
<CyteEditor
html={content}
placeholder="Start writing…"
locale="en-US"
onChange={(e) => content = e.html}
/>
Content Binding
Svelte uses the html prop and onChange event:
<CyteEditor
html={content}
onChange={(e) => content = e.html}
/>
Toolbar Customization
Configure which toolbar items to display via the toolbar prop:
<CyteEditor
html={content}
toolbar={['bold', 'italic', 'underline', '|', 'heading', 'align']}
onChange={(e) => content = e.html}
/>
For full control, use the toolbarRender callback with click delegation:
<script>
let editorManager = null
function handleToolbarClick(e) {
const btn = e.target.closest('[data-cmd]')
if (!btn || !editorManager) return
const chain = editorManager.getEditor().chain().focus()
const commands = {
toggleBold: () => chain.toggleBold().run(),
toggleItalic: () => chain.toggleItalic().run(),
}
commands[btn.dataset.cmd]?.()
}
</script>
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div onclick={handleToolbarClick}>
<CyteEditor
html={content}
onChange={(e) => content = e.html}
onReady={(mgr) => editorManager = mgr}
toolbarRender={({ activeStates, disabledStates }) => `
<div class="my-toolbar">
<button class="${activeStates.bold ? 'active' : ''}"
${disabledStates.bold ? 'disabled' : ''}
data-cmd="toggleBold">
Bold
</button>
</div>
`}
/>
</div>
Vanilla JS
Direct integration using EditorManager — no framework required.
Requirements: None (framework-free, supports IIFE/UMD)
Installation
npm install @cyte-editor/core @cyte-editor/vanilla
Import Styles
import '@cyte-editor/core/style.css'
Basic Usage
import { EditorManager } from '@cyte-editor/core'
import '@cyte-editor/core/style.css'
import { renderToolbar } from '@cyte-editor/vanilla'
const el = document.querySelector('#editor')
const manager = EditorManager.create(el, {
height: '400px',
locale: 'en-US',
})
manager.setContent('<p>Hello, CyteEditor!</p>')
const toolbar = renderToolbar(document.querySelector('#toolbar'), {
isProMode: false,
})
toolbar.attachEditor(manager.getEditor(), manager)
Content API
Vanilla JS uses the EditorManager API directly:
// Set content
manager.setContent('<p>New content</p>')
// Get content
const html = manager.getHTML()
const json = manager.getJSON()
const text = manager.getText()
// Listen for changes
manager.on('update', ({ html }) => {
console.log('Content changed:', html)
})
Framework Comparison
| Framework | Package | Component | Content Binding |
|---|---|---|---|
| Vue 3 | @cyte-editor/vue3 | <CyteEditor> | v-model:html |
| Vue 2 | @cyte-editor/vue2 | <CyteEditor> | :html + @update:html |
| React | @cyte-editor/react | <CyteEditor> | html + onChange |
| Angular | @cyte-editor/angular | <cyte-editor> | [html] + (onChange) |
| Svelte | @cyte-editor/svelte | <CyteEditor> | html + onChange |
| Vanilla | @cyte-editor/vanilla | EditorManager | setContent() / getHTML() |
Pro Plugins (Optional)
Pro plugins extend CyteEditor with advanced capabilities. Each plugin is a separate package:
npm install @cyte-editor/pro-export
npm install @cyte-editor/pro-paste
npm install @cyte-editor/pro-revision
- pro-export — Import/export Markdown, Word (.docx), and HTML.
- pro-paste — Smart clipboard handling for Word, Excel, WPS, and HTML.
- pro-revision — Version snapshots, rich-text diff, and side-by-side comparison.
Pro plugins require @cyte-editor/license and a valid license key:
npm install @cyte-editor/license
Registering Plugins
Plugins can be registered at creation time or dynamically:
// At creation
const manager = EditorManager.create(el, {
plugins: [ProPaste(), ProExport(), ProRevision()],
license: { key: 'your-license-key' },
})
// Dynamically
manager.use(ProPaste())
For framework adapters, pass plugins through the same plugins config option. See the API Reference for full configuration details.
TypeScript Support
CyteEditor is written in TypeScript and ships complete type definitions out of the box. No additional @types packages are required.
Next Steps
- Installation — Package overview and environment requirements.
- Getting Started — Quick-start guide with minimal setup.
- API Reference — Full EditorManager API, config options, and events.