Magnolia Vue Editor

This page describes the installation, components and functions of the Magnolia Vue Editor — a lightweight, fully-featured library connecting Vue projects with the WYSIWYG authoring experience of the Magnolia Pages app.

Magnolia Vue Editor only supports Vue 3.
For Vue 2, see the @magnolia-services/vue2-editor site.

Installation

To install the editor, open the command prompt and enter the following command.

npm install @magnolia/vue-editor
vue editor is the latest version of the Magnolia Vue Editor.

Reference

<EditableArea>

The wrapping component for areas.

The component can be used only inside the Vue components that are instantiated by EditablePage. That is, the Vue component must be in the componentMappings object supplied to the EditablePage via its config parameter.

By default, the area component loops over all of its child components.

EditableArea renders Vue components for each component node in its content. It determines which component to render based on the mgnl:template value of the node and the componentMappings supplied to the EditablePage config property. The properties of each component and areas (if any) are passed as props to the child components.

The default behavior can be changed with customView.

In the editor view of the Magnolia Pages app, it will add the annotations that are required to render the green bars with the authoring UI. The annotations are added as HTML comments.

Properties

Property Description

content

Area content that is passed as a property to the parent component where the EditableArea is used.

Example
<template>
  <div>
    <EditableArea v-if="main" v-bind:content="main" />
  </div>
</template>

<script>
import { EditableArea } from '@magnolia/vue-editor';

export default {
  name: "Home",
  components: {
    EditableArea
  },
  props: ["main"]
};
</script>

elementType

EditableArea wraps its children components in a single div element. The wrapping element can be changed by passing a new element type with elementType, which must be a valid DOM element passed as string.

Example
<EditableArea v-bind:content="main" />
/*
<div>
  ...children
</div>
*/

<EditableArea v-bind:content="main" v-bind:elementType='ul' />
/*
<ul>
  ...children
</ul>
*/

customView

Function to overwrite the default behavior of EditableArea.

customView receives one variable with all area data passed as a content property.

Examples
<template>
  <div>
    <EditableArea v-if="main" v-bind:content="main" v-bind:customView="customView" />
  </div>
</template>

<script>
import { EditableArea } from '@magnolia/vue-editor';

export default {
  name: "Home",
  components: {
    EditableArea
  },
  props: ["main"]
};
</script>
<template>
  <div>
    <EditableComponent v-for="childContent in components" v-bind:key="childContent['@id']" v-bind:content="childContent" />
  </div>
</template>

<script>
import { EditableComponent } from '@magnolia/vue-editor';

export default {
  name: 'customView',
  props: ['content'],
  components: { EditableComponent },
  computed: {
    components() {
      return this.content ? this.content['@nodes'].map(nodeName => this.content[nodeName]) : [];
    }
  }
}
</script>

<EditableComponent>

The wrapping component for components.

EditableComponent component can only be used inside the customView of the EditableArea.

The component determines which Vue component to render based on the mgnl:template value of the content and the componentMappings supplied to the EditablePage config property. Component dialog properties and areas are passed to the component as props.

Properties

Property Description

content

Component content that is passed as part of area content.

<EditablePage>

The wrapping component for Magnolia-managed page content.

It determines which Vue component to render based on the mgnl:template value of the content and the componentMappings supplied to the EditablePage config property. Page dialog properties and areas are passed to the component as props.

In the editor view of the Pages app, it will add the annotations that are required to render the green bars with the authoring UI. The annotations are added as HTML comments.

Properties

Property Description

content

Page content response coming from Magnolia Delivery API.

Example endpoint definition
$type: jcrDeliveryEndpoint_v2
workspace: website
limit: 100
systemProperties:
  - mgnl:template
depth: 10
nodeTypes:
  - mgnl:page
childNodeTypes:
  - mgnl:area
  - mgnl:component

An example response can be seen here.

config

Configuration object containing the componentMappings object with mappings between the mgnl:template values and Vue components.

Example
import Home from './pages/Home.vue'

const config = {
  componentMappings: {
    'spa:pages/Home': Home,
  },
};

templateAnnotations

Template information required for the Page Editor to create the authoring UI (the green bars). templateAnnotations are fetched from

<MAGNOLIA_INSTANCE>/.rest/template-annotations/v1/<PAGE_PATH>
Example
https://demo.magnolia-cms.com/.rest/template-annotations/v1/travel

