Skip to content

Choosing a Vue text editor is only the first decision. The toolbar can contain every formatting feature your product supports and still be difficult to use. The problem is usually not the editor engine; it is the decision to expose every button on every screen.

A comment box, a support reply and a long-form article do different jobs. A comment needs bold, lists and links. An article may need headings, images, tables and preview. Giving all three screens the same large toolbar makes the small editor noisy and makes the important actions harder to find.

This guide explains how I design a Vue 3 text editor around the content people are actually creating. The examples use @erag/text-editor-vue, but the UX decisions apply to a Vue WYSIWYG editor, a Markdown editor or a headless editor with your own controls.

What should a Vue text editor include? ​

There is no single best Vue text editor for every product. A drop-in rich text editor gives you a ready-made toolbar, menus and browser behavior. A headless Vue editor gives you more control over the interface but asks you to build the controls and interaction states yourself. A Markdown editor is a good fit when the stored format matters more than visual formatting.

For most admin panels, comments and article forms, start with the smallest rich text feature set that solves the writing job:

Use caseUseful Vue text editor features
CommentsBold, italic, lists, links and a short height
Support repliesFormatting, links, templates and predictable paste behavior
Blog postsHeadings, lists, links, images, preview and draft saving
Internal notesFormatting, mentions and a clear read-only mode

This decision prevents the common mistake of choosing a powerful editor and then exposing its entire feature list. The editor should feel like part of your product, not like a separate word processor embedded inside it.

Start with the user’s writing job ​

Before choosing toolbar buttons, write down what the user is trying to publish. A useful editor preset answers these questions:

  • Is the content a short message or a document?
  • Will another person read it as formatted HTML?
  • Are images, tables or links part of the job?
  • Does the content need moderation before it is visible?
  • Will most users edit on a phone?

If the answer is “short message”, do not expose a miniature word processor. If the answer is “knowledge base article”, give the user headings, lists and links, but still keep rarely used actions discoverable under a menu.

The toolbar should make the common action obvious and the uncommon action possible. It does not need to display both with the same visual weight.

Use a focused preset for comments ​

@erag/text-editor-vue accepts a compact toolbar string. A comment editor can stay small and predictable:

vue
<script setup lang="ts">
import { ref } from 'vue';
import { Editor, type EditorInit } from '@erag/text-editor-vue';
import '@erag/text-editor-vue/style.css';

const comment = ref('');

const commentEditor: EditorInit = {
    height: 220,
    menubar: false,
    toolbar: 'bold italic | bullist numlist | link',
    statusbar: false,
    placeholder: 'Write a reply…',
};
</script>

<template>
    <Editor v-model="comment" :init="commentEditor" />
</template>

This preset gives users familiar formatting without asking them to understand source code, media plugins or document-level menus. The shorter toolbar also leaves more space for the text area on a phone.

A placeholder should describe the action rather than repeat a field label. “Write a reply…” helps more than “Content”. If the editor is optional, say so near the submit button instead of putting a paragraph of instructions inside the editing surface.

Use the menubar for secondary actions ​

An article editor may need more controls, but the toolbar still benefits from a hierarchy. Keep undo, redo, headings, common formatting, lists and links visible. Put less common actions under Insert, Format or View.

ts
const articleEditor: EditorInit = {
    height: 520,
    menubar: ['file', 'edit', 'view', 'insert', 'format'],
    toolbar: 'undo redo | blocks | bold italic | bullist numlist | link image | preview fullscreen',
    plugins: ['history', 'formatting', 'lists', 'link', 'image', 'preview', 'fullscreen'],
};

When you supply a plugins array, plugin-backed toolbar controls need their matching plugin. Adding image to the toolbar without enabling the image plugin does not make the feature available. Keeping the two lists together makes the configuration easier to review.

Do not hide basic actions behind an icon-only menu on desktop if a text label would be clearer. People should be able to discover how to add a link or a heading without memorizing the product.

Keep the content area stable ​

Editor controls should not make the writing area jump. Choose a useful height, set a minHeight for smaller screens and let the status bar resize the editor only if resizing helps the workflow:

ts
const supportReplyEditor: EditorInit = {
    height: 300,
    minHeight: 220,
    maxHeight: 560,
    menubar: false,
    toolbar: 'undo redo | bold italic | bullist numlist | link',
    resize: true,
};

If a form has several fields, keep the submit button outside the editor and avoid placing important controls below an editor that grows without limit. A person should always know where the form ends.

