Vue.js Whitelabel Tutorial

Building a Vue.js whitelabel solution

This blog post was written by and published 8th July 2018.

vue.js whitelabel app structure

Structure of my finished whitelabel vue.js solution

This tutorial goes through setting up a whitelabel vue.js app from scratch but it should also help if you need to add whitelabel functionality to an existing vue project.


My setup:
Macbook using Visual Studio Code
node 8.11.3
npm 6.1.0
vue 2.5.16
vue-cli 3.0.0-rc.3

If you’re using v2 of the Vue Cli, there will be slight differences in how you setup/edit your project. I’ve detailed these with the [v2] tag and at the bottom of the page.

1. Getting setup

Using the Vue CLI (v3) I’m going to create my new project with the default options:

vue create vue-whitelabel

Vue CLI will generate your project, once completed open the folder and make sure your console is scoped to your ‘vue-whitelabel’ folder.

Install SCSS compiler

We’ll use SCSS variables to generate our different whitelabel styles so we need to install scss-loader and node-sass:

npm install sass-loader --save-dev && npm install node-sass --save-dev

Install cross-env

[v2] this may already be installed for vue-cli 2 users.

We’re going to use cross-env to set whitelabel variables through the package.json script commands.

npm install cross-env --save-dev

Create a whitelabel config file to store specific variables

You can store any specific settings or variables in this file, this is good for brand/site related settings such as brand name, logo url, contact information etc later we’ll pull these values into a vue component.

The whitelabel.config.js file I’m using for this demo:

// whitelabel.config.js
const whitelabelConfig = {
    'light': {
        'brand': 'Light Theme',
        'scssVariables': '../src/styles/whitelabel-variables/light',
        'homeURL': 'https://www.example.com/light',
        'logoURL': '/img/logo.82b9c7a5.png',
        'contactEmail':  'light@example.co.uk',
    },
    'dark': {
        'brand': 'Dark Theme',
        'scssVariables': '../src/styles/whitelabel-variables/dark',
        'homeURL': 'https://www.example.com/dark',
        'logoURL': '/img/logo.82b9c7a5.png',
        'contactEmail':  'dark@example.co.uk',
    }
}
 
module.exports = whitelabelConfig

2. Updating package.json scripts

[v2] the Vue CLI scripts are a bit different in v2 of the CLI, please see the guide to v2 package.json scripts

Im going to create two different whitelabel versions, a light version and a dark version. I’ll do this using a new environment variable named VUE_APP_BRAND* which will control the webpack build output.

*Vue CLI 3+ users need to prefix the variable name with VUE_APP_, I was initially caught out by this.
[v2] vue cli 2 users don’t need to prefix the variable name as above – though you’d be future proofing by doing so.

I’ve updated the package.json file to include two new whitelabel version specific ‘serve’ scripts, add these for each whitelabel variant you’re working with.

I also updated the default ‘serve’ script to run the ‘light’ version as a default.

"scripts": {
    "serve": "npm run serve-light",
    "serve-light": "cross-env process.env.VUE_APP_BRAND='light' vue-cli-service serve",
    "serve-dark": "cross-env process.env.VUE_APP_BRAND='dark' vue-cli-service serve",
    "build": "npm run build",
    "lint": "vue-cli-service lint"
},

Note: I’ll edit the build script in the final steps, to output my final whitelabel variants. If you run the build script before this then you’ll get an error because it’s not setting the VUE_APP_BRAND variable.

3. Compiling variant specific SCSS

[v2] with Vue CLI v2 you’ll need to update the webpack.base.conf.js file – instead of using a vue.config.js file to include your whitelabel.config import and alias configuration. Skip to editing webpack.base.conf.js file

Because I’m using v3 of the Vue CLI I need to add a vue.config.js file in order to manipulate my webpack build.

I had to install the path npm package to correctly resolve the file path, you can do this by installing via npm:

npm install path --save

After including the path package I include my whitelabel.config.js file which contains all the settings/variables for the whitelabel solution.

Include whitelabel config and create webpack alias

// include whitelabel config
const whitelabelConfig = require('./whitelabel.config')

I’ll use the VUE_APP_BRAND variable which I set in my package.json script to get the active whitelabel varient’s SCSS variables file path.

// get whitelabel variant variables folder path
const brandVariablesPath = whitelabelConfig[process.env.VUE_APP_BRAND].scssVariables

And then use this to create an alias which I can use in my main stylesheet to import the variant’s variables.scss file.

resolve: {
        alias: {
            // create alias for whitelabel SCSS variable files
            'brandVariables': path.resolve(__dirname, brandVariablesPath),
        }
}

You could also create an alias to specify an image folder path, if you have the same named images for each whitelabel variant.

Using the webpack alias in my core.scss stylesheet

This is my core.scss which will pull the correct variables.scss file for the variant im using and output the compiled styles. Notice ~brandVariables, the ‘~’ tells webpack this is an alias and it will resolve to the correct folder path.

// core.scss
// using alias to get either 'light' or 'dark' varient folder path
@import '~brandVariables/variables.scss';

body {
    background: $page-bg;
    color: $text-color;
}

a {
    color: $link-color;
}

My variant specific variables.scss files:
vue whitelabel scss variables

My core.scss import in main.js
vue importing scss code

My full vue.config.js file:

// vue.config.js
// include path to resolve file path
const path = require('path')

// include whitelabel config
const whitelabelConfig = require('./whitelabel.config')

// check which brand config to use for SCSS Variables
const brandVariablesPath = whitelabelConfig[process.env.VUE_APP_BRAND].scssVariables