Example

<template>
  <EditablePage
    v-if="page"
    v-bind:content="page"
    v-bind:config="config"
    v-bind:templateAnnotations="templateAnnotations"
  />
</template>

<script>
import { EditablePage, EditorContextHelper } from "@magnolia/vue-editor";
import Home from './pages/Home.vue'

const config = {
  componentMappings: {
    'spa:pages/Home': Home,
  },
};

export default {
  name: 'App',
  components: {
    EditablePage
  },
  data() {
    return {
      page: null,
      templateAnnotations: {},
      config,
    };
  },
  async mounted() {
    const pageRes = await fetch('http://localhost:8080/magnoliaAuthor/.rest/pages/spa-home');
    const page = await pageRes.json();

    if (EditorContextHelper.inIframe()) {
      const templateAnnotationsRes = await fetch(
        'http://localhost:8080/magnoliaAuthor/.rest/template-annotations/v1/spa-home'
      );
      const templateAnnotations = await templateAnnotationsRes.json();

      this.templateAnnotations = templateAnnotations;
    }

    this.page = page;
  }
}
</script>

EditorContextHelper.inIframe

Using EditorContextHelper.getMagnoliaContext is the recommended approach.

global.mgnlInPageEditor is deprecated and not necessary.

EditorContextHelper.getMagnoliaContext

A function that returns the magnoliaContext object.

This function requires 3 parameters:

Property Type Description

requestUrl

string

A full request/site URL (e.g., https://foo.bar or https://foo.bar?mgnlPreview=false&mgnlChannel=desktop).

For example, in a browser, it can be read with window.location.href. For other frameworks use the framework’s specific way of getting full URL.

spaRootNodePath

string

Magnolia’s root node path of the SPA website e.g. /foo or /foo/bar.

languages

array of strings

Website language(s) passed as an array of strings (e.g., ['en', 'de']).

The first language in the array is the default locale.

magnoliaContext object

Property Type Description

isMagnolia

boolean

Specifies whether the request comes from Magnolia app e.g. Pages app.

isMagnoliaEdit

boolean

Specifies whether the request comes from Magnolia app in edit mode.

isMagnoliaPreview

boolean

Specifies whether the request comes from Magnolia app in preview mode.

version

string

The version number.

This is only present if the request comes from the Magnolia app for a specific version.

nodePath

string

Magnolia’s node path for requested content.

currentLanguage

string

The language for requested content.

searchParams

object

Object with search parameters of the requestUrl enriched with Magnolia’s specific parameters.

search

string

String with search parameters of the requestUrl enriched with Magnolia’s specific parameters.

Example

import { EditorContextHelper } from '@magnolia/vue-editor';

const requestUrl = 'https://foo.bar/travel/?mgnlPreview=false&mgnlChannel=desktop';
const spaRootNodePath = '/home';
const languages = ['en', 'de'];
const magnoliaContext = EditorContextHelper.getMagnoliaContext(requestUrl, spaRootNodePath, languages);

/*
magnoliaContext = {
  isMagnolia: true,
  isMagnoliaEdit: true,
  isMagnoliaPreview: false,
  nodePath: /home/travel,
  currentLanguage: 'en',
  searchParams: { mgnlChannel: 'desktop', mgnlPreview: 'false', variants: 'all' },
  search: '?mgnlPreview=false&mgnlChannel=desktop&variants=all&lang=en'
}
*/

// Fetch page content
const pagesRes = await fetch(PAGES_API + magnoliaContext.nodePath + magnoliaContext.search);

// Fetch template annotations
if (magnoliaContext.isMagnolia) {
  const templateAnnotationsRes = await fetch(TEMPLATE_ANNOTATIONS_API + magnoliaContext.nodePath);
}
When using this function to determine isMagnolia* properties, such as isMagnolia being true, be sure to add magnoliaContext search parameters to all links, so that it ensures the correct behavior when navigating the website inside Magnolia’s app e.g. Pages app.

Demo

For headless SPA demos showcasing the Magnolia Vue Editor, see minimal-headless-spa-demos.

Changelog

A list of notable changes for any given version is available on the changelog page.

Feedback

Headless

×

Location

This widget lets you know where you are on the docs site.

You are currently perusing through the Headless docs.

Main doc sections

DX Core Headless PaaS Legacy Cloud Incubator modules