DEV Community

Cover image for White Labelling
Abayomi Ogunnusi
Abayomi Ogunnusi

Posted on

White Labelling

White Label Application

White Labelling is a common practice in software development. It allows a single application to be used by multiple clients. Each client can have their own branding, logo, color scheme, etc. This allows the client to feel like they have their own application. The application can be customized for each client without having to create a separate application for each client. This is a common practice in the SaaS (Software as a Service) industry.

Let's create a white labelling application using Node.js, Express, and MongoDB.
We will create a simple application that allows us to create clients and users. Each client will have their own users. The User can be a Merchant or even a separate application. For simplicity, we will just call them users and keep them in the same database.

Step 1 - Create a new project

mkdir white-label-app
cd white-label-app
npm init -y
Enter fullscreen mode Exit fullscreen mode
npm install express mongoose
Enter fullscreen mode Exit fullscreen mode

Client Model

models/client.js

const mongoose = require('mongoose');

const clientSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        unique: true
    },
    logo: {
        type: String,
        required: true
    },
    primaryColor: {
        type: String,
        required: true
    },
    secondaryColor: {
        type: String,
        required: true
    },
    font: {
        type: String,
        required: true
    },
    users: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }]
});

const Client = mongoose.model('Client', clientSchema);

module.exports = Client;
Enter fullscreen mode Exit fullscreen mode

User Model

models/user.js

const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const userSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true,
        minlength: 6
    },
    client: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Client',
        required: true
    }
});

userSchema.pre('save', async function(next) {
    const user = this;
    if (user.isModified('password')) {
        user.password = await bcrypt.hash(user.password, 8);
    }
    next();
});


const User = mongoose.model('User', userSchema);

module.exports = User;
Enter fullscreen mode Exit fullscreen mode

Create the routes

routes/client.js

const express = require('express');
const router = express.Router();
const Client = require('../models/client');


router.post("/", async(req,res)=>{
    try{
        const client = new Client(req.body);
        await client.save();
        res.status(201).send(client);
    }catch(e){
        return res.status(400).json({error: e.message});

}
});


router.get("/", async(req,res)=>{
    try{
        const clients = await Client.find({});
        res.send(clients);
    }catch(e){
        return res.status(400).json({error: e.message});

}
});

router.get("/:id", async(req,res)=>{
    try{
        const client = await Client.findById(req.params.id);
        res.send(client);
    }catch(e){
        return res.status(400).json({error: e.message});

}
});


module.exports = router;
Enter fullscreen mode Exit fullscreen mode

routes/user.js

const express = require("express");
const router = express.Router();
const User = require("../models/user");
const Client = require("../models/client");

router.post("/", async (req, res) => {
  try {
    const { username, password, client } = req.body;
    if (!username || !password || !client) {
      return res.status(400).json({ error: "Please provide all fields" });
    }

    const userExist = await User.findOne({ username });
    if (userExist) {
      return res.status(400).json({ error: "User already exists" });
    }

    const clientExists = await Client.findById(client);
    console.log(clientExists);
    if (!clientExists) {
      return res.status(400).json({ error: "Client does not exist" });
    }
    const user = new User({ username, password, client: clientExists._id });
    await user.save();

    clientExists.users.push(user._id);
    await clientExists.save();

    res.status(201).send(user);
  } catch (e) {
    return res.status(400).json({ error: e.message });
  }
});

router.get("/", async (req, res) => {
  try {
    const users = await User.find({});
    res.send(users);
  } catch (e) {
    return res.status(400).json({ error: e.message });
  }
});

module.exports = router;

Enter fullscreen mode Exit fullscreen mode

index.js

const express = require('express');
const mongoose = require('mongoose');
const clientRouter = require('./routes/client');
const userRouter = require('./routes/user');

const app = express();
const port = process.env.PORT || 3000;

app.use(express.json());
app.use("/clients", clientRouter);
app.use("/users", userRouter);

mongoose.connect('mongodb://
localhost:27017/white-label-app');

app.listen(port, () => {
    console.log(`Server is up on port ${port}`);
});

mongoose.connection.on('connected', () => {
    console.log('Connected to MongoDB');
});

mongoose.connection.on('error', (error) => {
    console.log(error);
});

Enter fullscreen mode Exit fullscreen mode
node index.js
Enter fullscreen mode Exit fullscreen mode
curl -X POST -H "Content-Type: application/json" -d '{"name":"Client 1","logo":"https://via.placeholder.com/150","primaryColor":"#000000","secondaryColor":"#ffffff","font":"Arial"}' http://localhost:3000/clients
Enter fullscreen mode Exit fullscreen mode
curl -X POST -H "Content-Type: application/json" -d '{"username":"user1","password":"password","client":"5f9e9c9b9c9b9c9b9c9b9c9b"}' http://localhost:3000/users
Enter fullscreen mode Exit fullscreen mode
curl -X GET http://localhost:3000/users
Enter fullscreen mode Exit fullscreen mode
curl -X GET http://localhost:3000/users/5f9e9c9b9c9b9c9b9c9b9c9b
Enter fullscreen mode Exit fullscreen mode
curl -X GET http://localhost:3000/clients
Enter fullscreen mode Exit fullscreen mode
curl -X GET http://localhost:3000/clients/5f9e9c9b9c9b9c9b9c9b9c9b
Enter fullscreen mode Exit fullscreen mode

Break it down

Let's break it down again.

  • An application can have multiple clients.
  • Each client can have multiple users.
  • Each user can have their own username and password. Each client can have their own logo, color scheme, and font.

Conclusion

This is a very simple example of a white labelling application. You can take this further and create a more complex application. You can add more features to the application. Thank you for reading. I hope you learned something new today. Happy coding!

Questions

What approach do you take when creating a white labelling application? Do you have any tips or tricks? Let me know in the comments below.

Top comments (0)