5 min read

Live Preview Component

Live Preview and Visual Editor is a powerful component for integrating Directus with your website and giving users a meaningful view of the data.
Live Preview Component

The live-preview component provides an interactive, resizable preview interface with support for visual editing, zoom controls, and multiple URL management.

Key Features

  • Responsive iframe Display - Renders and manages iframe content with dynamic sizing
  • Zoom & Resize Controls - Built-in zoom levels (25% to 200%) and manual dimension adjustment
  • Multiple URL Support - Switch between different preview URLs with a dropdown menu
  • Visual Editing Integration - Toggle editable elements and open URLs in the visual editor
  • Dynamic URL Handling - Support for dynamically generated preview URLs
  • Sidebar Support - Optional resizable sidebar for additional content
  • Fullscreen Mode - Toggle between fixed dimensions and fullscreen preview
  • Accessibility - Includes proper ARIA labels and keyboard navigation

Composition API

Props

PropTypeDescription
urlstring | string[]Required, Single URL or array of URLs to preview
dynamicUrlstringOptional, Dynamically generated URL
dynamicDisplaystringOptional, Text to display instead of actual URL
invalidUrlbooleanOptional, Mark URL as invalid
urlDisplaystringOptional, Custom URL text display
singleUrlSubduedbooleanOptional, Subdue single URL display (default: true)
headerExpandedbooleanOptional, Expand header for more space
hideRefreshButtonbooleanOptional, Hide the refresh button
hidePopupButtonbooleanOptional, Hide the new window button
inPopupbooleanOptional, Display as popup window
centeredbooleanOptional, Center content
isFullWidthbooleanOptional, Full width mode flag
canEnableVisualEditingbooleanOptional, Enable visual editor option
versionContentVersion, 'key' | 'name'Optional, Content version
showOpenInVisualEditorbooleanOptional, Show visual editor option (default: true)
defaultShowEditableElementsbooleanOptional, Show editable elements by default
sidebarSizenumberOptional, Sidebar width in pixels
sidebarCollapsedbooleanOptional, Sidebar collapsed state (default: true)
sidebarDisabledbooleanOptional, Disable sidebar

Emits

EmitPropertiesDescription
new-windowvoidUser clicked open in new window
selectUrlnewUrl, oldUrlUser switched between URLs
saved{ collection, primaryKey }Content saved via visual editor
exit-full-widthvoidUser exited full width mode
update:sidebarSizesize: numberSidebar resized
update:sidebarCollapsedcollapsed: booleanSidebar toggled

Slots

SlotDescription
#display-optionsAdditional display options in header
#sidebarSidebar content
#notificationsNotification content
#prepend-headerContent before header buttons
#append-headerContent after header buttons
#append-urlContent after URL display
#overlay="{ frameEl, frameSrc }"Custom overlay elements

Usage Example

Here's how to use the component in your component:

<script setup lang="ts">
import { ref } from 'vue';
import type { ContentVersion } from '@directus/types';

// Simple single URL preview
const previewUrl = ref('https://example.com');

// Multiple URLs for switching
const previewUrls = ref([
  'https://example.com',
  'https://example.com/about',
  'https://example.com/contact'
]);

// Dynamic URL generation
const dynamicUrl = ref('https://api.example.com/preview/v1');
const dynamicDisplay = ref('Dynamic Preview');

// Version tracking for visual editor
const currentVersion = ref<Pick<ContentVersion, 'key' | 'name'> | null>({
  key: 'v1-draft',
  name: 'Draft Version'
});

// Sidebar state management
const sidebarSize = ref(333);
const sidebarCollapsed = ref(true);

// Handle URL selection changes
const handleSelectUrl = (newUrl: string, oldUrl: string) => {
  console.log(`Switched from ${oldUrl} to ${newUrl}`);
};

// Handle saved content from visual editor
const handleSaved = (data: { collection: string; primaryKey: string | number }) => {
  console.log(`Saved to ${data.collection}:${data.primaryKey}`);
};

// Handle sidebar resize
const handleSidebarResize = (size: number) => {
  sidebarSize.value = size;
};
</script>

