When you are developing a multitenant application, all your tenants (customers) want their design or color coding (theme) to match their brand standards. First, you have to come up with a unique design or layout for your web app which can be neutral and can be customizable to any design easily. By reading this requirement, of course, you get Bootstrap in your mind. By using Bootstrap you can easily make your web app design very flexible and responsive. We all know benefits of using Bootstrap. If you don't then go to Getbootstrap.com and get it.

Bootstrap can be a base for responsive web applications. You need to create custom CSS by overriding existing Bootstrap classes. You can also make your customization of Bootstrap common for all tenants by using the .less provided by Bootstrap instead of directly using .css.

I have added my example of designing multitenant web applications design using Bootstrap.

For our implementation (our example), we considered bootstrap V3.3.7 as there still may be a learning curve for understanding the new version of the framework. I think using new the version of  Bootstrap could bring a little bit of risk to a team. You can use a new version of Bootstrap and apply the same strategy for handling multi-tenant web design customization. We have used ASP.NET MVC Core using Visual Studio.

The implementation of custom designs has to follow the following steps.

1. Installation

Install the basic Bootstrap with .less files. You can download Bootstrap .less files from the following URL. https://getbootstrap.com/docs/3.3/getting-started/

Also, you can implement packages like npm or nuget.

In this post, we'll also describe how to install grunt and grunt commands.

2. Define Your Own Customization on Top of Bootstrap Using Your Own .less Files

As per the ASP.NET Core MVC project folder structure, I have added the Bootstrap .less files under lib/bootstrap.

I have added a folder called "less" under the root folder and added in the main .less file. This can be your application's main .less file. You can add a reference to bootstrap.less under this. You can find the bootstrap.less file under lib/bootstrap/less. Bootstrap.less is the main file of Bootstrap which has all the references to other .less files and Bootstrap variables. bootstrap.less looks like below.

The main.less file has a bootstrap.less reference.

Check the Bootstrap variable.less file. Bootstrap has defined all variables for all colors and sizes. You can directly change this variable's values. By including bootstrap.less into main.less, you can use these variables to your custom .css classes too. You can also override the values of variables if you wanted to keep your custom.less file separate for each tenant.

3. Install Grunt and Packages for .less.

You can use Gulp or Grunt as a task runner for generating .css files from .less files. You can do other tasks also, like minification and bundling, using it. For our example, we have used the Grunt task runner. 

You can find a detailed article about how to use Grunt with ASP.NET Core here and for Gulp here.

Here is the getting started with Grunt.

You need Node.js installed on your machine. Install Node.js with Node Package Manager (npm).

You can install Grunt using npm with the following command:

npm install -g grunt-cli 

For our project, we need to add an npm Configuration File (package.json). 

For manual installing Grunt to your project, open a command prompt and change your directory to your project directory.

cd c:\{your project directory} 

If you have added Node.js to the PATH environment variable then you only have to apply the npm command directly, otherwise, you have to give the full path of the npm exe like below and run install grunt.

C:\{your project directory}> "c:\Program Files\nodejs"\npm install grunt --save-


Install packages for .less

C:\{your project directory}> "c:\Program Files\nodejs"\npm install grunt-contrib

-less --save-dev 

o/p: + grunt-contrib-less@1.4.1added 62 packages in 8.574s 

Using Visual Studio, you can simply update the package.json file and update packages from Dependencies -> Righ click on "npm" => Click on "Restore packages."


"Restore Package"

It will look like following after restoring the package:

Add Gruntfile.js to a solution. Get more information from here https://gruntjs.com/getting-started

The sample grunt file looks like below.

4. Generate Different Stylesheet Files According to Custom Variables Using Grunt

Using the Grunt task runner you can generate .css files from .less files. We already have installed the required package for .less.

We need to add a Grunt task for .less with different parameter options. You can find the whole list of parameters and guideline for adding Grunt tasks for less here.

We are going to use the "modifyVars" parameter to modify the .less variable value. Using this parameter, you can pass the value of any .less parameter like Bootstrap's @brand-primary.

With the "files" parameter, you can define the source of .less files and the destination .css files (resulting file).

In our case, we have our main.less file which has a reference to bootstrap.less along with custom CSS classes. We can define different task according to the environment. Also, we can define different task according to a tenant.

Like the above gruntfile, we have defined the task to generate CSS for the development environment and production environment.

For development, you need to check the .css classes sometimes, so there's no need to do compression. While in the production environment you can define compress: true. It minifies the .css.

We defined the value of the 'brand-primary' variable under modifyVars for both environments.

Under the "files" tag, you can define source file as a .less file and the results file as a .css file like how in the above example we have following.

files: { 'wwwroot/css/site.debug.css': 'wwwroot/less/main.less'} 

The Grunt task generates a site.debug.css file in the defined path using the main.less file.

Similarly, you can add another task for a different tenant. You can pass a variable value according to customer requirements. You can also generate different variables for a .less file with customer specific values and generate .css using different .less files according to tenants.

Tenant task is shown below.

5. Add a Tenant Code Wwitch

You can change the use of .css files according to your tenant id. You can manage it with _layout.cshtml.

After login, you can programmatically get tenant names. You can implement a base controller and take one global variable which can be used for all views. You can decide how you get your tenant name as I wanted to focus on switching stylesheets according to different tenant name.

In following code sample, I have created one variable called tenantcode which has a tenant name. This variable can get values dynamically from the server login according to who is logged in.  I have used tenantcode to generate CSS names for that particular tenant.

In ASP.NET MVC Core, you can define the environment for development and production. You can also define your own custom one. You can get more information about the environment tag from this URL.

So, as per our logic, it generates a tenant CSS URL like "~/css/site_tenant1.css". It would be just site_.debug.css for development.

By changing tenantcode , you can change the theme of your application.

Tenant 1 theme

 Development theme

The code sample is on my GitHub, here.

If you want anything to be elaborated on more then let me know in the comments.