Website Page Routing with Node.js Express and EJS

Express is pretty much the default framework to create a website with Node. Just like any website creation, the first step to create an Express website is to set up an template and routing. EJS is an easy templating language to generate 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 a lot more like PHP and learning how to use was much easier for me.

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

Aim here is to create a 3-page websites with home, about and contact pages with 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

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.

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).

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.

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

about.ejs

contact.ejs

head.ejs in the include folder

nav.ejs in the include folder

footer.ejs in the include folder

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

scripts.ejs in the include folder

CSS

style.css

Front-End
TypeScript: type aliases to check type equality

This post is to analyse how the type equality check by using type aliases proposed by Matt Pocock in his twitter post. These type aliases allow us to elegantly express type equality checks in unit tests. All we need to do is to pass the output and expected types in …

Front-End
Fixing it.only type error in Jest

If you are getting a type error with it.only in Jest, it could be due to incorrect TypeScript typings or incompatible versions of Jest and TypeScript. To resolve this issue, you can try the following steps: Make sure you have the latest versions of Jest and its TypeScript typings installed …

Front-End
yup conditional validation example

Here’s an example of a Yup validation logic where the first input field is optional but, if filled, it must contain only alphabetic characters, and the second input field is required: import * as Yup from “yup”; const validationSchema = Yup.object().shape({ firstField: Yup.string().matches(/^[A-Za-z]*$/, { message: “First field must contain only …