@devvibex/plugin
v0.1.4
Published
Vite plugins for visual editing, JSX source locations, iframe error postMessage, and a custom Vite error overlay.
Maintainers
Readme
Vibex Frotend Plugin
Vite plugins for visual editing (click-to-edit with source-aware elements), JSX metadata (data-source-location, data-dynamic-content), iframe → parent error reporting via postMessage, and a custom Vite client error overlay aligned with the Vibe-X tooling stack.
This file is the package’s primary documentation and is what npm shows on the package page after publish.
Source: lh-vibex-frontend-plugin
Features
| Capability | Plugin / export | Summary |
|------------|-----------------|---------|
| JSX source tags | babelTransformPlugin | Babel AST transform adds data-source-location and data-dynamic-content on HTML/SVG JSX; injects Tailwind CDN in dev HTML. |
| Visual edit UI | visualEditPlugin | Injects a client script before </body>; hover/click elements with data-source-location, submit edits via postMessage or CustomEvent. |
| Sandbox errors | postMessageInject | Dev-only: forwards error, unhandledrejection, some console.error, and Vite HMR WebSocket issues to parent as app_error. |
| Branded overlay | errorOverlayPlugin | Patches Vite’s client.mjs to replace the default ErrorOverlay with a custom implementation; also exports ErrorOverlay / errorOverlayCode for advanced use. |
Requirements
- Node.js ≥ 18
- Vite 6 (recommended; this package targets the Vite plugin API and client bundle shape)
Installation
npm install @devvibex/pluginRuntime dependencies: @babel/parser, @babel/traverse, @babel/generator, @babel/types (used by the JSX transform).
Quick start
Register plugins in vite.config.js / vite.config.ts. Typical order: React (or your framework plugin) first, then the Babel transform (pre-enforce), then visual edit, postMessage inject, and the error overlay.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import {
visualEditPlugin,
postMessageInject,
babelTransformPlugin,
errorOverlayPlugin,
} from '@devvibex/plugin';
export default defineConfig({
plugins: [
react(),
babelTransformPlugin(),
visualEditPlugin(),
postMessageInject(),
errorOverlayPlugin(),
],
});postMessageInjectusesapply: 'serve'— it only runs in dev and affects HTML injection for the dev server.babelTransformPluginusesenforce: 'pre'so it runs before most transforms. Pair it with@vitejs/plugin-reactas shown so JSX is still handled correctly for your framework.
API reference
babelTransformPlugin()
Returns a Vite plugin that:
- Injects
<script src="https://cdn.tailwindcss.com"></script>before</head>(for visual-editing-related styling in dev). - Transforms
.js,.jsx,.ts,.tsx(skipsnode_modulesand paths containingvisual-edit-agent). - Skips files that look like react-three-fiber / Three.js imports (
@react-three/,from 'three', etc.) to avoid invaliddata-*props on non-DOM reconcilers. - On intrinsic HTML and SVG JSX tags, prepends:
data-source-location— value ispath:line:column, wherepathis derived from the file (e.g.pages/...orcomponents/...segments when present).data-dynamic-content="true" | "false"— heuristic based on JSX children (expressions, non-literals, etc.).
Uses an in-memory LRU cache for transform results.
visualEditPlugin(options?)
Returns a plugin with transformIndexHtml that injects an inline module script before </body>. The client:
- Targets elements with
data-source-location(and readsdata-dynamic-contentwhen submitting). - In iframes, submits changes with
parent.postMessage({ type: messageTypeDataRequest, data: { ... } }, '*')and listens formessageTypeDataResponse. - In top window, dispatches a
CustomEventnamedmessageTypeDataRequestwithdetailas the payload.
Notable options (all optional; defaults are sensible for tooling):
| Option | Default | Notes |
|--------|---------|--------|
| defaultEnabled | false | Whether visual edit mode starts on |
| persistState | false | Persist enabled flag in sessionStorage |
| submitTimeout | 10 | Seconds (converted to ms internally) waiting for parent response in iframe |
| showBadge | false | Floating toggle badge |
| enableKeyboardShortcut | false | Toggle with Ctrl/Cmd+Shift+E |
| defaultInputDisabled | false | Disable the inline input until changed via messaging |
| multiSelectSameLocation | false | Highlight/select all elements sharing the same data-source-location |
| language | 'en' | One of en, ko, vn, jp, ch (placeholder copy) |
| translations | built-in map | Deep-merge overrides per language key |
| attributeSourceLocation | 'data-source-location' | Attribute name the client queries |
| attributeDynamicContent | 'data-dynamic-content' | Dynamic hint attribute |
| colorHover / colorSelected / colorSubmit | purple theme | UI chrome colors (hex) |
| messageTypeDataRequest | 'visual-edit-request' | Outgoing request type / event name (top window) |
| messageTypeDataResponse | 'visual-edit-response' | Parent → iframe response type |
| messageTypeToggle | 'visual-edit-toggle' | postMessage to enable/disable |
| messageTypeLanguage | 'visual-edit-language' | postMessage { language } |
| messageTypeConfig | 'visual-edit-config' | e.g. { multiSelectSameLocation: boolean } |
| messageTypeInputControl | 'visual-edit-input-control' | e.g. { disabled: boolean } |
Runtime global: window.__VISUAL_EDIT__ exposes enable, disable, toggle, setLanguage, setMultiSelect, setInputDisabled, isEnabled, isMultiSelect, isInputDisabled, and config.
postMessageInject()
Dev-only plugin. Prepends a script that:
- Listens to
errorandunhandledrejectionand posts{ type: 'app_error', error: { title, details, componentName } }towindow.parentwhen in an iframe. - Wraps
console.errorto detect certain static import messages and forward them similarly. - Wraps
WebSocketto observe Vite HMR messages (error,full-reload, etc.) and forward structured errors.
Parent windows should validate event.origin in production embeds; the injected script uses '*' as the target origin for postMessage.
errorOverlayPlugin()
Transforms Vite’s vite/dist/client/client.mjs in dev (non-SSR) to rename the original overlay class and inject the bundled ErrorOverlay implementation so the default export name stays valid for Vite.
ErrorOverlay and errorOverlayCode
ErrorOverlay: Custom element subclass used as the patched overlay; forwards errors to the parent frame viapostMessage(type: 'app_error') when applicable.errorOverlayCode: String of class source prepared for injection intoclient.mjs(handles minified export names). Most apps only neederrorOverlayPlugin(), not direct use of this constant.
Message contracts (summary)
Visual edit (iframe → parent):
{ type: 'visual-edit-request', data: { sourceLocation, content, element, elementIndex?, dynamicContent? } }Parent should reply with { type: 'visual-edit-response', success: boolean } (type strings are configurable via plugin options).
Errors (child → parent):
{ type: 'app_error', error: { title?, details?, componentName?, originalError? } }Package contents (publish)
Published tarball includes dist/ only (main / module / exports point to ./dist/index.min.js). ESM, Node platform, with Babel packages external at bundle time (installed as dependencies).
Maintainers — build before publish:
npm run buildprepare runs npm run build on npm install in a git checkout; consumers installing from npm receive prebuilt dist.
