Building a Vue.js whitelabel solution

[caption id="attachment_1827" align="alignright" width="220"] Structure of my finished whitelabel vue.js solution[/caption]
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.1
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:
My core.scss import in main.js
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"
},
Now 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),
}
},