Deploying a Node.js App to Heroku

Introduction

There are numerous free hosting services available for getting your Node.js applications up and running publicly. One of these services is Heroku, that allows you to deploy, manage and scale your applications on the web.

In this article we'll be building a simple Node and Express.js application that shortens given links, and deploy it to Heroku.

Creating a Node.js URL Shortener

To make the development process easier we'll be using Express, which is a lightweight web framework that is flexible and easily customizable. Express comes with an application generator, but we'll start from scratch.

Creating the Project Directory

Let's cd into the workspace and create a new directory for the project:

$ mkdir url-shortener

Initializing npm

Next let's initialize npm, and with it, start our project:

$ npm init

npm init will ask a series of questions (package name, version, description, etc). For simplicity's sake, let's skip all of these by hitting RETURN for each prompt. Node will then generate a package.json file and print it to the terminal:

{
  "name": "url-shortener",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
}

The fields in package.json (package name, description, author, etc) can be updated at anytime so you don't need to worry about it too much.

What we've added here manually is the "start": "node app.js". This will be extremely important later, when we deploy the app to Heroku.

Heroku needs to know how to run our application, and this is typically done via a Procfile. Since our application is so simple, a Procfile would be overkill, and it's enough to simply define that our app should be ran by simply executing the node app.js command.

Installing Express

With that out of the way, we're ready to install Express:

$ npm install express --save

Building a Node Server

With Express installed I'll create a very simple application in a file called app.js:

const express = require('express');
const app = express();
const path = require('path');
const port = 3000;

app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname + '/index.html'));
});

app.listen(port, () => console.log(`url-shortener listening on port ${port}!`));

The application at this point is really only Express boilerplate required to set it up, with a single route handler that returns an HTML page on port 3000.

Let's go ahead and define the page, which will accept a URL we want to shorten. It'll only consist of a header and a simple form that accepts the URL:

<h1>URL Shortener</h1>

<form method="POST" action="/url">
  <input type="text" name="url" />
  <input type="submit" />
</form>

We can test if the application is running fine by executing:

$ node app.js

Since we've added the "start" : "node app.js" command to our package.json file, we can also run it using an NPM command:

$ npm start

And navigating to http://localhost:3000:

application homepage

Handling Form Submission

While the page is rendering correctly, there's no logic to actually handle the POST request sent via the form at the /url endpoint.

To snatch the URL from the request sent via the form, we'll be using the body-parser module and extract it from the request body, so let's go ahead and require it as well and set it up for use:

const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.urlencoded());

With that done, we can extract the body of the request via req.body so let's go ahead and make another request handler that packs the URL from the body and sends it back via the response:

app.post('/url', function(req, res) {
    const url = req.body.url;

    res.send(url);
});

This still isn't what we want as we're getting the entire URL back and not the shortened version.

Shortening the URL

The only thing left to do for our Node app to be complete is to actually shorten the URL before sending it back. For this, we can use the node-url-shortener module. Let's install it via npm:

$ npm install node-url-shortener --save

Then require the package in the application:

const urlShortener = require('node-url-shortener');

And lastly, let's add another block of code that shortens the URL before sending it back:

app.post('/url', function(req, res) {
    const url = req.body.url;

    urlShortener.short(url, function(err, shortUrl){
        res.send(shortUrl);
    });
});

The urlShortner has a short() method that accepts two parameters: the original URL and a callback function. The shortened URL gets passed into the callback function and then into res.send().

Let's start up the application and test it out:

input url

After inputting a URL, we're greeted with:

url shortener result

Deploying to Heroku

Signing up for Heroku and Installing the CLI

Now that the application has been built, it's time to think about Heroku. If you don't have an account, head over to signup.heroku.com and create one.

Once you have an account, the next thing to do is install Heroku's CLI tools, which are used for deployment. Heroku provides installation instructions at The Dev Center.

Pushing to Heroku

Deploying to Heroku works via Git. It's very simple once you understand how it works. In essence you can deploy to Heroku by pushing to a remote repo, just like pushing to GitHub.

Because this is a new project, Git needs to be initialized:

$ git init

Now, we're ready to add and commit all the project files. Though, before doing that, we'll add a .gitignore file because we don't want the node_modules directory to be committed. It should be generated by npm upon deployment rather than committed to source control.

In your .gitignore file, simply add:

node_modules

With that out of the way, we can add and commit:

$ git add .
$ git commit -m 'initial commit'

Once the project is commited, we need to create a Heroku app that'll correspond to our Node app:

$ heroku create
Creating app... !
 ▸    Invalid credentials provided.
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/browser/abcd1234-b6a7-4df4-bb42-0eaf987d0637
Logging in... done
Logged in as [email protected]
Creating app... done, ⬢ nameful-wolf-12818
https://nameful-wolf-12818.herokuapp.com/ | https://git.heroku.com/nameful-wolf-12818.git

If this is your first time using the CLI, Heroku will ask you to login via the browser. The process is very simple, just follow the instructions.

Once complete, Heroku returns the newly created app name and URL (your app name will be different to mine). If you browse to the URL you'll see a Heroku welcome page.

This still isn't our URL shortener app, simply a public Heroku app to which we'll deploy our own.

Deploying the App

In the previous heroku create command, a new remote will have been added to your Git repository, allowing you to deploy to Heroku with a simple command like this:

$ git push heroku master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 326 bytes | 326.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
...
...
...
remote: Verifying deploy... done.
To https://git.heroku.com/nameful-wolf-12818.git
   5cb9118..dd0bacd  master -> master

Since the application is successfully deployed, we can go ahead and start it up:

deployed application on heroku

Though, we'll encounter an issue due to the mismatch in ports. In our app, we've hardcoded that it uses port 3000, but Heroku works on a different port and this clash crashes our application.

In order to make the application work both locally and on Heroku, we'll change the port to be either 3000 or the process.env.PORT, which is set by Heroku:

const port = process.env.PORT || 3000;

Deploying the application again and refreshing the page, everything works just fine!

heroku deployed application homepage

heroku deployed application result page

Conclusion

There are numerous free hosting services available for getting your applications up and running publicly. One of these services is Heroku, that allows you to deploy, manage and scale your applications on the web.

We've built a simple Node and Express application that shortens provided URLs via the node-url-shortener module. We've then prepared that app for deployment and finally got it up and running on Heroku.

Author image
About Tom Kadwill