Examples & Live Demos
Switch between the Live Preview tab to test interactive editors directly in your browser and the Vue Code tab to view the complete code snippets.
1. Basic Controlled Component
Minimal two-way binding using Vue 3 v-model.
vue<script setup lang="ts">
import { shallowRef } from 'vue';
import { Editor } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<p>Hello World!</p>');
</script>
<template>
<Editor v-model="content" placeholder="Start typing..." />
</template>
Minimal custom toolbar preset with top menubar disabled.
vue<script setup lang="ts">
import { computed, shallowRef } from 'vue';
import { Editor, type EditorInit } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<h2>Customized Editor</h2>');
const editorConfig = computed<EditorInit>(() => ({
height: 240,
menubar: false,
statusbar: true,
toolbar: 'undo redo | bold italic underline | alignleft aligncenter alignright | bullist numlist | removeformat',
}));
</script>
<template>
<Editor v-model="content" :init="editorConfig" />
</template>
3. Readonly & Disabled Modes
Dynamically toggle the editor between editable, readonly, and disabled states.
vue<script setup lang="ts">
import { shallowRef } from 'vue';
import { Editor } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<p>Dynamic state toggling.</p>');
const isReadonly = shallowRef(false);
const isDisabled = shallowRef(false);
</script>
<template>
<div class="controls">
<label><input v-model="isReadonly" type="checkbox" /> Readonly</label>
<label><input v-model="isDisabled" type="checkbox" /> Disabled</label>
</div>
<Editor
v-model="content"
:readonly="isReadonly"
:disabled="isDisabled"
/>
</template>
4. Programmatic Control (Template Ref API)
Trigger focus, insert HTML, or clear content programmatically using useTemplateRef.
vue<script setup lang="ts">
import { shallowRef, useTemplateRef } from 'vue';
import { Editor, type EditorInstance } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<p>Initial content...</p>');
const editor = useTemplateRef<EditorInstance>('editor');
function insertGreeting(): void {
editor.value?.focus();
editor.value?.insertHtml('<p><strong>Hello from API!</strong> 👋</p>');
}
function clearContent(): void {
editor.value?.clear();
}
</script>
<template>
<button type="button" @click="insertGreeting">Insert Greeting</button>
<button type="button" @click="clearContent">Clear</button>
<Editor ref="editor" v-model="content" />
</template>
5. Mentions (@) Autocomplete
Type @ in the editor to trigger team member autocomplete.
vue<script setup lang="ts">
import { computed, shallowRef } from 'vue';
import { Editor, type EditorInit, type MentionSelectEvent } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<p>Type <strong>@</strong> to mention someone.</p>');
const teamMembers = [
{ id: 1, label: 'Damon Cross', description: 'Senior Backend Developer', value: 'damon@example.com' },
{ id: 2, label: 'Ava Mitchell', description: 'Product Designer', value: 'ava@example.com' },
];
const editorConfig = computed<EditorInit>(() => ({
height: 280,
mentions: {
enabled: true,
items: teamMembers,
},
}));
</script>
<template>
<Editor v-model="content" :init="editorConfig" />
</template>
Type {{ or open the Merge Tags sidebar drawer.
vue<script setup lang="ts">
import { computed, shallowRef } from 'vue';
import { Editor, type EditorInit, type MergeTagItem } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<p>Dear <code>{{ client.name }}</code>...</p>');
const tags: MergeTagItem[] = [
{ name: 'Client name', value: 'client.name', group: 'Client Details' },
{ name: 'Proposal ID', value: 'proposal.id', group: 'Proposal' },
];
const editorConfig = computed<EditorInit>(() => ({
height: 280,
mergeTags: {
enabled: true,
items: tags,
},
}));
</script>
<template>
<Editor v-model="content" :init="editorConfig" />
</template>
7. Templates Selection
Select structured document templates from the top menu.
vue<script setup lang="ts">
import { computed, shallowRef } from 'vue';
import { Editor, type EditorInit } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<p>Select a template...</p>');
const editorConfig = computed<EditorInit>(() => ({
height: 280,
templates: {
enabled: true,
items: [
{
id: 'welcome-email',
title: 'Welcome Email',
description: 'Client onboarding template',
content: '<h2>Welcome Aboard!</h2><p>Dear Customer, welcome.</p>',
},
],
},
}));
</script>
<template>
<Editor v-model="content" :init="editorConfig" />
</template>
8. Image Uploads & Progress
Drag & drop or select images with simulated progress reporting.
vue<script setup lang="ts">
import { computed, shallowRef } from 'vue';
import { Editor, type EditorInit, type ImagesUploadHandler } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<p>Upload or drag an image...</p>');
const handleImageUpload: ImagesUploadHandler = async (blobInfo, progress) => {
return new Promise((resolve) => {
let p = 0;
const interval = setInterval(() => {
p += 25;
progress(p);
if (p >= 100) {
clearInterval(interval);
resolve('https://picsum.photos/600/350');
}
}, 150);
});
};
const editorConfig = computed<EditorInit>(() => ({
height: 300,
imagesUploadHandler: handleImageUpload,
}));
</script>
<template>
<Editor v-model="content" :init="editorConfig" />
</template>
9. Enterprise All-in-One Suite
Complete production-grade setup with all plugins, mentions, merge tags, templates, and full toolbar.
vue<script setup lang="ts">
import { computed, shallowRef } from 'vue';
import { Editor, type EditorInit } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';
const content = shallowRef('<h2>Enterprise Document Editor 🚀</h2>');
const editorConfig = computed<EditorInit>(() => ({
height: 350,
menubar: true,
statusbar: true,
mentions: { enabled: true, items: [...] },
mergeTags: { enabled: true, items: [...] },
templates: { enabled: true, items: [...] },
toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline | forecolor backcolor | alignleft aligncenter alignright | bullist numlist | link image media table | code preview fullscreen',
}));
</script>
<template>
<Editor v-model="content" :init="editorConfig" />
</template>