Tutorial: Create a Vanilla JavaScript SPA for authentication in a customer tenant

This tutorial is part 2 of a series that demonstrates building a Vanilla JavaScript (JS) single-page application (SPA) and preparing it for authentication using the Microsoft Entra admin center. In part 1 of this series, you registered an application and configured user flows in your Microsoft Entra ID for customers tenant. This tutorial demonstrates how to create a Vanilla JS SPA using npm and create files needed for authentication and authorization.

In this tutorial;

  • Create a Vanilla JavaScript project in Visual Studio Code
  • Install required packages
  • Add code to server.js to create a server


Create a new Vanilla JS project and install dependencies

  1. Open Visual Studio Code, select File > Open Folder.... Navigate to and select the location in which to create your project.

  2. Open a new terminal by selecting Terminal > New Terminal.

  3. Run the following command to create a new Vanilla JS project:

    npm init -y
  4. Create additional folders and files to achieve the following project structure:

        └── public
            └── authConfig.js
            └── authPopup.js
            └── authRedirect.js
            └── claimUtils.js
            └── index.html
            └── signout.html
            └── styles.css
            └── ui.js    
        └── server.js

Install app dependencies

  1. In the Terminal, run the following command to install the required dependencies for the project:

    npm install express morgan @azure/msal-browser

Edit the server.js file

Express is a web application framework for Node.js. It's used to create a server that hosts the application. Morgan is the middleware that logs HTTP requests to the console. The server file is used to host these dependencies and contains the routes for the application. Authentication and authorization are handled by the Microsoft Authentication Library for JavaScript (MSAL.js).

  1. Add the following code snippet to the server.js file:

    const express = require('express');
    const morgan = require('morgan');
    const path = require('path');
    const DEFAULT_PORT = process.env.PORT || 3000;
    // initialize express.
    const app = express();
    // Configure morgan module to log all requests.
    // serve public assets.
    // serve msal-browser module
    app.use(express.static(path.join(__dirname, "node_modules/@azure/msal-browser/lib")));
    // set up a route for signout.html
    app.get('/signout', (req, res) => {
        res.sendFile(path.join(__dirname + '/public/signout.html'));
    // set up a route for redirect.html
    app.get('/redirect', (req, res) => {
        res.sendFile(path.join(__dirname + '/public/redirect.html'));
    // set up a route for index.html
    app.get('/', (req, res) => {
        res.sendFile(path.join(__dirname + '/index.html'));
    app.listen(DEFAULT_PORT, () => {
        console.log(`Sample app listening on port ${DEFAULT_PORT}!`);

In this code, the app variable is initialized with the express module and express is used to serve the public assets. MSAL-browser is served as a static asset and is used to initiate the authentication flow.

Next step