Introduction

This guide will walk you through steps necessary to include MDB package in your Express project and to add some basic setup for you project.

Prerequisites

Before starting project make sure to install Node LTS (12.x.x recommended).


Creating a new Express application

Step 1

Create and open your project's main folder and run following commands or create files manually.

        
            
      mkdir my-project
      cd my-project
      mkdir static
      mkdir static/templates
      touch {app.js,static/templates/index.html}
      npm init -y
      
        
    

When you’re done, your complete project should look like this:

        
          my-project/
          ├── static/
          │   └──  templates/
          │        └── index.html
          ├── app.js
          └── package.json
        
      

Step 2

Install Express and nodemon

        
            
        npm i --save-dev express nodemon
      
        
    

Install MDB

Now when we have Express project initialized and MDB package installed, let's add MDB to the project.

Note: CDN works only with MDB Free version. If you are MDB Pro user, choose different installation method.

NPM

Installation

To install MDB UI KIT in your project easily type the following command in terminal:

MDB Free
        
            
            npm install mdb-ui-kit
          
        
    
MDB Pro Essential users
        
            
            npm install git+https://oauth2:ACCESS_TOKEN@git.mdbootstrap.com/mdb/standard/mdb-ui-kit-pro-essential
          
        
    
MDB Pro Advanced users
        
            
            npm install git+https://oauth2:ACCESS_TOKEN@git.mdbootstrap.com/mdb/standard/mdb-ui-kit-pro-advanced
          
        
    

Now when we have Express project initialized and MDB package installed, let's move on to setting up the project.

NPM

Step 1

Download the package

Step 2

Create directory my-project/assets/

Step 3

Unpack downloaded file and copy mdb folder to the my-project/assets/

CDN

Installation via CDN is the easiest methods of integrating MDB UI KIT with your project. Just copy the latest compiled JS script tag and CSS link tag from cdnjs to the application.

Here's an example code:

CSS

        
            
          <!-- Font Awesome -->
          <link
          href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
            rel="stylesheet"
          />
          <!-- Google Fonts -->
          <link
            href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
            rel="stylesheet"
          />
          <!-- MDB -->
          <link
            href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.0.0/mdb.min.css"
            rel="stylesheet"
            />
        
        
    

JS

        
            
          <!-- MDB -->
          <script
            type="text/javascript"
            src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.0.0/mdb.min.js">
          </script>
        
        
    

Configure Express

Express configuration is different for every installation method.

NPM

With our project folder ready, we can configure our app and run project locally.

Open app.js and paste the code from following example to make linking mdb.min.js and mdb.min.css easier and to avoid errors.

        
            
        const express = require("express");
        const path = require("path");

        const app = express();
        const PORT = 9090;

        app.use("/mdb", express.static(path.join(__dirname, "node_modules/mdb-ui-kit")));
        
        app.get("/", (req, res) => {
          res.sendFile(path.join(__dirname, "static/templates/index.html"));
        });

        app.listen(PORT, () => {
          console.log(`App running on localhost:${PORT}`);
        });
      
        
    

Let's add some code to static/templates/index.html to check if everything works fine.

        
            
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
      <meta http-equiv="x-ua-compatible" content="ie=edge" />
      <title>Express app with MDB!</title>
      <!-- MDB -->
      <link rel="stylesheet" href="mdb/css/mdb.min.css" />
    </head>

    <body>
      <!-- Start your project here-->
      <div class="container">
        <button class="btn btn-primary">Click me!</button>
      </div>
      <!-- End your project here-->
      <!-- MDB -->
      <script type="text/javascript" src="mdb/js/mdb.min.js"></script>
      <!-- Custom scripts -->
      <script type="text/javascript"></script>
    </body>
  </html>
  
        
    

We’re including a little bit of styling here with the div class="container", <button> and .btn btn-primary with ripple effect so we can ensure that CSS and JS were loaded from MDB succesfuly.

Let's add start script to the package.json

        
            
        "scripts": {
          "start": "nodemon app.js"
        }
      
        
    