<template>
  <!-- Simple single URL preview -->
  <live-preview
    :url="previewUrl"
    @select-url="handleSelectUrl"
  />

  <!-- Multiple URLs with sidebar -->
  <live-preview
    :url="previewUrls"
    :sidebar-size="sidebarSize"
    :sidebar-collapsed="sidebarCollapsed"
    @select-url="handleSelectUrl"
    @update:sidebar-size="handleSidebarResize"
    @update:sidebar-collapsed="(collapsed) => sidebarCollapsed = collapsed"
  >
    <!-- Additional display options in header -->
    <template #display-options>
      <!-- Custom display options here -->
    </template>

    <!-- Sidebar content -->
    <template #sidebar>
      <div class="sidebar-content">
        <!-- Your sidebar content -->
      </div>
    </template>

    <!-- Notifications area -->
    <template #notifications>
      <!-- Your notifications here -->
    </template>
  </live-preview>

  <!-- Advanced: With visual editing and dynamic URLs -->
  <live-preview
    :url="previewUrls"
    :dynamic-url="dynamicUrl"
    :dynamic-display="dynamicDisplay"
    :version="currentVersion"
    :can-enable-visual-editing="true"
    :default-show-editable-elements="false"
    @select-url="handleSelectUrl"
    @saved="handleSaved"
  >
    <!-- Custom overlay for the iframe -->
    <template #overlay="{ frameEl, frameSrc }">
      <!-- Custom overlay elements -->
    </template>

    <!-- Header customization -->
    <template #prepend-header>
      <!-- Content before header buttons -->
    </template>

    <template #append-header>
      <!-- Content after header buttons -->
    </template>

    <template #append-url>
      <!-- Content after URL display -->
    </template>
  </live-preview>
</template>

Advanced Features Explained

1. Zoom Controls

The component provides preset zoom levels (25%, 50%, 75%, 100%, 150%, 200%) that automatically adjust the iframe scale. Zoom is disabled in fullscreen mode.

// The zoom state is managed internally, but you can observe it
// through the displayed dimensions
const displayWidth = ref(1200);  // Actual rendered width
const displayHeight = ref(800);  // Actual rendered height

2. Visual Editing Integration

When enabled, the component integrates with Directus's visual editor:

const canEnableVisualEditing = true;
const version = {
  key: 'content-version-key',
  name: 'Version Name'
};

// Listen for saves from the visual editor
@saved="handleSaved"

3. Dynamic URLs

The component can maintain both static and dynamic URLs:

const staticUrls = ['https://example.com', 'https://example.com/about'];
const dynamicUrl = 'https://api.example.com/preview'; // Generated dynamically
// The dynamic URL will appear in the dropdown if different from static URLs

4. Sidebar Management

The sidebar uses a split panel for resizable content:

const sidebarSize = ref(333);        // Default width in pixels
const sidebarCollapsed = ref(true);  // Collapsed state

// Snap points: component snaps at 333px width
// Min size: 252px
// Max size: 540px

Internal Methods & State

The component provides a global window.refreshLivePreview() method that can refresh the iframe:

// Refresh with current URL
window.refreshLivePreview(null);

// Refresh with specific URL
window.refreshLivePreview('https://example.com/new-path');

Styling Customization

The component uses CSS custom properties for theming:

--preview--color: Navigation button foreground color
--preview--color-disabled: Disabled state color
--preview--header--background-color: Header background
--preview--header--border-color: Header border
--preview--header--height: Header height (2.5rem or 3.375rem expanded)

Accessibility Features

  • ARIA labels on all buttons (v-tooltip directives)
  • Proper button states (aria-pressed)
  • Semantic HTML structure
  • Keyboard-navigable controls
  • Iframe has appropriate title attribute

Performance Considerations

  • Uses ResizeObserver for responsive dimension tracking
  • Efficient watchers with lazy initialization
  • Computed properties for derived state
  • Event-based updates to parent components

Wrapping Up

Live Preview and Visual Editor is a powerful component for integrating Directus with your website and giving users a meaningful view of the data. Make sure to set up your website to fetch content from Directus.

Live Preview | Directus Docs
Explore our resources and powerful data engine to build your projects confidently.
Frontend Library | Directus Docs
Explore our resources and powerful data engine to build your projects confidently.
Send me a coffee