Skip to content

@vizel/vue

Vue 3 components and composables for Vizel editor.

Looking for a guide?

See the Vue Guide for step-by-step tutorials and common patterns.

Installation

bash
npm install @vizel/vue

Components

Vizel

All-in-one editor component with built-in bubble menu. This is the recommended way to get started.

vue
<script setup lang="ts">
import { Vizel } from '@vizel/vue';
import '@vizel/core/styles.css';
</script>

<template>
  <Vizel
    :initialContent="{ type: 'doc', content: [] }"
    placeholder="Start writing..."
    :editable="true"
    autofocus="end"
    :showBubbleMenu="true"
    :enableEmbed="true"
    class="my-editor"
    :features="{ markdown: true }"
    @update="({ editor }) => {}"
    @create="({ editor }) => {}"
    @focus="({ editor }) => {}"
    @blur="({ editor }) => {}"
  />
</template>

Props:

PropTypeDefaultDescription
initialContentJSONContent-Initial editor content (JSON)
initialMarkdownstring-Initial editor content (Markdown)
v-model:markdownstring-Two-way Markdown binding
placeholderstring-Placeholder text
editablebooleantrueEditable state
autofocusboolean | 'start' | 'end' | 'all' | number-Auto focus behavior
featuresVizelFeatureOptions-Feature configuration
classstring-CSS class name
showToolbarbooleanfalseShow fixed toolbar above editor
showBubbleMenubooleantrueShow bubble menu on selection
enableEmbedboolean-Enable embed in link editor
flavorVizelMarkdownFlavor"gfm"Markdown output flavor
localeVizelLocale-Locale for translated UI strings
extensionsExtensions-Additional Tiptap extensions
transformDiagramsOnImportbooleantrueTransform diagram code blocks when importing markdown

Slots:

SlotPropsDescription
toolbar{ editor: Editor }Custom toolbar content

Events:

EventPayloadDescription
update{ editor: Editor }Fires when content changes
update:markdownstringFires when Markdown content changes
create{ editor: Editor }Fires when the editor initializes
destroy-Fires when the editor destroys
selectionUpdate{ editor: Editor }Fires when the selection changes
focus{ editor: Editor }Fires when the editor gains focus
blur{ editor: Editor }Fires when the editor loses focus
errorVizelErrorFires when an error occurs

Composables

useVizelEditor

This composable creates and manages a Vizel editor instance.

typescript
import { useVizelEditor } from '@vizel/vue';

const editor = useVizelEditor(options?: VizelEditorOptions);

Returns: ShallowRef<Editor | null>

useVizelState

This composable forces a re-render on editor state changes.

typescript
import { useVizelState } from '@vizel/vue';

const updateCount = useVizelState(() => editor.value);

Returns: Ref<number> (update count)

useVizelEditorState

This composable returns a VizelEditorState object that reactively tracks editor state (bold, italic, heading level, etc.).

typescript
import { useVizelEditorState } from '@vizel/vue';

const state = useVizelEditorState(() => editor.value);
// state.value.isBold, state.value.isItalic, state.value.headingLevel, etc.

Returns: ComputedRef<VizelEditorState> — reactive computed ref with boolean flags for formatting state and current node info

useVizelAutoSave

This composable auto-saves editor content with debouncing.

typescript
import { useVizelAutoSave } from '@vizel/vue';

const result = useVizelAutoSave(
  getEditor: () => Editor | null,
  options?: VizelAutoSaveOptions
);

Returns:

PropertyTypeDescription
statusComputedRef<VizelSaveStatus>Current save status
hasUnsavedChangesComputedRef<boolean>Whether unsaved changes exist
lastSavedComputedRef<Date | null>Last save timestamp
errorComputedRef<Error | null>Last error
save() => Promise<void>Save content manually
restore() => Promise<JSONContent | null>Restore content manually

useVizelMarkdown

This composable provides two-way Markdown synchronization with debouncing.

typescript
import { useVizelMarkdown } from '@vizel/vue';

const result = useVizelMarkdown(
  getEditor: () => Editor | null,
  options?: VizelMarkdownSyncOptions
);

Options:

OptionTypeDefaultDescription
debounceMsnumber300Debounce delay in milliseconds
transformDiagramsbooleantrueTransform diagram code blocks when setting markdown

Returns:

PropertyTypeDescription
markdownRef<string>Current Markdown content
setMarkdown(md: string) => voidUpdate editor from Markdown
isPendingRef<boolean>Whether sync is pending

useVizelTheme

This composable accesses theme state within VizelThemeProvider.

typescript
import { useVizelTheme } from '@vizel/vue';

const { theme, resolvedTheme, systemTheme, setTheme } = useVizelTheme();

Returns:

PropertyTypeDescription
themeVizelThemeCurrent theme setting
resolvedThemeVizelResolvedThemeResolved theme (actual applied theme)
systemThemeVizelResolvedThemeSystem preference
setTheme(theme: VizelTheme) => voidSet theme function

useVizelCollaboration

This composable tracks real-time collaboration state with a Yjs provider.

typescript
import { useVizelCollaboration } from '@vizel/vue';

const {
  isConnected,
  isSynced,
  peerCount,
  error,
  connect,
  disconnect,
  updateUser,
} = useVizelCollaboration(
  () => provider,
  { user: { name: 'Alice', color: '#ff0000' } }
);

Parameters:

ParameterTypeDescription
getProvider() => VizelYjsProvider | null | undefinedGetter function for the Yjs provider
optionsVizelCollaborationOptionsCollaboration options including user info

Returns: UseVizelCollaborationResult

PropertyTypeDescription
isConnectedComputedRef<boolean>Whether the editor is connected to the server
isSyncedComputedRef<boolean>Whether initial sync is complete
peerCountComputedRef<number>Number of connected peers
errorComputedRef<Error | null>Last error
connect() => voidConnect to the server
disconnect() => voidDisconnect from the server
updateUser(user: VizelCollaborationUser) => voidUpdate user cursor info

useVizelComment

This composable manages document comments and annotations.

typescript
import { useVizelComment } from '@vizel/vue';

const {
  comments,
  activeCommentId,
  isLoading,
  error,
  addComment,
  removeComment,
  resolveComment,
  reopenComment,
  replyToComment,
  setActiveComment,
  loadComments,
  getCommentById,
} = useVizelComment(() => editor.value, { key: 'my-comments' });

Parameters:

ParameterTypeDescription
getEditor() => Editor | null | undefinedGetter function for the editor
optionsVizelCommentOptionsComment configuration options

Returns: UseVizelCommentResult

PropertyTypeDescription
commentsComputedRef<VizelComment[]>All stored comments (newest first)
activeCommentIdComputedRef<string | null>Currently active comment ID
isLoadingComputedRef<boolean>Whether comments are loading
errorComputedRef<Error | null>Last error
addComment(text: string, author?: string) => Promise<VizelComment | null>Add a comment to the selection
removeComment(commentId: string) => Promise<void>Remove a comment
resolveComment(commentId: string) => Promise<boolean>Resolve a comment
reopenComment(commentId: string) => Promise<boolean>Reopen a comment
replyToComment(commentId: string, text: string, author?: string) => Promise<VizelCommentReply | null>Reply to a comment
setActiveComment(commentId: string | null) => voidSet the active comment
loadComments() => Promise<VizelComment[]>Load comments from storage
getCommentById(commentId: string) => VizelComment | undefinedGet a comment by ID

useVizelVersionHistory

This composable manages document version history with save, restore, and delete operations.

typescript
import { useVizelVersionHistory } from '@vizel/vue';

const {
  snapshots,
  isLoading,
  error,
  saveVersion,
  restoreVersion,
  loadVersions,
  deleteVersion,
  clearVersions,
} = useVizelVersionHistory(() => editor.value, { maxVersions: 20 });

Parameters:

ParameterTypeDescription
getEditor() => Editor | null | undefinedGetter function for the editor
optionsVizelVersionHistoryOptionsVersion history configuration

Returns: UseVizelVersionHistoryResult

