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
|
|
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 | ||||
|---|---|---|---|---|---|
|
An object with default values for boolean attributes Configurable attributes
Example configuration for a
slot element
|
||||
|
Area content that is passed as a property to the parent component where the
|
||||
|
|
||||
|
Function to overwrite the default behavior of
|
<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.
<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 |
|---|---|
|
required Page content response coming from Magnolia Delivery API.
An example response can be seen here. |
|
required Configuration object containing the
|
|
Template information required for the Page Editor to create the authoring UI (the green bars).
|
|
required Introduced with front-end SDK v2, the property is used to determine the page mode (edit/preview). It holds properties that support page rendering, such It replaces the previous iframe-based detection ( |
Example
<script setup lang="js">
import {
fetchPageContent,
fetchTemplateAnnotations,
} from '@/app/services/magnolia-service';
import { environment } from '@/environments/environment';
import config from '@/magnolia.config';
import { EditorContextService } from '@magnolia/frontend-helpers-base';
import { EditablePage } from '@magnolia/vue-editor';
import { onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
defineOptions({
name: 'MagnoliaPageResolver',
});
const content = ref(null);
const templateAnnotations = ref(null);
const configRef = ref(config);
const magnoliaContextRef = ref(null);
const route = useRoute();
const loadPageContent = async () => {
const languages = environment.languages;
const nodeName = environment.appBase;
const magnoliaContext = EditorContextService.getMagnoliaContext(
window.location.href,
nodeName,
languages
);
magnoliaContextRef.value = magnoliaContext;
const [contentState, templateAnnotationsState] = await Promise.allSettled([
fetchPageContent(magnoliaContext, environment.pageBase),
fetchTemplateAnnotations(
magnoliaContext,
environment.templateAnnotationsBase
),
]);
const content = contentState.value;
const templateId = content['mgnl:template'];
if (!templateId) {
return;
}
const templateAnnotations = templateAnnotationsState.value;
return {
content,
templateAnnotations,
};
};
watch(
() => route.path,
async () => {
const data = await loadPageContent();
content.value = data.content;
templateAnnotations.value = data.templateAnnotations;
}
);
onMounted(async () => {
const data = await loadPageContent();
content.value = data.content;
templateAnnotations.value = data.templateAnnotations;
});
</script>
<template>
<EditablePage
v-if="content"
:content="content"
:templateAnnotations="templateAnnotations"
:magnoliaContext="magnoliaContextRef"
:config="configRef"
/>
</template>
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 | ||
|---|---|---|---|---|
|
string |
A full request/site URL (e.g.,
|
||
|
string |
Magnolia’s root node path of the SPA website e.g. |
||
|
array of strings |
Website language(s) passed as an array of strings (e.g.,
|
magnoliaContext object
| Property | Type | Description | ||
|---|---|---|---|---|
|
boolean |
Specifies whether the request comes from Magnolia app e.g. |
||
|
boolean |
Specifies whether the request comes from Magnolia app in edit mode. |
||
|
boolean |
Specifies whether the request comes from Magnolia app in preview mode. |
||
|
string |
The version number.
|
||
|
string |
Magnolia’s node path for requested content. |
||
|
string |
The language for requested content. |
||
|
object |
Object with search parameters of the |
||
|
string |
String with search parameters of the |
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.
Issues
Content mismatches on NuxtJS
To prevent content mismatches that trigger the Hydration completed but contains mismatches. error in the console of your production environment, add the following configuration to nuxt.config.ts:
...
build: {
transpile: ["@magnolia/vue-editor", "@magnolia/template-annotations"],
},
alias: {
"@magnolia/vue-editor": "@magnolia/vue-editor/src/main.js",
"@magnolia/template-annotations":
"@magnolia/template-annotations/src/index.js",
},
...
Changelog
A list of notable changes for any given version is available on the changelog page.