@mdzip/editor-vue

Vue wrapper for the MDZip workspace editor.
4,738 4
Install
npm install @mdzip/editor-vue
Latest Version:2.4.0
Vue:3
License:Apache-2.0
Last Updated:Oct 23, 2026
Links: GitHub  ·  npm
Maintainer: kylemwhite

MDZip logo

@mdzip/editor-vue

npm license

Vue 3 component wrapper for the MDZip workspace editor.

@mdzip/editor-vue provides a MdzipWorkspace component that embeds the full MDZip workspace UI — document preview, editor, package navigator, and asset manager — as a native Vue 3 component.

Install

npm install @mdzip/editor-vue

Peer dependency: vue >=3.

Basic Usage

<script setup lang="ts">
import { MdzipWorkspace } from '@mdzip/editor-vue';

const props = defineProps<{ bytes: Uint8Array }>();
</script>

<template>
  <div style="height: 600px">
    <MdzipWorkspace
      :bytes="props.bytes"
      file-name="document.mdz"
      mode="read-only"
      controls="viewer"
      @failed="console.error"
    />
  </div>
</template>

The parent element must have an explicit height. The component expands to fill it.

Archive Diff

<script setup lang="ts">
import { MdzipDiff } from '@mdzip/editor-vue/diff-view';
</script>

<template>
  <div style="height: 600px">
    <MdzipDiff
      :before="{ bytes: baseBytes, label: 'Git base' }"
      :after="{ bytes: workingBytes, label: 'Working tree' }"
      initial-path="index.md"
      :toolbar-actions="[{ id: 'refresh', label: 'Refresh', icon: 'refresh', run: refresh }]"
    />
  </div>
</template>

The component emits selectionChanged and failed. Its exposed handle provides openPath, openPreviousChange, openNextChange, setShowUnchanged, setNavigationVisible, and setToolbarActions. The built-in toolbar adds Previous/Next change buttons and a Show-unchanged toggle; pass a controls prop ({ navigation?, changeTraversal?, showUnchanged? }) to opt any out.

Editor Mode

<MdzipWorkspace
  :bytes="bytes"
  file-name="document.mdz"
  mode="editable"
  controls="standalone-editor"
  @saved="onSaved"
  @changed="onChanged"
/>

Props

Prop Type Default Description
bytes Uint8Array | null null Raw archive bytes to open
workspace MdzWorkspace | null null Pre-built workspace object
fileName string 'document.mdz' Filename used for format detection and Save dialogs
mode MdzipWorkspaceMode 'read-only' 'read-only' or 'editable'
sourceFormat MdzipSourceFormat — Override format detection: 'mdz' or 'markdown'
controls MdzipControlPreset | MdzipControlPolicy 'viewer' 'preview', 'viewer', 'standalone-editor', 'hosted-editor', or a policy object
toolbarDensity 'comfortable' | 'compact' | 'dense' 'comfortable' Semantic sizing preset for built-in toolbar controls
contentDensity 'comfortable' | 'compact' 'comfortable' Semantic padding preset for editor and preview content
imageHydrationAnimation 'auto' | 'initial' | 'off' 'auto' Control preview image reveal animation: every render, first render per document path, or never
initialLayout MdzipWorkspaceLayout — Starting layout: 'preview', 'editor', 'split'
initialColorScheme MdzipColorSchemePreference 'system' 'light', 'dark' or 'system' (follows the OS setting live)
systemColorScheme MdzipSystemColorScheme — Makes the color scheme menu's System choice follow the host's theme instead of the OS setting, with its own label and icon, e.g. { colorScheme: 'dark', label: 'VS Code theme', icon: '<svg…>' }; changes apply live
previewMaxWidth MdzipPreviewMaxWidth 'default' Preview reading-column width: 'narrow', 'default', 'wide', 'full' or a pixel number; the user can change it from the toolbar's page-width menu
navigationMode MdzipNavigationMode 'editor' Package navigation mode
navigationButtonActive boolean true Whether the navigation button is shown
inlineSvgLinks boolean true Shows archive SVGs that contain links inline, so the links can be clicked (draw.io .drawio.svg diagrams, for example); other SVGs stay images. Read when the view is created
hostFileActions readonly MdzipFileAction[] — The host's own items in the file tree's right-click menu on files ({ id, label, appliesTo?, run }), e.g. "Open in Another Editor". Also shown as buttons on the card that stands in for a .drawio image. Read when the view is created
markdownRenderer MdzipMarkdownRenderer | null null Custom markdown renderer (keep the reference stable)
markdownExtensions readonly MdzipMarkdownRenderExtension[] [] Markdown pipeline extensions, diffed by name — inline arrays are safe
entryRenderers readonly MdzipEntryRenderer[] [] Entry renderers claiming the content area for matching entries, diffed by id — inline arrays are safe
entrySlotPriority number 0 Matching priority of the #entry slot relative to entryRenderers
frontMatter MdzipFrontMatterOptions {} Front matter panel config (enabled, display, collapsible, label) — always registered, diffed by deep equality; inline objects are safe
externalLinks MdzipExternalLinkPolicy — External-link policy, e.g. { target: '_blank' } (adds rel="noopener noreferrer"); optional rel and predicate(href). Re-applies without a re-render only when target, rel or predicate change; inline objects are safe

