Javascript

Hosting your Node.JS web application on Back4App servers

Introduction

This tutorial explains how you can set up a subdomain and easily host static pages. After completing this step-by-step guide, you will be able to use a Node JS App to Register and Login Users.

Prerequisites

To complete this tutorial, you will need:

  • If you want to test this App locally, you need to install Node JS in your local environment. You can follow the Official NodeJS tutorial to install Node JS at your terminal it successfully.
  • An app created with Back4App.
  • Back4App Command Line Configured with the project.

First off, let’s talk about our new simple application!

We’ll describe an example about the usage of Web hosting with Node JS!

Let’s imagine that we need to build a simple Log in, Register and request password from Users included in your Back4App Dashboard. We will be able to use Bootstrap, Static files (CSS and Images) and usign Express in the Project.

See the live app here: nodeapplication.back4app.io.

You can clone this complete application in the App code templates on the Back4App Platform here.

Understand our final structure

Firstly, complete the set up using the Command Line Interface (see prerequisites), to understand how it will work with the final structure from the files:

├── NodeJSWebApp/
│  ├── cloud/
│  │   ├── app.js
│  │   ├── routes.js
│  │   ├── package.json
│  │   ├── views/
│  │   │   ├── head.ejs
│  │   │   ├── index.ejs
│  │   │   ├── reset_password.ejs
│  ├── public/
│  │   ├── images/
│  │   ├── css/
│  │   │   ├── style.css

Step 1 - Enable your subdomain name on Back4app

Enable your Web Hosting feature, please follow the steps available in the guide below:

Activating your Web Hosting and Live Query

Step 2 - Create and upload files

Before getting started with this step, we recommend you using Command Line Tool (see prereqs) to upload your files easily!

First off, create the files called as app.js and package.json inside the cloud directory!

Inside the cloud folder (in your terminal), you need to write:

$ touch package.json

Now, insert the npm module ‘body-parser’ inside the file package.json:

1
2
3
4
5
{
  "dependencies": {
    "body-parser": "*"
  }
}

Troubleshooting: It is not necessary to run npm install inside the cloud folder because the Back4App server will install it automatically!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Require the module
var bodyParser = require("body-parser");

// Set up the views directory
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

// Set up the Body Parser to your App
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true})); 

//Require the routes.js file

require('./routes');

Step 3 - Create the views to your App

We’ll provide template EJS files to make the template App, you can change it anytime at your end. :)

Returning to the terminal

Inside the Cloud directory, it is necessary to create the views folder and the following EJS files:

  • head.ejs - We will use it to add content to head of HTML structure.
  • index.ejs - We will use it to Register and Log in users.
  • reset_password.ejs - We will use it for the user request the Password Reset.

Hint:
We will construct the views using Bootstrap, click here to read more about it.

