Website Page Routing Navigation with Node.js Express and EJS

website page routing with nodejs and express js and ejs

website page routing with nodejs and express js and ejs.

Hello Guyz! How are you all? so I am back with a new blogging series we call website page routing with nodejs and express js and ejs.

Express is just about the default framework to make a website with Node. rather like any website creation, the primary step to make an Express website is to line up an template and routing. EJS is a simple templating language to get HTML with Javascript. It works well with Node without having to learn more complicated front-end frameworks like Angular or React. I started web development with PHP. EJS feels plenty more like PHP and learning a way to use was much easier on behalf of me .

website page routing with nodejs and express js and ejs.

Another important component in Express is that the Router class which could be a middleware to make url path-based routing easy and maintainable.

The aim here is to make a 3-page website with home, about and contact pages with a header, nav and footer templates and routing traffic by the express server. Let’s get started!

Project Folder

We first create a main project folder and run npm init -y. Then, organise it as below.

-- project_folder
 -- css
    -- style.css
 -- html
    -- about.ejs
    -- contact.ejs
    -- index.ejs
    -- include
        -- footer.ejs
        -- head.ejs
        -- nav.ejs
        -- scripts.ejs
 -- routes
    -- index.js
 -- app.js
 -- package.json
 -- package-lock.json
 -- node_modules

Packages

Dependencies are below. For the front-end, we will use bootstrap 4 which requires jquery and popper.js. The ejs package for creating template.

"dependencies": {
    "bootstrap": "4.0.0",
    "ejs": "2.6.1",
    "body-parser": "1.18.3",
    "express": "4.16.3",
    "jquery": "3.3.1",
    "popper.js": "1.12.9"
}

URL Routing

We are using the Router class. This enable us to export the routing logic as a module and use it in the main app.js. There are a few different ways for routing (see documentation here). When the logic gets complicated, using the Router class to compartmentalise routing makes it easier to maintain.

index.js in the routes folder

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
  console.log('Request for home recieved');
  res.render('index');
});

router.get('/about', (req, res) => {
  console.log('Request for about page recieved');
  res.render('about');
});

router.get('/contact', (req, res) => {
  console.log('Request for contact page recieved');
  res.render('contact');
});

module.exports = router;

app.js in the main project folder

To serve static files, we need to use the express.static. By default, express cannot access to the files in other folders. We also need to set the default views directory where we have ejs files. The router gets imported and used as middleware.

const express = require('express');
const path = require('path');
const routes = require('./routes');

const app = express();
// Set the default views directory to html folder
app.set('views', path.join(__dirname, 'html'));

// Set the folder for css & java scripts
app.use(express.static(path.join(__dirname,'css')));
app.use(express.static(path.join(__dirname, 'node_modules')));

// Set the view engine to ejs
app.set('view engine', 'ejs');

app.use('/', routes);

app.listen(3000, () => {
  console.log('Server is running at localhost:3000');
});

Serving Bootstrap and Javascripts files

Once we set the folders to serve static files by using the express.static, the path to the css or javascript files should not include the folder path. If you do, you will get the horrible MIME type error as below:

Refused to apply style from whatever-the-file-path because its MIME type (‘text/html’) is not a supported stylesheet MIME type, and strict MIME checking is enabled).

Node Js Navigations

You can replicate this error by changing the stylesheet path from href=”bootstrap/dist/css/bootstrap.min.css” to href=”../node_modules/bootstrap/dist/css/bootstrap.min.css” in the head.ejs file for the link element.

Using Templates with EJS

This is the simplest part. Use the ejs syntax which is very similar to including templates with PHP.

<% include ./include/head %>

We can now create the front-end view in whatever way you want by writing html and css.

Here is the html and css example of simple 3 page websites. Note that we are using bootstrap 4 for most of the styling with a few custom css.

HTML

index.ejs

<!DOCTYPE html>
<html lang="en">
    <% include ./include/head %>
    <body>
        <% include ./include/nav %>
        <div class="container">
            <div class="row">
                <h1>Home</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>

        <% include ./include/scripts %>
        <% include ./include/footer %>
    </body>
</html>

about.ejs

<!DOCTYPE html>
<html lang="en">
    <% include ./include/head %>
    <body>
        <% include ./include/nav %>
        <div class="container">
            <div class="row">
                <h1>About</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>

        <% include ./include/scripts %>
        <% include ./include/footer %>
    </body>
</html>

contact.ejs

<!DOCTYPE html>
<html lang="en">
    <% include ./include/head %>
    <body>
        <% include ./include/nav %>
        <div class="container">
            <div class="row">
                <h1>Contact</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>

        <% include ./include/scripts %>
        <% include ./include/footer %>
    </body>
</html>

head.ejs in the include folder

<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>Node EJS | Home</title>

    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

nav.ejs in the include folder

<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="#">Navbar</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" 
    data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
        <div class="navbar-nav ml-auto">
        <a class="nav-item nav-link active" href="/">Home</span></a>
        <a class="nav-item nav-link" href="about">About</a>
        <a class="nav-item nav-link" href="contact">Contact</a>
        </div>
    </div>
</nav>

footer.ejs in the include folder

Included a small trick to call Javascript. It displays the current year dynamically.

<footer class="container-fluid footer">
  <div class="container">
    <div class="row">
      <div class="col-12">
        <p></p>
        <p></p>
        <% let year = (new Date()).getFullYear() %>
        <p style="float:right;">&copy;<%= year %> mydatahack.com</p>
      </div>
    </div>

  </div>
</footer>

scripts.ejs in the include folder

<!-- jQuery first, then Popper.js, then Bootstrap JS. -->
<script src="jquery/dist/jquery.slim.min.js"></script>
<script src="popper.js/dist/umd/popper.min.js"></script>
<script src="bootstrap/dist/js/bootstrap.min.js"></script> 

CSS

style.css

hr {
  background-color: #fff;
	border-top: 2px dotted #8c8b8b;
}

.footer{
  background-color: #D1C4E9;
  margin:0px auto;
  padding: 20px 0px 20px 0px;
  vertical-align:bottom;
}

So it was an overview of how can we make a simple routing navigation in node js and express js using ejs. website page routing with nodejs and express js and ejs.