Finally, we can start our app. From the my-project folder in your terminal, run:

        
            
        npm run start
      
        
    

Manual Installation

With dependencies installed and our project folder ready to start coding, we can configure our app and run project locally.

Open app.js and paste the code from following example to make linking mdb.min.js and mdb.min.css easier and to avoid errors.

        
            
          const express = require("express");
          const path = require("path");

          const app = express();
          const PORT = 9090;

          app.use("/assets", express.static(path.join(__dirname, "assets")));
          app.use("/static", express.static(path.join(__dirname, "static")));

          
          app.get("/", (req, res) => {
            res.sendFile(path.join(__dirname, "static/templates/index.html"));
          });

          app.listen(PORT, () => {
            console.log(`App running on localhost:${PORT}`);
          });
        
        
    

Let's add some code to static/templates/index.html to check if everything works fine.

        
            
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
        <meta http-equiv="x-ua-compatible" content="ie=edge" />
        <title>Express app with MDB!</title>
        <link rel="stylesheet" href="/assets/mdb/css/mdb.min.css"/>
      </head>

      <body>
        <!-- Start your project here-->
        <div class="container">
          <button class="btn btn-primary">Click me!</button>
        </div>
        <!-- End your project here-->
        <!-- MDB -->
        <script type="text/javascript" src="/assets/mdb/js/mdb.min.js"></script>
        <!-- Custom scripts -->
        <script type="text/javascript"></script>
      </body>
    </html>
    
        
    

We’re including a little bit of styling here with the div class="container", <button> and .btn btn-primary with ripple effect so we can ensure that CSS and JS were loaded from MDB succesfuly.

Now add start script to the package.json

        
            
          "scripts": {
            "start": "nodemon app.js"
          }
        
        
    

Finally, we can start our app. From the my-project folder in your terminal, run:

        
            
          npm run start
        
        
    

CDN

With our project folder ready, we can configure our app and run project locally.

Installation via CDN is one of the easiest methods of integrating MDB UI KIT with your project. Just copy the latest compiled JS script tag and CSS link tag from cdnjs to the application.

Don't forget to add also Font Awesome and Roboto font if you need. Here's an example code:

CSS

        
            
        <!-- Font Awesome -->
        <link
          href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
          rel="stylesheet"
        />
        <!-- Google Fonts -->
        <link
          href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
          rel="stylesheet"
        />
        <!-- MDB -->
        <link
          href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/#[[latestVersion]]#/mdb.min.css"
          rel="stylesheet"
        />
      
        
    

JS

        
            
        <!-- MDB -->
        <script
          type="text/javascript"
          src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/#[[latestVersion]]#/mdb.min.js"
        ></script>
      
        
    

Example backend app

Lets see how to integrate Express.js application with MDB 5 in our layout, components, and utilities. To do this, we will create simple todo app using expressjs and MDB Standard.


Creating a new Express.js project

For our example, we will create a new Express.js application from mdb starter. Navigate to your project directory, i.e. mdb-standard-express-app and follow the steps below.

Step 1

Creating MongoDB database.

In order to create a new database you need to run the following command:

        
            
        mdb database init -db mongodb
    
        
    

Now you need to provide your user data and then the database details. Please provide the values of your choice. For example:

  • Enter username tony
  • Enter password Stark_12
  • Repeat password Stark_12
  • Enter database name todo_app
  • Enter description Database for the TODO app

Note: the password must contain at least one uppercase letter, one lowercase letter, one number, one special symbol and have minimum length of 8.

Important Do not close your terminal window until you save your credentials somewhere. This is the only time we will show you your database password. If you won't save it you'll loose it.

Step 2

Creating Node.js API with Express and Mongoose.

In case you don't know, Mongoose is a MongoDB object modeling tool. It helps managing MongoDB access and models. You can initialize a MDB GO starter that already has configured Mongoose. Simply run the following command:

        
            
      mdb backend init
    
        
    