You can add content to your respective views. You can use the below templates without any hassle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  <title>Back4App - Node JS Application</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="shortcut icon" type="image/png" href="/favicon.png"/>
  <!-- Bootstrap CSS--> 
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

  <!-- jQuery--> 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <!-- Bootstrap JS--> 
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

  <!-- Stylesheet Pages -->
  <link rel="stylesheet" type="text/css" href="/css/style.css">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  <!DOCTYPE html>
  <html>
  <head>
    <% include head.ejs %>
  </head>
  <body>
    <section id="header">
      <div class="container">
        <div class="row">
          <div class="col-sm-6">
            <div class="box-settings box-register">
              <div class="wrap-login100">
                <form class="validate-form" method="POST" action="/users/register">
                  <h2 class="title-screen">
                    Register a new account
                  </h2>
                  <div class="form-group">
                    <input type="text" name="usernameRegister" placeholder="Username" class="form-control" value="<%= infoUser.usernameRegister %>">
                  </div>
                  <div class="form-group">
                    <input type="text" name="emailRegister" placeholder="Email" class="form-control" value="<%= infoUser.emailRegister %>">
                  </div>
                  <div class="form-group">
                    <input type="password" name="passwordRegister" placeholder="Password" class="form-control" value="<%= infoUser.passwordRegister %>">
                  </div>
                  <% if (RegisterMessage != 'undefined' ? RegisterMessage  : '' ) { %>
                    <div class="alert alert-<%= typeStatus %>" role="alert">
                      <p><%= RegisterMessage %></p>
                    </div>
                  <% } %>
                  <div class="form-group">
                    <button class="btn-login btn">
                      Register
                    </button>
                  </div>
                </form>
              </div>            
            </div>
          </div>
          <div class="col-sm-6">
            <div class="box-settings box-login">
              <div class="wrap-login100">
                <form class="validate-form" method="POST" action="/users/login">
                  <h2 class="title-screen">
                    Access your account
                  </h2>
                  <div class="form-group">
                    <input type="text" name="usernameLogin" placeholder="Username" class="form-control" value="<%= infoUser.usernameLogin %>">
                  </div>

                  <div class="form-group">
                    <input type="password" name="passwordLogin" placeholder="Password" class="form-control" value="<%= infoUser.passwordLogin %>">
                  </div>
                  <% if (loginMessage != 'undefined' ? loginMessage  : '' ) { %>
                    <div class="alert alert-<%= typeStatus %>" role="alert">
                      <p><%= loginMessage %></p>
                    </div>
                  <% } %>
                  <div class="form-group">
                    <button class="btn-login btn">
                      Login
                    </button>
                  </div>

                  <div class="text-forgot">
                    <a href="/users/forgot-password">
                      Forgot Password? Click here to retrive your access!
                    </a>
                  </div>
                </form>
              </div>            
            </div>
          </div>
        </div>
      </div>
    </section>
  </body>
  </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  <!DOCTYPE html>
  <html>
  <head>
    <% include head.ejs %>
  </head>
  <body>
    <section id="header">
      <div class="container">
        <div class="row">
          <div class="col-sm-offset-3 col-sm-6" align="center">
            <div class="box-settings box-password">
              <div class="wrap-login100">
                <form class="validate-form" method="POST" action="/users/forgot-password">
                  <h2 class="title-screen">
                    Retrieve your access
                  </h2>
                  <p>Insert your email address</p>
                  <div class="form-group">
                    <input type="text" name="email" placeholder="Email" class="form-control" value="<%= infoUser.email %>">
                  </div>
                  <% if (resetPass != 'undefined' ? resetPass  : '' ) { %>
                    <div class="alert alert-<%= typeStatus %>" role="alert">
                      <p><%= resetPass %></p>
                    </div>
                  <% } %>
                  <div class="form-group">
                    <button class="btn-login btn">
                      Reset Password
                    </button>
                  </div>
                </form>
              </div>            
            </div>
          </div>
        </div>
      </div>
    </section>
  </body>
  </html>

Step 4 - Create the routes to render the views

Now, we need to configure the Routes to render the views that were created previously. The routes will be built using Express.

1
2
3
4
5
6
7
8
// Index
app.get('/', (req, res) => {
  res.render('index', {loginMessage: '', RegisterMessage: '', typeStatus: '',  infoUser: ''});
});
// Request Password
app.get('/users/forgot-password', (req, res) => {
  res.render('reset_password', { resetPass: '', typeStatus: '', infoUser: ''});
});

Hint:
As you can see, we are configuring variable as parameters, which will be used to display alerts on the page.

Step 5 - Create the routes to save the informations to your database

We will use the Parse Server Javascript Guide as a reference for developing our functions for Register, Login and Request the Password.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Request the Log in passing the email and password
app.post('/users/login', async(req, res) => {
  let infoUser = req.body;
  
  try{
    let user = await Parse.User.logIn(infoUser.usernameLogin, infoUser.passwordLogin)
    res.render('index', { loginMessage: "User logged!", RegisterMessage: '', typeStatus: "success",  infoUser: infoUser });
  } catch (error){
    res.render('index', { loginMessage: error.message, RegisterMessage: '', typeStatus: "danger",  infoUser: infoUser});
  }
});

// Register the user passing the username, password and email
app.post('/users/register', async(req, res) => {
  let infoUser = req.body;    
  let user = new Parse.User();

  user.set("username", infoUser.usernameRegister);
  user.set("password", infoUser.passwordRegister);
  user.set("email", infoUser.emailRegister);

  try{
    await user.signUp();
    res.render('index', { loginMessage : '', RegisterMessage: "User created!", typeStatus: "success",  infoUser: infoUser});
  } catch (error) {
    res.render('index', { loginMessage : '', RegisterMessage: error.message, typeStatus: "danger",  infoUser: infoUser});
  }
});

// Request the Password reset passing the email
app.post('/users/forgot-password', function(req, res) {
  let infoUser = req.body;
  try{  
    await Parse.User.requestPasswordReset(infoUser.email);
    res.render('reset_password', { resetPass: "Check your email!", typeStatus: "success", infoUser: infoUser});
  } catch (e){
    res.render('reset_password', { resetPass: error.message, typeStatus: "danger", infoUser: infoUser});
  }
});

Step 6 - Almost there! Static files in public folder

It’s not over yet! In the public folder, you can insert static files such as CSS and images to require this on the views :)

When you add files to CSS and images, you are able to provide different stylesheets to your Website created!

Step 7 - It’s done!

Up to this point, you have splendidly learned how to create a Node JS Application using Cloud code.

Click on this link to access the complete Project in Back4App at anytime.

With the steps described above, you’ll be able to work with the Web Hosting when using a Node JS application!