Official Vue 3 adapter for SightEdit visual editing system.
npm install @sightedit/core @sightedit/vue// main.js
import { createApp } from 'vue';
import { SightEditPlugin } from '@sightedit/vue';
import App from './App.vue';
const app = createApp(App);
app.use(SightEditPlugin, {
endpoint: '/api/sightedit',
debug: true
});
app.mount('#app');Then use in components:
<template>
<div>
<Editable sight="hero.title" type="text">
<h1>Welcome to SightEdit</h1>
</Editable>
<Editable sight="hero.description" type="richtext">
<p>Edit this content visually!</p>
</Editable>
</div>
</template>
<script>
import { Editable } from '@sightedit/vue';
export default {
components: { Editable }
};
</script><template>
<SightEditProvider :config="sightEditConfig">
<div class="app">
<Editable sight="hero.title" type="text">
<h1>Welcome to SightEdit</h1>
</Editable>
</div>
</SightEditProvider>
</template>
<script>
import { SightEditProvider, Editable } from '@sightedit/vue';
export default {
components: { SightEditProvider, Editable },
data() {
return {
sightEditConfig: {
endpoint: '/api/sightedit',
debug: true
}
};
}
};
</script>Makes any content editable:
<template>
<Editable
sight="product.name"
type="text"
placeholder="Enter product name"
:required="true"
:max-length="100"
@change="handleChange"
>
<h2>{{ productName }}</h2>
</Editable>
</template>
<script setup>
import { ref } from 'vue';
import { Editable } from '@sightedit/vue';
const productName = ref('Product Name');
const handleChange = (value) => {
console.log('Content changed:', value);
};
</script>Props:
sight(required): Unique identifier for the contenttype: Editor type (text, richtext, image, link, etc.)tag: HTML tag to render (default: 'div')placeholder: Placeholder textrequired: Make field requiredmin-length/max-length: Text length constraintsmin/max: Number constraintsoptions: Options for select typevalidation: Custom validation function
Events:
@change: Emitted when content changes
Button to toggle edit mode:
<template>
<EditModeToggle>
<template #default>
{{ isEditMode ? 'Exit Edit' : 'Enter Edit' }}
</template>
</EditModeToggle>
</template>
<script setup>
import { EditModeToggle, useEditMode } from '@sightedit/vue';
const { isEditMode } = useEditMode();
</script>Access the SightEdit instance and state:
<script setup>
import { useSightEdit } from '@sightedit/vue';
const { state, toggleEditMode, save } = useSightEdit();
// Access state
console.log(state.isEditMode);
console.log(state.instance);
// Toggle edit mode
const handleToggle = () => {
toggleEditMode();
};
// Save custom data
const saveCustomData = async () => {
await save('custom.data', { foo: 'bar' });
};
</script>Just get edit mode state:
<script setup>
import { useEditMode } from '@sightedit/vue';
const { isEditMode, toggleEditMode } = useEditMode();
</script>
<template>
<header>
<span v-if="isEditMode">Editing...</span>
<button @click="toggleEditMode">
{{ isEditMode ? 'Exit' : 'Edit' }}
</button>
</header>
</template>Get the save function:
<script setup>
import { useSightEditSave } from '@sightedit/vue';
const save = useSightEditSave();
const handleSave = async () => {
await save('settings.theme', '#667eea');
};
</script>If using global plugin:
<template>
<div>
<p>Edit mode: {{ $sightEdit.state.isEditMode ? 'ON' : 'OFF' }}</p>
<button @click="$sightEdit.toggleEditMode()">Toggle</button>
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$sightEdit.state.instance);
}
};
</script><script setup lang="ts">
import { Editable } from '@sightedit/vue';
import type { SightEditConfig } from '@sightedit/vue';
const config: SightEditConfig = {
endpoint: '/api/sightedit',
auth: {
type: 'bearer',
token: 'your-token'
}
};
const handleChange = (value: any) => {
console.log('Changed:', value);
};
</script><template>
<Editable sight="features" type="collection">
<div class="features-grid">
<div v-for="i in 3" :key="i" :data-sight-item="i">
<h3 :data-sight="`title`">Feature {{ i }}</h3>
<p :data-sight="`description`">Description {{ i }}</p>
</div>
</div>
</Editable>
</template><template>
<Editable
sight="settings.theme"
type="color"
@change="updateTheme"
>
<div class="color-display" :style="{ backgroundColor: themeColor }">
Theme Color: {{ themeColor }}
</div>
</Editable>
</template>
<script setup>
import { ref } from 'vue';
import { Editable } from '@sightedit/vue';
const themeColor = ref('#667eea');
const updateTheme = (color) => {
themeColor.value = color;
document.body.style.backgroundColor = color;
};
</script>// main.js
app.use(SightEditPlugin, {
endpoint: '/api/sightedit',
auth: {
type: 'bearer',
getToken: async () => {
const token = await fetchAuthToken();
return token;
}
}
});// plugins/sightedit.client.js
import { SightEditPlugin } from '@sightedit/vue';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(SightEditPlugin, {
endpoint: '/api/sightedit',
mode: process.env.NODE_ENV === 'development' ? 'development' : 'production'
});
});app.use(SightEditPlugin, {
endpoint: '/api/sightedit',
onError: (error) => {
console.error('SightEdit error:', error);
// Show notification
toast.error('Failed to save changes');
}
});SightEdit automatically detects new editable elements:
<template>
<div>
<button @click="addItem">Add Item</button>
<div v-for="item in items" :key="item.id">
<Editable :sight="`item.${item.id}.name`" type="text">
<h3>{{ item.name }}</h3>
</Editable>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { Editable } from '@sightedit/vue';
const items = ref([
{ id: 1, name: 'Item 1' }
]);
const addItem = () => {
items.value.push({
id: Date.now(),
name: `Item ${items.value.length + 1}`
});
};
</script>