Back
Serverside Rendering With Express And EJS Templates
Let's learn how to achieve server-side rendering of HTML files with Express and EJS. We'll build a strong foundation in this tutorial.
Server-side rendering means using a server to generate HTML files. This generation/rendering of HTML files is in response to a URL request to the server. Server-side, unlike client-side rendering, utilizes JavaScript modules to render HTML instead of the browser and DOM element. This article will examine how we can achieve server-side rendering using an Express server and EJS for templating.
What is EJS?
EJS is a JavaScript templating language for generating HTML with plain JavaScript. In addition, it provides support for writing JavaScript alongside HTML by utilizing unique tags.
A template language is a language that allows you to create placeholders that we can substitute for different values within our code. Templating with EJS provides a simple syntax that is easy to understand and aids fast development time. Also, EJS allows you to divide your HTML into sub-templates that can be reused and included in different templates.
EJS tags and uses
Getting Started
To get started, we will need to create an express application; to do this, you must have Node.js installed. (You can download Node.js here if you do not already have it.) After this, create a new folder, "express-ejs," and run the command below in the newly created folder.
The command will create the new node environment we will need for development. Following this, we will install all required dependencies.
The code block above will install the Express framework and EJS templating engine.
Set up Express Application
In this section, we will set up the Express server. First, create an app.js file and views folder.
The express.json()
is an Express middleware that allows you to parse requests sent with a JSON payload. We will also specify the folder to serve static files using express.static()
middleware; this accepts the directory for the static files as a parameter.
The code block above also creates a new Express application that sets up the template engine. In Express, views
indicate the directory where the template files exist; in this case, we will pass the views folder as the second parameter. Once you specify views
, Express will load the template engine module internally.
Following this, we will update the package.json to the code below:
In the project folder, create a server.js
file with the following code:
The code block above will create a new Express server that listens for connections between the specified host and port.
EJS
After bootstrapping the Express server, we will work on the template engine in the views folder. We will first set up the header and footer as partials; these are sub-templates you would like to reuse across other templates.
Styling headers and footers
In the views folder, create a partials folder with two files; header.ejs and footer.ejs. Partials are added to other files using include; this accepts the file path as a value. The usage for include is demonstrated below:
Serving a template from an Express application
The next step will be to set up the pages for the application and serve them from the Express application. First, we will create an index.ejs file with the following code:
In the code block above, we added the header and footer using include in the file and the information we want for the home page. Next, we will serve the index.ejs page from the Express app:
From the code block above, we have a method that responds to GET requests on the "/" route. Within the method, we render the index file as a response by calling the res.render()
method; this accepts two parameters: the file's name to render and the data to pass to the file. To test this, we will run npm start-dev
in the terminal. Visit http://localhost:4400/ on your web browser; you should see the index.ejs page rendered.
Injecting dynamic data into the EJS template
Following the previous section, we will look at how to use the data passed to the EJS template. In the views folder, create a posts.ejs file with the following code:
The template above expects the "posts" variable to exist in the data injected on a template render. Using the EJS template tags, we will loop through posts passed to the template and render the HTML file for each post data. In the Express app, we will add the code block below the GET method for the index route to render the posts.ejs file:
From the code block above, we will render the posts.ejs file with the posts variable passed to the template. We can preview the posts page by visiting http://localhost:4400/posts.
Next, we will set up a dynamic page that renders individual posts. But, first, we will create a post.ejs file with the code:
The code block will accept a data object with the keys title and body. Using EJS tags, we will display the value of the keys in the HTML. Finally, we will add the code block in the app.js to render the post page:
In the GET method, we have an id parameter passed to the request URL. We will use the id parameter to find the needed post from the posts variable and pass it to the post.ejs template. We can test this by visiting http://localhost:4400/post/1, 1 being the id for the post we want to fetch.
The app.all()
method is used to catch all requests that do not match the routes before it; this is why it is after all declared routes. We are using the app.all()
method to catch all requests to routes that do not exist on our server and return a 404 error.
Conclusion and resources
This article reviewed how to use EJS templates to create reusable partials and leverage the templates when rendering pages from an Express server. We also covered how to create dynamic pages using an Express server. If you want to learn more about EJS and Express, you can find visit the official documents at https://ejs.co/#docs and http://expressjs.com/en/guide/routing.html.
Using the information from this article, I recommend that you try building a simple blog using Express and EJS. You can also review the complete code for the project in this Github Repository.