Deploy Vue 3 App to Heroku via Github
Tags: vue, heroku, github, node
Published: 2022-07-14 20:27:41

## Contents

- [Intro](#intro)
- [Link the app to heroku via Github Connect](#link-the-app-to-heroku-via-github-connect)
- [Go live](#go-live)
- [Fixing the errors](#fixing-the-errors)
    - [Serve app with express](#serve-app-with-express)
    - [Fix vite issue](#fix-vite-issue)
    - [Change heroku environment settings](#change-heroku-environment-settings)

## Intro
So you're trying to test your Vue skills or you need to share your work with someone else by deploying your Vue 3 app to a live environment and of the many [free cloud hosting platforms](https://www.websiteplanet.com/blog/best-free-cloud-hosting-services/), you've decided to use [heroku](https://www.heroku.com) but there's this bug you are encountering after all is set.

```bash
heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/"
```

You've googled all around and no solution or the tutorials/articles available are only for Vue 2. This is what has led to the article you now read. 

So either you've faced this error or you just need a guide, follow on as I walk you through. I'll be connecting the app to Heroku via Github and not the heroku cli. In my opinion, this is easier to integrate and you can set up CI/CD with the click of few buttons without the need for _yaml files_ configuration.

I assume you have a running Vue 3 app and you've pushed it to [Github](https://github.com).

## Link the app to heroku via Github Connect.
* login to your heroku account and go to your dashboard. Click on 'New', give it a name and select 'Create new app'. 
![App on heroku](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1tw2du1rjxhjl1xfvxf.png)

* On the 'Deployment method' section, select Github.
![deployment method selction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0hznwgynfwn3hsbuggwa.png) then follow the process to authorise heroku to have access to your github repository then select/search your code repo and connect it.
![heroku app connected to github](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ptclv0wnqmwydub4vjc.png)

Here is where you get CI/CD integration easily. On the 'Automatic deploys' section you can choose to have your app deploy automatically whenever you push to the branch of your choice. isn't that nice?

## Go live

On the 'Manual deploy', we will now deploy our app by clicking on 'deploy branch' and heroku will attempt to build it and make it available on a url accessible link.


![Deployed app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qihwxox609svvs8ijo5r.png)

it tells us our app deployed successfully but when we try to view it, it shows us 'Application error'. and when we check our logs(More > View Logs) we see this 
```bash
2022-07-13T19:01:34.763285+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=vue-app-heroku-github.herokuapp.com request_id=90dddd7c-ec38-4a5c-8423-4953a1c199ea fwd="105.112.183.72" dyno= connect= service= status=503 bytes= protocol=https
```

so what could be wrong? In deploying an app, Heroku tries to auto detect what kind of app it is and applies an appropriate builder and looks for the entry file/script instruction. So it sees a package.json script and thinks our app is a node.js app and hence applies the node.js builder as can be seen from the builder logs(Activity > view builder log). 

## Fixing the errors
To fix the error we are going to make our Vue app into a Node.js served app so the heroku Node.js bundler can build it for us. we'll be using the packages `express` and `serve-static` then we'll add a "start" script instruction to our package.json file and change the configuration on our heroku environment if error persist.

### Serve app with express 
Go back to your terminal and run the command below 
```bash
npm install express serve-static
```
So express(a Node.js framework) will serve as our app entry router and serve-static will serve the file after vite must have compiled it for the vue-router to use it's router feature.

Next, create a javascript file at the root directory of your app and paste the following code into it.

```javascript
const express = require('express')
const serveStatic = require('serve-static')
const path = require('path')

//initialise the express package
const app = express()

//use the serve-static package to serve the bundled app files in the dist directory
app.use('/', serveStatic(path.join(__dirname, '/dist')))

// this * route is to serve project on different page routes except root `/`
app.get(/.*/, function (req, res) {
	res.sendFile(path.join(__dirname, '/dist/index.html'))
})

//heroku automatically assigns port so leave it to do it's
//work, don't set a port in the heroku dashboard. while the
//5000 or whatever number you set will be for your local
//machine.
const port = process.env.PORT || 5000
app.listen(port)
console.log(`app is listening on port: ${port}`)

```
 Heroku needs a "start" script instruction so we're going to add one. so navigate to your package.json file and modify the "scripts" section to look like this
```json
"scripts": {
    "dev": "vite",
    "start": "node index.js",
    "build": "vite build",
    "preview": "vite preview --port 4173",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
  },
```

where `index.js` is the name of the javascript file we created earlier. At this point if your app is a fresh install then your app should now be accessible when you click "Open App".

This is what I was able to gather from the internet, thanks to tutorials like [this](https://dev.to/anjolaogunmefun/deploy-vue-js-projects-to-heroku-1hb5) and [this](https://www.codementor.io/@ravianand1988/easily-4-steps-to-continuous-delivery-auto-deploy-vue-js-app-on-heroku-xljk977pq).

However if you're using an existing app that's large in size and or you're encountering an error that seems to trace itself to vite from the application logs then follow on.

### Fix vite issue
In vue 2, the vue-cli was used to build the app for production however in vue 3, there is a change to [vite](https://vitejs.dev/). Vite has an [instruction guide](https://vitejs.dev/guide/static-deploy.html#heroku) for deploying apps based on it to heroku but the build pack used is deprecated as at the writing of this article. 


From a Stack Overflow [answer](https://stackoverflow.com/a/72318409/9157239), I got to know that heroku sometimes prunes packages in devDepencies in production mode and this is where vite is registered meaning it won't be able to build successfully in that scenario. So we're going to use the npx(Node Package Executor) command to tell the deployment to execute the vite command needed to build our app. In the scripts section of package.json file, add the following: 
```json
"prestart": "npm run build",
"build": "npx vite build",
"start": "node index.js",
```
`prestart` may not be necessary but just to ensure the build runs.

### Change heroku environment settings
We'll also turn off production mode so that vite won't be pruned when heroku is building our app so we'll set 

```
NODE_ENV=development
```

on our heroku dashboard via settings > Config Vars. (I assume this app is not really for production else if vite issues persist, you may need to remove it from devDependcies into dependecies though that isn't optimal) Also we're going to set 
```
NODE_MODULES_CACHE = false
```
so it won't use previously cached node modules. If you have environmental variables, i.e those set in your .env file, you can set them here as well. Remember your .env file should not be pushed to github for security reasons. *In Vue 3 the convention for environmental variables is VITE_XXXX*. so let's say you have an API_URL variable you're sending requests to then it will be VITE_API_URL.
Then push your changes to Github and if you already enabled automatic deploys from GitHub in  Deploy > Automatic deploys. Your app should be available when you click "Open app" or you can manually deploy as well.


---
This is my first article on dev.to but not my first time here. Let me know if this helped you or any other comments! 
Header Image by [Mr PAI](https://www.linkedin.com/in/ilesanmi-peter-068956165)