Intro

Vue is rapidly becoming one of the most popular JavaScript frameworks for building user interfaces. Vue 3 can be used as the UI for a Sitecore MVC website (i.e. not headless), but a few configuration gotchas need to be addressed, and a general strategy for working with your markup needs to be implemented.

There are also some significant differences to implementing Vue 3 in a .NET application like Sitecore, as opposed to Vue 2. Let’s get started using Vue 3 with Sitecore MVC!

Getting Vue 3 set up

These steps assume you’re working with an existing Sitecore MVC implementation. If you don’t have a working instance, you can always try Vue out on one of the demo sites available in the Sitecore GitHub repositories (you will need a valid Sitecore license of course).

The first step to using Let’s get started using Sitecore MVC with Vue 3 is installing the necessary packages for Vue, including the means to compile, load, and bundle all of your Vue components. There are a lot of options here, but at a minimum you will want Vue (again, we’re focusing on Vue 3 here), a package to load Vue, load your SaSS/ CSS, and some way to compile and bundle your Vue components.

The goal here is to set up a working combination of Vue 3 within a Sitecore .NET application, so we’re going to keep it simple and only include the essentials. First, let’s add a bundler by running the following command in a terminal:

Prerequisites

The main assumption here is that you have an existing Sitecore instance. You also most likely have an existing front-end setup (and therefore already have npm/ yarn and a package.json file). If not, install node and run  npm init. Alternatively, you can use yarn by running  yarn init.

Install packages for Vue 3

Get started by installing our bundler as a dev dependency. Here I am using the most recent release of Parcel (at the time of writing, version 2.7.0). Webpack is another good option, but takes a bit more effort in the configuration department.

npm install parcel –save-dev

or

yarn add parcel –dev

Next, we want to install Vue and a few associated loaders to help us make use of JavaScript and CSS in our single file components (SFCs).

npm install vue

npm install vue-loader vue-template-compiler vue-style-loader css-loader –save-dev

or

yarn add vue

yarn add vue-loader vue-template-compiler vue-style-loader css-loader –dev

Create your component

You can begin by selecting any Sitecore rendering and extending the UI to use Vue. For this post, we’re choosing a simple example of a Sitecore rendering for a Heading with a headline and subheadline field.

Update Razor view markup

Whatever rendering you’re using to incorporate Vue and extend the UI, you will want to have an identifier (you can use a class or a tag name not already established). You will also want to use properties to pass data from the razor view to your view component.

@using Sitecore.Mvc

@model HeadingRenderingModel

<div @Html.Sxa().Component(“heading-component”, Model.Attributes)>    
@if (!String.IsNullOrWhiteSpace(Model.ErrorMessage))
    {
        <div class=”error-message”>            
@Model.ErrorMessage
        </div>    
}
    else
    {
        <!– Vue template –>        
<heading headline=”@Html.Sitecore().Field(Templates.Heading.FieldNames.Heading)”
                 subhadline=”@Html.Sitecore().Field(Templates.Heading.FieldNames.Subheadline)”
</cart-heading>
    }
</div>

Create a simple SFC vue component

Here we’re creating a Vue SFC called heading-component.vue. It contains a template that will display our Sitecore fields, some basic JavaScript to declare the properties for the Sitecore fields, and some simple CSS to style the component.

<template>
<p class=”heading__wrapper”>
<div class=”heading__headline”>{{ headline }}</div>
<div class=”heading__subheadline”>{{ subheadline }}</div>
</p>
</template>
<script>
import { ref, watch } from ‘vue’;
export default {
name: ‘Heading’,
props: {
headline: {
type: String,
dault: ”,
required: true
},
subheadline: {
type: String,
default: ”,
required: false
}
},
setup(props) {
// TODO: do some stuff if you want
}
}
</script>
<style>
.heading__wrapper {
font-family: sans-serif;
}
.heading__headline {
font-size: 2rem;
font-weight: 600;
}
.heading__subheading {
font-size: 1.125rem;
}
</style>

Wire up your Vue 3 component

Mount up

In Vue 2, when mounting an application that has a template, the rendered content replaces the element we mount to. In Vue 3, the rendered application is appended as a child of such an element, replacing the innerHTML.

To create a root and mount your component as a child to the root, you create an app.js file and add the following code.

import { createApp } from ‘vue’;
import Heading from ‘./Components/scripts/heading-component.vue’;

// Creates root Vue app and adds Heading component
createApp({
components: {
Heading
}
}).mount(‘.heading-component’);

Add an alias

The preceding setup would allow us to use Vue components in our application, but the data from Sitecore (via the razor view) would not be passed via the attributes we used (headline and subheadline) without specifying an alias. We need to take control of the imprt of Vue and force the use of the ES module. This is not well documented, but several blog posts on the web reference this required step in using Vue with a .NET MVC applciation.

Webpack has an alias property, but Parcel is “configuration-less” so it will require updating the package.json file with our alias. Interestingly, the NPM docs don’t list alias as an official property of the package.json file, but the Parcel official documentation does recommend configuring the alias this way, so it should be safe.

“alias”: {
“vue”: “vue/dist/vue.runtime.esm-bundler.js”
}

Conclusion

Adding Vue 3 has some gotchas, especially if you’re familiar with how to work with Vue 2 in the context of a Sitecore MVC website. If ou’re having trouble or running into issues, make sure you are mounting your component as a child of the root app and that you have an alias configured that your bundler can recognize.