and choose Express.js + MongoDB API starter from the list that shows up.

After initialization just go to the newly created project directory and open the .env file. After that edit the DB_CONNECTION_STRING value. You should paste the connection string that's been shown to you in the previous step.

Step 3

We have to add one more thing to the project. Let's install CORS and add them to index.js

        
            
      npm install -D cors dotenv
    
        
    

Add some config to the index.js

        
            
      'use strict';

      require('dotenv').config();
      const cors = require("cors");
      const express = require('express');
      const bodyParser = require('body-parser');
      const mongoose = require('mongoose');
      const { port, mongoUrl } = require('./app/config');

      const app = express();

      app.use(bodyParser.json());
      app.use(cors());
      app.use(express.static('public'));
      app.use(require('./app/routes'));

      mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false, useCreateIndex: true });

      const db = mongoose.connection;
      db.on('error', (err) => console.error('MongoDB connection error:', err));
      db.once('open', () => app.listen(port, () => console.log(`Listening on port: ${port}`)));

    
        
    

We also need to modify the routes/index.js and routes/tasks.js a little bit.

        
            
      "use strict";

      const express = require("express");
      const router = express.Router({ mergeParams: true });

      router.use("/", require("./tasks"));

      module.exports = router;
    
        
    
        
            
      'use strict';

      const express = require('express');
      const router = express.Router({ mergeParams: true });
      const Task = require('../models/task');

      router.get('/', (request, response) => {

          Task.find({}, (err, res) => {
              if (err) {
                  console.error(err);
                  return response.sendStatus(500);
              }
              response.send(res);
          });
      });

      router.get('/:id', (request, response) => {

          const { id } = request.params;

          Task.findOne({ _id: id }, (err, res) => {
              if (err) {
                  console.error(err);
                  return response.sendStatus(500);
              }
              response.send(res);
          });
      });

      router.post('/', (request, response) => {

          const { name, desc } = request.body;

          if (!name || !desc) return response.sendStatus(400);

          const task = new Task({ name, desc });
          task.save()
              .then(res => response.send(res))
              .catch(e => {
                  console.error(e);
                  response.sendStatus(500);
              });
      });

      router.put('/:id', async (request, response) => {

          const { id } = request.params;
          const { name, desc } = request.body;

          if (!name && !desc) return response.sendStatus(400);

          Task.findOneAndUpdate({ _id: id }, { name, desc })
              .then(res => response.send(res))
              .catch(e => {
                  console.error(e);
                  response.sendStatus(500);
              });
      });

      router.delete('/:id', async (request, response) => {

          const { id } = request.params;

          Task.deleteOne({ _id: id })
              .then(() => response.sendStatus(200))
              .catch(e => {
                  console.error(e);
                  response.sendStatus(500);
              });
      });

      module.exports = router;
    
        
    

Thanks to this config, express will be able to reponse for requests with data from database or to serve files, depending on our needs. List of other endpoints:

  • GET /tasks/:id
  • POST /tasks
  • PUT /tasks/:id
  • DELETE /tasks/:id

Creating client-side code

Add new content to index.html file inside the public directory.

Since our starter database contains some sample models and routes, let's use them. We will create an application that will show a list of tasks. We also intend to create a functonality for adding new tasks, changing their content and removing them.

We have already prepared the code for you, so go ahead and copy and paste it into public/index.html.

Ok, so what's actually going on there. We use MDB components, mdb.Button, mdb.Modal, mdb.ListGroup and few other. The modal will be responsible to show inputs that will allow you to add, edit and send tasks to the database. At the end, the list group will display our data.

