~ 6 min read

Deploying a Fastify & Vue 3 Static Site to Heroku

share this story on
How to deploy a Vue 3 static site to Heroku with a Fastify Node.js backend server to serve the static files.

In today’s fast-paced world of web development, deploying static sites has become a common practice.

And I know, you’re thinking “why would anyone deploy static sites (also commonly referred to as SSG) to Heroku?“. Especially these days when modern web hosting exists in the likes of Vercel and Netlify? Well the answer is not as exciting as you’d hope - constraints at work.

Static sites offer numerous benefits such as better performance in the form of less JavaScript on the page, less round-trip HTTP requests, and generally they’re easier to scale. In this article, we will explore how to deploy a Vue 3 static site to Heroku with a Fastify Node.js backend server to serve the static files. By the end, you’ll have a clear understanding of the process and be able to deploy your own static site with ease.

Introduction to Deploying Static Sites

Before we dive into the deployment process, let’s briefly discuss static sites. Unlike dynamic websites that generate content on the server, static sites consist of pre-rendered HTML, CSS, and JavaScript files.

These files are generated once, on build-time, and are later served directly from a web server or cloud native hosting such as AWS’s S3 buckets or other cloud offerings, without the need for server-side processing. This approach results in faster load times and improved performance for end-users. Vercel for example, is well-known for providing stellar performance in this context, as they’re able to leverage AWS’s infrastructure to deliver those static files as close as possible to the user. This is often referred to as “the edge”.

What is Heroku?

Once the pioneer in Platform as a Service (PaaS), Heroku is a cloud platform that enables developers to deploy, manage, and scale applications effortlessly. It supports a wide range of programming languages and frameworks, making it a popular choice for deploying web applications. Heroku provides a streamlined deployment process, automatic scaling, and easy integration with various third-party services.

That said, Heroku isn’t a natural choice for delivering static files. Let’s unravel and understand why.

Why Use a Fastify Node.js Backend Server for Hosting Static Sites?

Heroku, as great as it is, is more suitable for application servers and its common use-case is spinning up web servers (called “dynos”). In the context of static files, this means that we’d have to build a web server (and use it as a dyno) that hosts the static files for the website.

In fact, for performance reasons it is highly recommended to use generic web servers to serve static files, such as nginx or apache http server, over the Node.js runtime.

With Heroku, to keep things simple and comfortable developer ergonomics and good developer experience, we’ll serve these static files with the Fastify Node.js backend server. Fastify is a lightweight and efficient web framework for Node.js, known for its exceptional performance.

By choosing Fastify to serve static files, we can leverage additional functionalities like URL routing, middleware support, and server-side logic if needed and stay within the Node.js user-land development. This combination gives us the flexibility to build complex applications while still enjoying the benefits of a static site architecture.

How to Deploy a Vue 3 Static Site to Heroku with Fastify

Now, let’s dive into the step-by-step process of deploying a Vue 3 static site to Heroku using Fastify. We’ll cover creating a new Heroku app, setting up Fastify to serve Vue 3 static files, and configuring Heroku’s app environment variables for Vite’s build.

1. Create a New Heroku App

The first step is to create a new Heroku app to host our static site. Follow these steps:

  • Log in to your Heroku account or create a new one if you haven’t already.
  • Once logged in, navigate to the Heroku dashboard.
  • Click the “New” button and select “Create new app” and choose the Node.js application framework.
  • Choose a unique name for your app and select your preferred region.
  • Click the “Create app” button to create the app.

2. The Vue 3 Static Site Setup

For this project, I scaffolded the Vue 3 frontend application using Vuetify 3 which is a UI component library and it creates the project with: Vue 3 Vuetify 3 Vite

The Vite workflow uses a vite build command to build the static site assets and the default configuration generates all the files in the dist/ directory.

3. Setting up Fastify to Serve Vue 3 Static Files

To serve these files over HTTP we need a Node.js web application.

Now that we have our Heroku app, let’s configure Fastify to serve the Vue 3 static files. Follow these steps:

  • Create a new directory for your project and navigate into it.
  • Initialize a new Node.js project using npm init.
  • Install Fastify as a dependency: npm install --save --ignore-script fastify @fastify/static.
  • Create a new file named server.js and open it in your preferred code editor. Mine is, well, VS Code, surprise surprise!
  • We’ll import the Fastify library and set it up to serve static files from the dist/ directory:

const fastify = require("fastify")({ logger: true });
const path = require("path");

fastify.register(require("@fastify/static"), {
  root: path.join(__dirname, "dist"),
  prefix: "/",
});

fastify.setNotFoundHandler(function (request, reply) {
  reply.sendFile("index.html");
});

fastify.listen(
  { port: process.env.PORT || 3000, host: process.env.HOST || "0.0.0.0" },
  (err, address) => {
    if (err) throw err;
  }
);

In this example, we’re using the @fastify/static plugin to serve static files from the dist directory.

You’ll notice we also used a Fastify “not found” handler as a catch-all wildcard for routing. This is relevant for Single Page Applications (SPAs) and a frontend routing setup with client-side browsing history.

4. Configure Heroku’s App Environment Variables for Vite’s Build

To ensure a successful build and deployment of the Vue 3 static site, we need to configure the necessary environment variables in our Heroku app. Specifically, we need to set the NODE_ENV variable to production and configure any other environment variables required by your Vue 3 build process:

  • Go to your Heroku dashboard and navigate to your app.
  • Click on the “Settings” tab.
  • Scroll down to the “Config Vars” section.
  • Click the “Reveal Config Vars” button.
  • Add the following environment variables:
  • NODE_ENV set to production

Additional variables as required by your Vue 3 build process (e.g., VITE_APP_API_URL). These environment variables ensure that Vite, the build tool for Vue 3, optimizes the production build accordingly.

Deploying to Heroku

Now that everything is set up, let’s deploy our Vue 3 static site to Heroku:

  • Commit your project to a version control system like Git.
  • In your terminal, log in to Heroku using the command heroku login.
  • Link your local project directory to the Heroku app by running heroku git:remote -a <your-app-name>.
  • Deploy your code to Heroku by executing git push heroku main.
  • Heroku will receive your code, build the application, and deploy it to a dyno. Once the deployment process completes, you can access your deployed Vue 3 static site by visiting your Heroku app’s URL.

Conclusion

Deploying a Vue 3 static site to Heroku with a Fastify Node.js backend server offers developers the benefits of a static site architecture while retaining the flexibility to add server-side functionalities when necessary.

Indeed, Heroku isn’t a native frontend hosting platform but by following the steps outlined in this article, you can easily deploy your own static site to Heroku. Thanks to Fastify’s edge for performance and being a robust web application framework we can rely on it as a web server to serve our Vue 3 static sites.

Happy coding and deploying!