PropertyTypeDescription
snapshotsComputedRef<VizelVersionSnapshot[]>All stored snapshots (newest first)
isLoadingComputedRef<boolean>Whether history is loading
errorComputedRef<Error | null>Last error
saveVersion(description?: string, author?: string) => Promise<VizelVersionSnapshot | null>Save a new version
restoreVersion(versionId: string) => Promise<boolean>Restore a version
loadVersions() => Promise<VizelVersionSnapshot[]>Load versions from storage
deleteVersion(versionId: string) => Promise<void>Delete a version
clearVersions() => Promise<void>Delete all versions

Components

VizelFindReplace

Find & Replace panel component. This component renders when the Find & Replace extension is open.

vue
<script setup lang="ts">
import { VizelFindReplace } from '@vizel/vue';
</script>

<template>
  <VizelFindReplace
    :editor="editor"
    class="my-find-replace"
    @close="() => console.log('Closed')"
  />
</template>

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance
classstring-CSS class name
localeVizelLocale-Locale for translated UI strings

Events:

EventPayloadDescription
close-Fires when the panel closes

VizelEditor

This component renders the editor content area.

vue
<VizelEditor :editor="editor" class="my-editor" />

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance
classstring-CSS class name

VizelBlockMenu

Block context menu that appears when clicking the drag handle.

vue
<script setup>
import { VizelBlockMenu } from '@vizel/vue';
</script>

<template>
  <VizelBlockMenu />
</template>
PropTypeDefaultDescription
actionsVizelBlockMenuAction[]vizelDefaultBlockMenuActionsCustom menu actions
nodeTypesVizelNodeTypeOption[]vizelDefaultNodeTypesNode types for "Turn into" submenu
classstring-CSS class name
localeVizelLocale-Locale for translated UI strings

VizelBubbleMenu

This component renders a floating formatting bubble menu.

vue
<VizelBubbleMenu 
  :editor="editor"
  class="my-bubble-menu"
/>

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance
classstring-CSS class name
showDefaultMenubooleantrueShow default formatting menu when no children
pluginKeystring-Custom plugin key for the bubble menu
updateDelaynumber-Delay in ms before updating menu position
shouldShow(props) => boolean-Custom function to control menu visibility
enableEmbedboolean-Enable embed option in link editor

Slots:

SlotDescription
defaultCustom bubble menu content

VizelBubbleMenuDefault

This component renders the default bubble menu with all formatting buttons.

vue
<VizelBubbleMenuDefault 
  :editor="editor"
  :enableEmbed="false"
/>

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance
enableEmbedbooleanfalseEnable embed in links

VizelBubbleMenuButton

This component renders an individual bubble menu button.

vue
<VizelBubbleMenuButton
  icon="lucide:bold"
  :isActive="editor.isActive('bold')"
  @click="editor.chain().focus().toggleBold().run()"
/>

VizelBubbleMenuDivider

This component renders a bubble menu divider.

vue
<VizelBubbleMenuDivider />

VizelToolbar

This component renders a fixed toolbar.

vue
<script setup lang="ts">
import { VizelToolbar } from '@vizel/vue';
</script>

<template>
  <VizelToolbar :editor="editor" class="my-toolbar" />
</template>

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance (falls back to context)
classstring-CSS class name
showDefaultToolbarbooleantrueShow default toolbar content
localeVizelLocale-Locale for translated UI strings

Slots:

SlotPropsDescription
default{ editor: Editor }Custom toolbar content

VizelToolbarDefault

This component renders the default toolbar content with grouped formatting buttons.

vue
<VizelToolbarDefault :editor="editor" :actions="customActions" />

Props:

PropTypeDefaultDescription
editorEditor-Editor instance (required)
classstring-CSS class name
localeVizelLocale-Locale for translated UI strings
actionsVizelToolbarActionItem[]vizelDefaultToolbarActionsCustom actions (supports dropdowns)

VizelToolbarDropdown

This component renders a dropdown toolbar button with a popover of nested actions.

vue
<VizelToolbarDropdown :editor="editor" :dropdown="headingDropdown" />

Props:

PropTypeDefaultDescription
editorEditor-Editor instance (required)
dropdownVizelToolbarDropdownAction-Dropdown action definition (required)
classstring-CSS class name