controls, density, imageHydrationAnimation, and rendering prop changes apply in place — they never recreate the workspace view. Line-number visibility changes preserve the current CodeMirror document and selection. See the @mdzip/editor Rendering Extensibility docs for the contracts and lifecycle rules.

Native entry rendering (#entry slot)

<MdzipWorkspace :bytes="bytes">
  <template #entry="{ context }">
    <ManifestEditor
      v-if="context.path.toLowerCase() === 'manifest.json'"
      :manifest="context.manifest"
      :editable="context.mode === 'editable'"
      @manifest-change="context.updateManifest"
    />
  </template>
</MdzipWorkspace>

A slot render that produces no content (its v-if is false) delegates to entryRenderers and the built-in rendering. The slot mounts in a detached tree sharing the host app context (plugins, provide/inject); the context is reactive, and the tree unmounts on selection change.

Events

Event Payload Description
changed MdzipWorkspaceChange Emitted when archive bytes change
saved MdzipWorkspaceSave Emitted on Save
snapshotChanged MdzipWorkspaceSnapshot Emitted on any state change
selectionChanged MdzipWorkspaceSnapshot Emitted when the editor selection changes
dirtyChanged MdzipWorkspaceSnapshot Emitted when the dirty flag changes
validationChanged MdzipWorkspaceSnapshot Emitted when validation state changes
colorSchemeChanged MdzipColorScheme Emitted when the color scheme changes
colorSchemePreferenceChanged MdzipColorSchemePreference Emitted when the user picks Light, Dark or System in the toolbar menu
previewWidthChanged MdzipPreviewWidthChoice Emitted when the user picks a width in the toolbar's page-width menu
previewRendered MdzipWorkspaceSnapshot Emitted when the preview HTML is mounted
assetsHydrated MdzipWorkspaceSnapshot Emitted once the mounted preview's images have loaded
linkActivated MdzipLinkActivatedEvent Emitted for every preview link click before built-in handling; call event.preventDefault() to take over
failed unknown Emitted on unrecoverable errors

Conversion hook

onConversionRequested is a function prop (not an emit, because it must return a value): pass (action: MdzipConversionAction) => boolean | Promise<boolean>. It fires when the user triggers the markdown→MDZ conversion flow (nav button, Insert Image, or image paste on a plain .md). Return/resolve true to take over and suppress the built-in conversion dialog.

onPackRequested is the same kind of function prop for the folder→.mdz packing decision surfaced by the exposed packFilesAsWorkspace(files, options) method — fires only when the file list contains more than one Markdown file, with the same return contract as onConversionRequested.

Image insertion

Pass image-insert-mode="markdown", "ask", or "html" for the built-in image markup flow. Pass :image-insert-handler="handler" for host-owned image UI; the handler can return Markdown or HTML sizing/alignment settings, return null to cancel, or return undefined to fall back to imageInsertMode.

Pass :image-edit-handler="handler" to let users edit an existing image by clicking it. Fully opt-in — with no handler, clicking an image does nothing and no edit affordance appears; there is no built-in fallback dialog.

File management (nav pane)

With controls="standalone-editor" or "hosted-editor" (or fileActions: true in a custom policy), the navigation pane offers a right-click context menu: new .md file, new folder, rename/move, duplicate, replace, download, copy markdown link, set entry point, set cover image, and delete. Files can also be dragged between folders, and OS files can be dropped onto the pane. Copy and Download remain available in read-only mode. The same operations are exposed on the handle: removeFile, renameFile, setEntryPoint, and setCoverImage.

Imperative API

Use a template ref to access the exposed handle:

<script setup lang="ts">
import { ref } from 'vue';
import { MdzipWorkspace, type MdzipWorkspaceExposed } from '@mdzip/editor-vue';

const workspace = ref<MdzipWorkspaceExposed>();

async function save() {
  const snapshot = await workspace.value?.flush();
  if (snapshot) {
    await persist(snapshot.bytes);
    workspace.value?.markPersisted();
  }
}
</script>

<template>
  <MdzipWorkspace ref="workspace" ... />
</template>

The handle also exposes whenRendered(), which resolves once the current preview (including its images) is mounted — useful for revealing or animating read-only preview content.

Links and anchors

The linkActivated event fires for every preview link click, before the view's own handling, with the parsed link (kind: 'anchor' | 'document' | 'relative' | 'external', plus path, anchor, targetPath, sourcePath, modifier keys). Call event.preventDefault() in the handler to route the link yourself; unprevented clicks keep the built-in behavior. The handle also exposes scrollToAnchor(anchor) (waits for the preview to mount, resolves whether it scrolled; safe straight after load), getAvailableAnchors(), openPath(path, { anchor }) (opens another file, optionally at an anchor) and getCurrentPath(). Changing only fileName (e.g. after Save As) renames in place without reopening; set preserveSelectionOnReopen to stay on the current file when the archive content changes. See the @mdzip/editor README.

See the @mdzip/editor package for the full API reference, theming guide, and framework-agnostic usage.

Version History

Version Released Vue License
2.4.0 >=3.0.0 Apache-2.0
2.3.0 >=3.0.0 Apache-2.0
2.2.0 >=3.0.0 Apache-2.0
2.1.0 >=3.0.0 Apache-2.0
2.0.1 >=3.0.0 Apache-2.0