// set webpack configuration
module.exports = {
    configureWebpack: {
      resolve: {
        alias: {
            // create alias for whitelabel SCSS variable files
            'brandVariables': path.resolve(__dirname, brandVariablesPath),
        }
      }
    }
}

Now I can run either npm run serve-light or npm run serve-dark and webpack will build the solution using the relevant SCSS variables and style the app using either the light or dark theme.

Next ill pull the whitelabel variables from the config file we setup earlier.

4. Using whitelabel variables within Vue templates

Open a vue component file and import the whitelabel.config.js file. Include the process.env.VUE_APP_BRAND environment variable to only pull the specific whitelabel variant variables from the file.

const whitelabel = require('../../whitelabel.config')[process.env.VUE_APP_BRAND] 

The variant variables are now available through the whitelabel object, and can set Vue component data as below:

data() {
    return {
      // set the brand variable
      brand: whitelabel.brand,
      homeURL: whitelabel.homeURL,
      logoURL: whitelabel.logoURL,
      email: whitelabel.contactEmail
    }
},

5. Whitelabeling the router base url

If you’re vue app is using a router and you’re planning on using your whitelabel solution on different base URLs e.g:
‘light’ variant is shown on url example.com/vue-app-light
‘dark’ variant is shown on url example.com/vue-app-dark
you’ll need to specify the base URL setting in your src/router/index.js:

// /router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'

Vue.use(Router)

// check to see if the 'baseURL' variable is set
var defaultBase
try { defaultBase = baseURL }
catch(e) {
  // if baseURL is undefined set a default
  // default to vue-app-light variant url
  defaultBase = '/vue-app-light'
}
console.log('vue base url:', defaultBase)

export default new Router({
  mode: 'history',
  base: defaultBase, // we set the app's base url here
  routes: [
    {
      path: '/',
      name: 'helloworld',
      component: HelloWorld
    }
  ]
})

You can then set the baseURL js variable just above where you’re loading your app’s JavaScript files.

<script>
  // specify the base url for the 'dark' variant
  var baseURL = "/vue-app-dark"
</script>
<script type=text/javascript src="/manifest.[hash].js"></script>
<script type=text/javascript src="/vendor.[hash].js"></script>
<script type=text/javascript src="/app.[hash].js"></script>

6. Update the whitelabel build output

Im going to adjust the build scripts and output to work with my whitelabel solution.

Update build scripts and output

[v2] the CLI scripts are slightly different in v2, you can see the guide to v2 package.json scripts below

Like I did earlier with the ‘serve’ scripts, I’ve added a new build script to the package.json file for each whitelabel variant. These will create production-ready versions of the whitelabel variant. I’ve updated the default ‘build’ script to run both of my whitelabel varients.

Aswell as setting the VUE_APP_BRAND variable I’m also specifying the output destination for each using Vue CLI’s --dest dist/variant option.

"scripts": {
    "serve": "npm run serve-light",
    "serve-light": "cross-env process.env.VUE_APP_BRAND='light' vue-cli-service serve",
    "serve-dark": "cross-env process.env.VUE_APP_BRAND='dark' vue-cli-service serve",
    "build": "npm run build-light && npm run build-dark",
    "build-light": "cross-env process.env.VUE_APP_BRAND='light' vue-cli-service build --dest dist/light",
    "build-dark": "cross-env process.env.VUE_APP_BRAND='dark' vue-cli-service build --dest dist/dark",
    "lint": "vue-cli-service lint"
},

Whitelabel Vue.js OutputNow if I run npm run build my script will produce a production-ready output for each of my two variants.

Each output folder will contain of all the JS and specific stylesheets for the whitelabel variant.

Conclusion

A basic vue.js whitelabel solution. I’ve simplified this tutorial but have used this method for a small production application. This may not be the best way to whitelabel your vue app, but it will work, if you have any suggestions let me know.

Vue Whitelabel source code

You can download the source code for my solution through BitBucket

Vue CLI v2 differences

[v2] Setting up package.json scripts

Vue CLI v3+ uses a new set of script commands and the old scripts are slightly different.

// Vue CLI v2 default package.json scripts for 'dev' and 'build
"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "build": "node build/build.js",
}
// Vue CLI v3 default package.json scripts for 'dev' and 'build
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "npm run build",
}

Like I did for my v3 scripts I’m adding commands to set the environment variable for each variant’s ‘dev’ and ‘build’ scripts. This will pass the variant name to my config files and .vue template files. I can use these scripts to test my whitelabel variations and build production-ready versions of each whitelabel variant.

"scripts": {
    "dev-light": "cross-env process.env.VUE_APP_BRAND='\"light\"' webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "dev-dark": "cross-env process.env.VUE_APP_BRAND='\"dark\"' webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "build-light": "cross-env process.env.VUE_APP_BRAND='\"light\"' node build/build.js",
    "build-dark": "cross-env process.env.VUE_APP_BRAND='\"dark\"' node build/build.js"
}

[v2] Setting up whitelabel alias in webpack.base.config.js

Vue CLI v3+ uses a zero config setup so you have to add a special vue.config.js file to manipulate the webpack build. With v2 you can directly edit your webpack config, you should look for the webpack.base.config.js file which is located inside src/build folder.

Include the whitelabel config file and set the brandVariablesPath variable.

// include whitelabel config
const whitelabelConfig = require('./whitelabel.config')

// get whitelabel variant variables folder path
const brandVariablesPath = whitelabelConfig[process.env.VUE_APP_BRAND].scssVariables

Add brandVariables alias to the resolve section, like:

resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
    /* 
      vue defaults here - dont remove these 
    */
    // this is the line you'll need to add
    'brandVariables': path.resolve(__dirname, brandVariablesPath),
  }
},