Remember to replace API_URL value with your application URL. If it's not assigned yet, run mdb backend publish -p node12. By default it's like https://USERNAME-PROJECT_NAME.mdbgo.io.

        
            
      <!DOCTYPE html>
      <html>
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
            <meta http-equiv="x-ua-compatible" content="ie=edge" />
            <title>Material Design for Bootstrap</title>
            <!-- MDB icon -->
            <link rel="icon" href="assets/img/mdb-favicon.ico" type="image/x-icon" />
            <!-- Font Awesome -->
            <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css" />
            <!-- Google Fonts Roboto -->
            <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" />
            <!-- MDB -->
            <link rel="stylesheet" href="assets/css/mdb.min.css" />
        </head>
        <body>
          <div class="container mt-5">
            <div class="row pt-5">
              <div class="col text-center">
                <button class="btn btn-primary" data-mdb-toggle="modal" data-mdb-target="#addTaskModal">ADD TASK</button>
              </div>
            </div>
            <div class="row mt-3 p-5" style="min-height: 40vh;">
              <div class="col d-flex justify-content-center align-items-center">
                <ul class="list-group list-group-light" style="min-width: 22rem;">
                </ul>
              </div>
            </div>
            <div class="modal fade" id="addTaskModal" tabindex="-1" aria-labelledby="addTaskModalLabel"
            aria-hidden="true">
              <div class="modal-dialog">
                <div class="modal-content">
                  <div class="modal-header">
                    <h5 class="modal-title" id="addTaskModalLabel">Add task</h5>
                    <button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
                  </div>
                  <div class="modal-body">
                    <form id="addTaskForm" action="/" method="post">
                      <div class="form-outline mb-4">
                        <input name='name' type="text" id="nameInput" class="form-control" />
                        <label class="form-label" for="form7Example1">Name</label>
                      </div>

                      <div class="form-outline mb-4">
                        <input name="desc" type="text" id="descInput" class="form-control" />
                        <label class="form-label" for="form7Example2">Email address</label>
                      </div>
                    </div>
                    <div class="modal-footer">
                      <button type="button" class="btn btn-secondary" data-mdb-dismiss="modal">
                        Close
                      </button>
                      <button type="button" class="btn btn-primary modalConfirmBtn">Confirm</button>
                    </div>
                  </form>
                </div>
              </div>
            </div>

            <div class="modal fade" id="editTaskModal" tabindex="-1" aria-labelledby="editTaskModalLabel"
            aria-hidden="true">
              <div class="modal-dialog">
                <div class="modal-content">
                  <div class="modal-header">
                    <h5 class="modal-title" id="editTaskModalLabel">Edit Task</h5>
                    <button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
                  </div>
                  <div class="modal-body">
                    <form id="editTaskForm" action="/" method="post">
                      <div class="form-outline mb-4">
                        <input name='name' type="text" id="editNameInput" class="form-control" />
                        <label class="form-label" for="editNameInput">Name</label>
                      </div>

                      <div class="form-outline mb-4">
                        <input name="desc" type="text" id="editDescInput" class="form-control" />
                        <label class="form-label" for="editDescInput">Email address</label>
                      </div>
                    </div>
                    <div class="modal-footer">
                      <button type="button" class="btn btn-secondary" data-mdb-dismiss="modal">
                        Close
                      </button>
                      <button type="button" class="btn btn-primary modalConfirmBtn">Confirm</button>
                    </div>
                  </form>
                </div>
              </div>
            </div>
          </div>
        </body>

        <!-- MDB -->
        <script type="text/javascript" src="assets/js/mdb.min.js"></script>

        <!-- Custom scripts -->
        <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

        <script type="text/javascript"> 
          let taskToEditID
          let taskList
          let editTaskModalInstance;
          const API_URL = 'example url'
          const modalConfirmBtn = document.querySelector('.modalConfirmBtn');
          const editTaskModal = document.querySelector('#editTaskModal');
          const addTaskModal = document.querySelector('#addTaskModal');
          const modalEditConfirmBtn = editTaskModal.querySelector('.modalConfirmBtn');
          const addTaskForm = document.querySelector('#addTaskForm');
          const editTaskForm = document.querySelector('#editTaskForm');
          const addTaskModalInstance = mdb.Modal.getInstance(document.querySelector('#addTaskModal'))

          const createAndReloadTasks = (taskData) => {
            const taskListElement = document.querySelector('ul')
            taskListElement.innerHTML = ''
            for (let i = 0; i < taskData.length; i++) {
              const taskToAdd = 
              `<li class="list-group-item d-flex justify-content-between align-items-center gap-5">
                <div>
                  <div class="fw-bold">${taskData[i].name}</div>
                  <div class="fw-bold">${taskData[i].desc}</div>
                </div>
                <div>
                  <a class="editBtn" id="${taskData[i]._id}" style="cursor: pointer;">
                    <span class="fas fa-pen text-primary me-3" title="edit" data-mdb-toggle="modal" data-mdb-target="#editTaskModal"></span>
                  </a>
                  <a class="deleteBtn" id="${taskData[i]._id}" style="cursor: pointer;">
                    <span class="fas fa-trash text-danger" title="delete"></span>
                  </a>
                </div>
              </li>`
              taskListElement.insertAdjacentHTML('beforeend', taskToAdd)
            }
            const deleteBtns = document.querySelectorAll('.deleteBtn');
            const editBtns = document.querySelectorAll('.editBtn');

            deleteBtns.forEach((btn)=> {
              btn.addEventListener('click', ()=> {
                deleteTask(btn.id)
              })
            })

            editBtns.forEach((btn)=> {
              btn.addEventListener('click', ()=> {
                openEditModal(btn.id);
                taskToEditID = btn.id;
              })
            })
          }

          const openEditModal = (id) => {
            axios.get(`${API_URL}/${id}`).then((res) => {
              const taskData = res.data;
              editTaskForm.querySelector('#editNameInput').value = taskData.name;
              editTaskForm.querySelector('#editDescInput').value = taskData.desc;
            })
              editTaskModalInstance = mdb.Modal.getInstance(document.querySelector('#editTaskModal'))
          }

          const getTasks = (dataOnly) => {
            axios({url:API_URL, method: 'GET', params: {dataOnly: dataOnly}}).then((res) => {
              taskList = res.data
              if (true){
                createAndReloadTasks(taskList)
              }
            });
          };

          const deleteTask = (id) => {
            axios.delete(`${API_URL}/${id}`).then((res) => {
              getTasks(true)
            });
          }

          const addNewTask = () => {
            let formDataObject = {}
            const formData = new FormData(addTaskForm)

            formData.forEach((value, key) => {
              formDataObject[key] = value;
            });

            axios({url: API_URL, method: 'POST', data: formDataObject}).then((res, err) => {
              getTasks(true)
            }).catch((err) => {
              console.log(err)
            })
            addTaskForm.reset()
          }

          modalEditConfirmBtn.addEventListener('click', () => {
            const editedData = {
              name: editTaskForm.querySelector('#editNameInput').value,
              desc: editTaskForm.querySelector('#editDescInput').value
            }

            axios({url: `${API_URL}/${taskToEditID}`, method: 'PUT', data: editedData}).then((res, err) => {
              getTasks(true)
            }).catch((err) => {
              console.log(err)
            })
            editTaskModalInstance.hide()
          })

          modalConfirmBtn.addEventListener('click', () => {
            addNewTask()
            addTaskModalInstance.hide()
          })
          
          getTasks(true)
        </script>
      </html>
    
        
    

If you haven't done it already, run npm start in your terminal. The app should be fully functional and should work correctly with backend.

Now you can publish your project on MDB GO

        
            
          mdb backend publish -p node12
      
        
    

Optimization

If you want to further optimize your application please visit:


Backend features

Express.js:

This example was created with use of Express.js. By using our Express.js + MongoDB API starter we got a ready environment to start a new project.


Frontend features

MDB UI KIT:

To create the project we used our ui kit, with which we can build basic views very quickly.

Views and Layouts:

In this project we have successfully integrated the Express.js + MongoDB API starter with the MDB Standard package. We created simple layout using MDB components and we used those components to send request such as get, post, put and delete requests to the database.