VizelToolbarOverflow

This component renders a "..." overflow button that shows hidden actions in a popover.

vue
<VizelToolbarOverflow :editor="editor" :actions="overflowActions" />

Props:

PropTypeDefaultDescription
editorEditor-Editor instance (required)
actionsVizelToolbarActionItem[]-Actions to show in overflow (required)
classstring-CSS class name
localeVizelLocale-Locale for translated UI strings

VizelToolbarButton

This component renders an individual toolbar button.

vue
<VizelToolbarButton
  :is-active="editor.isActive('bold')"
  title="Bold (Cmd+B)"
  @click="editor.chain().focus().toggleBold().run()"
>
  <VizelIcon name="bold" />
</VizelToolbarButton>

Props:

PropTypeDefaultDescription
isActivebooleanfalseActive state
disabledbooleanfalseDisabled state
titlestring-Tooltip text
classstring-CSS class name
actionstring-Action identifier

VizelToolbarDivider

This component renders a divider between toolbar button groups.

vue
<VizelToolbarDivider />

VizelThemeProvider

This component provides theme context to its children.

vue
<VizelThemeProvider
  defaultTheme="system"
  storageKey="vizel-theme"
  :disableTransitionOnChange="false"
>
  <slot />
</VizelThemeProvider>

Props:

PropTypeDefaultDescription
defaultThemeVizelTheme"system"Default theme
storageKeystring"vizel-theme"Storage key
targetSelectorstring-Theme target
disableTransitionOnChangebooleanfalseDisable transitions

VizelSaveIndicator

This component displays the save status.

vue
<VizelSaveIndicator :status="status" :lastSaved="lastSaved" />

Props:

PropTypeDescription
statusVizelSaveStatusSave status
lastSavedDate | nullLast save time
classstringCSS class name

VizelPortal

This component renders its children in a portal.

vue
<VizelPortal :container="document.body">
  <slot />
</VizelPortal>

Props:

PropTypeDescription
containerHTMLElementPortal target

VizelColorPicker

This component renders a color selection interface.

vue
<VizelColorPicker
  :colors="colors"
  :value="currentColor"
  :recentColors="recentColors"
  @update:value="setColor"
/>

VizelIconProvider

This component provides custom icons for Vizel components.

vue
<script setup lang="ts">
import { VizelIconProvider } from '@vizel/vue';
import type { CustomIconMap } from '@vizel/core';

const icons: CustomIconMap = {
  bold: 'mdi:format-bold',
  italic: 'mdi:format-italic',
};
</script>

<template>
  <VizelIconProvider :icons="icons">
    <Vizel />
  </VizelIconProvider>
</template>

Props:

PropTypeDescription
iconsCustomIconMapMap of icon names to Iconify icon IDs

Slots:

SlotDescription
defaultChildren

VizelSlashMenu

This component renders the slash command menu.

vue
<VizelSlashMenu
  :items="items"
  :command="handleCommand"
  class="my-menu"
/>

Utilities

createVizelSlashMenuRenderer

This function creates a slash menu renderer for the SlashCommand extension.

typescript
import { createVizelSlashMenuRenderer } from '@vizel/vue';

const suggestion = createVizelSlashMenuRenderer();

const editor = useVizelEditor({
  features: {
    slashCommand: {
      suggestion,
    },
  },
});

Importing from @vizel/core and @tiptap/core

Framework packages do not re-export from @vizel/core. You must import directly:

typescript
// Framework-specific components and composables
import { 
  Vizel, 
  VizelEditor, 
  VizelBubbleMenu, 
  VizelThemeProvider,
  useVizelEditor,
  useVizelMarkdown,
  useVizelAutoSave,
} from '@vizel/vue';

// Vizel types and utilities from @vizel/core
import { getVizelEditorState, VIZEL_TEXT_COLORS } from '@vizel/core';
import type { VizelEditorOptions, VizelSaveStatus } from '@vizel/core';

// Tiptap types from @tiptap/core
import { Editor } from '@tiptap/core';
import type { JSONContent } from '@tiptap/core';

Released under the MIT License.