On screens around 680px or narrower, the package toolbar can scroll horizontally. That is useful, but it is not a reason to add twenty controls. A sideways toolbar with six relevant buttons is manageable; a sideways toolbar with every plugin is still exhausting.

Give keyboard users a complete path ​

Toolbar design is also keyboard design. Users should be able to type, select text, use familiar shortcuts, undo a mistake and move to the next form control. Make sure toolbar buttons have readable labels or accessible names, and do not put important actions behind a hover-only interaction.

If the editor sits inside an Inertia form, put the submit control after the editor in the normal tab order. A user who presses Tab after writing should reach the next meaningful control, not lose focus inside a group of formatting buttons.

The status bar can be useful for element information and resize behavior, but it should not be the only place where a user can understand what happened. Show save state or errors near the form action as well.

Match the toolbar to your stored HTML policy ​

A toolbar is a promise about what content the product accepts. If the product cannot safely render tables, do not expose a table action. If links need https only, validate that policy when saving the HTML. If images need an upload endpoint, configure the handler and show a useful failure when the upload does not complete.

The editor’s browser sanitizer protects the editing surface. Your Laravel application still owns the stored content and should sanitize it again before showing it to other users. The Vue rich text image upload guide covers storage, validation, progress and deletion when images are allowed.

Keep a distinction between draft HTML and published HTML if your workflow has moderation. A draft can be editable by its author while the public renderer accepts only the subset of tags and attributes your application has reviewed.

Use different presets instead of one giant configuration ​

One global editor configuration usually grows until every page pays for features it does not use. Define presets by job:

ts
export const replyEditor: EditorInit = {
    height: 220,
    menubar: false,
    toolbar: 'bold italic | bullist numlist | link',
};

export const articleEditor: EditorInit = {
    height: 520,
    menubar: ['edit', 'insert', 'format', 'view'],
    toolbar: 'undo redo | blocks | bold italic | bullist numlist | link image | preview',
    plugins: ['history', 'formatting', 'lists', 'link', 'image', 'preview'],
};

This also gives design and support teams something concrete to discuss. “The article editor needs an image button” is clearer than “the editor should have all features enabled”.

Handle empty and read-only states deliberately ​

An empty editor should have a useful placeholder and a clear submit state. If empty content is invalid, show the error near the editor after submit and keep the focus available. Do not rely on the browser’s required attribute for HTML content; an editor is not a normal text input.

For read-only content, use the editor’s read-only configuration or render sanitized HTML with a dedicated display component. A disabled toolbar with active-looking buttons is confusing. Readers do not need editing controls, and editors should know when their changes are actually possible.

Check mobile behavior with real content ​

Do not test only an empty editor at desktop width. Try a long heading, a list, a link dialog and an image on a narrow screen. Check that menus stay inside the viewport, the toolbar can be reached with touch and the editor does not push the save button into an unreachable area.

Test pasted content too. The formatting a user copies from Google Docs or a browser page can be much larger than the formatting your toolbar exposes. Keep the saved HTML policy stricter than the editing experience.

A practical Vue editor toolbar checklist ​

Before releasing a Vue rich text editor, ask:

  • Does every visible button help the current writing job?
  • Are common actions visible without opening a menu?
  • Are rare actions grouped under meaningful labels?
  • Does the toolbar work on a 360px-wide screen?
  • Can keyboard users reach the submit button naturally?
  • Does the placeholder explain what to write?
  • Is empty content validated on the server?
  • Are pasted HTML and links sanitized before public rendering?
  • Are image uploads and failed uploads understandable?
  • Is there a separate preset for comments and long documents?

Should I show a full toolbar on every page? ​

Usually no. A focused toolbar lowers visual noise and makes the important actions easier to find. Add a larger preset only where the content truly needs it.

Do I need a menubar if the toolbar already has buttons? ​

Not for a small comment editor. A menubar becomes useful when there are several groups of secondary actions, such as templates, tables, source code, preview or print.

Can the editor sanitizer replace server-side sanitization? ​

No. Browser sanitization improves the editing experience, but saved HTML is still input from a client. Sanitize and validate it again on the server before rendering it to other users.

A good Vue rich text editor toolbar feels smaller than the editor’s feature list. Decide what the user is doing, keep that path visible, move secondary actions into menus and make the saved content rules explicit. The editor then supports writing instead of asking users to operate a control panel.

Last updated:

Written by Amit Gupta. Code samples are MIT licensed.