Building SPA module inside Sitecore

Building SPA module inside Sitecore

How to use Vue.js in Sitecore

One of the abilities of Vue is being progressive. It means you might only introduce Vue.js core library or using full functionality of vue.js using Vue CLI.

In the recent Sitecore project that I was designing the Frontend side of it, initially I introduced the core library of vue.js for the search page by using Vue directly inside MVC razor code.
Then based on the requirement, I needed to run a few pages in the Sitecore as a SPA app. However, since not everyone has sitecore on their machine to develope, I was asked to come up with a solution to build a standalone app with the ability to be embeded in SItecore. (With SItecore 9 you wouldnot have any problem but we used version 8.2)
I came up with a solution to build a standalone SPA vue.js app and bring it to the sitecore as a web library which I am elaborating it in the next section.

Exporting Vue.js as a library into Sitecore

Step1 : Build your Vue.js app with Vue CLI

build your vue with vue cli and design your app pretending you don't have any Sitecore integration :)
You can easily use the VueX (state manager) and Router and any styling framework like Vuetify or bootstrap inside your app.

you need a content editable app?

In some cases you need yourvue.js app to be content editable so for that scenario, you need to build a template for the labels and images and all other content editable texts to be used inside the Vue.js App and expose a Sitecore API to make them available to the Vue.js app.

Step 2:

Register your components in Vue to be accessible as a library.

import Vue from "vue";
import app from "../App.vue";

Vue.component("app", app);

export default {
  app
  }

Edit tool-vue-lib

Step 3: Tweak your package.json file

You need to tell your Vue.js app to be acting like a library instead of a web app. so you need these changes in your package.json file:

 {
  "name": "tool-vue-lib",
  "version": "1.0.1",
  "private": false,
  "author": "Nelly Sattari",
  "main": "./dist/tool-vue-lib.common.js",
  "files": [
    "dist/*",
    "src/*",
    "public/*",
    "*.json",
    "*.js"
  ],
  "scripts": {
    "build-lib": "vue-cli-service build --target lib --name tool-vue-lib ./src/components/index.js",
     
  },
  ...
}

Then you need to run :

npm run build-lib

You will see some JS/CSS files with umd and common.js format will be built inside your dist folder. also This folder can be browsed by using any http-server app.
I installed http-server to view the app. See if you have any otherwise install one app.

Code is here :
Edit tool-vue-lib

Step 4: build a private npm repository

Publish your app in npmjs or in some private repository of your organization. I used Verdaccio for publishing the Vue.js app

publishing the client app to a private repository with @scope namespace

  • Add a @scope name to your package.json file in the client app

  "name": "@yourcompany/tool-vue-lib",
  

register your app into the private repository:

npm login --registry=https://yourserver:4443 --scope=@yourCompany
npm config set @yourCompany:registry https://yourserver:4443  
npm publish (This step should happen inside the app folder which is meant to be published) 

refer to npm doc

You might get an error on the publish contains of this error which means you need to increase the version in your package file to publish a new version of your app.

npm ERR! registry error parsing json
npm ERR! code EPUBLISHCONFLICT
npm ERR! publish fail Cannot publish over existing version.
npm ERR! publish fail Update the 'version' field in package.json and try again.
npm ERR! publish fail
npm ERR! publish fail To automatically increment version numbers, see:
npm ERR! publish fail     npm help version 

If you have not done it before refer to npmjs to add your user/pass and publish your app.

Step 5: Sitecore integration

This is an important step that you need to install your Vue.js app into your Sitecore as a normal npm library.
If you used a private npm repository to publish your vue.js app then make sure you install it in Sitecore from right path.

You need to add the @scope to tyour registry otherwise it will pick it from the npm public repository. To avoid manual change to the npm config, you can add .npmrc file to the root of project just beside the package.json and add the following config:

@yourCompany:registry=https://yourserver:4443
strict-ssl=false

Get the latest version the client app in sitecore

"devDependencies": {
   "@yourCompany/ClientApp": "latest",
}

Render the client app in sitecore

Depend on the requirement you can build a layout specific for the tool and drop the JS and Styles into that.
You need a Div with the id you used in your client app:

<div id="appCLient">
    <app></app>
</div>

and a Javascript file with this spec:

import Vue from "vue";
import { app } from '@yourCompany/ClientApp';

$(document).ready(() => {

    new Vue({
        el: '#appCLient',
        components: { app },
        router: app.router,
        store: app.store
    });

});

In case you used Vuetify as a styling framework in VUe.js

Inside the feature you need to import the pollyfill for the sake of Vuetify to be rendered in IE.
If your Webpack has an entry file then you need to import the babel polyfill to that file. If not and if you take the list of JS files from an array then you need to inject it to one of your Js files and push that file to the begining of the Array.

import '@babel/polyfill';
import Vue from "vue";
import { app } from '@yourCompany/tool-vue-lib';

$(document).ready(() => {

    new Vue({
        el: '#app',
        components: { app },
        router: app.router,
        store: app.store
    });

});

OR

     allScriptArrays.unshift(path.join(__dirname, '..', '..', '..', 'Feature', 'Tools', 'code', 'scripts', 'index.js*'));