This article goes over how to deploy a Parcel build to Heroku.
Parcel
Given you have a Parcel app:
In your package.json, make sure there’s a build
script:
{
"scripts": {
"build": "parcel build"
}
}
Heroku runs the
build
script if it exists during deploy.
Serve
Install serve to serve the static site:
npm install serve
Create a start script in package.json
:
{
"scripts": {
"build": "parcel build",
"start": "serve"
},
"dependencies": {
"serve": "latest"
}
}
Or create a Procfile to serve your project directory:
echo 'web: npx serve' > Procfile
Heroku determines how to start your app by looking for a Procfile or start script.
Then create serve.json so the static site and routes are served correctly:
touch serve.json
{
"public": "dist",
"rewrites": [{ "source": "**", "destination": "/index.html" }],
"headers": [
{
"source": "**",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=0, must-revalidate"
}
]
},
{
"source": "**/*.@(css|ico|jpg|jpeg|js|gif|png)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
}
]
}
Commit and push your repository.
Deprecated
Add the Heroku buildpacks in order:
The Node.js buildpack must come before the static buildpack since the site has to be built before it can be served.
The buildpacks can be added via the Heroku CLI:
heroku buildpacks:set heroku/nodejs --app <MY_APP_NAME>
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-static.git --app <MY_APP_NAME>
Replace
<MY_APP_NAME>
with your Heroku app name.
Or they can be added with app.json
:
{
"buildpacks": [
{
"url": "heroku/nodejs"
},
{
"url": "https://github.com/heroku/heroku-buildpack-static"
}
]
}
Create a static.json
:
touch static.json
And configure the options for your static application:
{
"root": "dist/",
"routes": {
"**": "index.html"
},
"https_only": true,
"error_page": "index.html",
"headers": {
"/**": {
"Cache-Control": "public, max-age=0, must-revalidate"
},
"/**.css": {
"Cache-Control": "public, max-age=31536000, immutable"
},
"/**.ico": {
"Cache-Control": "public, max-age=31536000, immutable"
},
"/**.jpg": {
"Cache-Control": "public, max-age=31536000, immutable"
},
"/**.jpeg": {
"Cache-Control": "public, max-age=31536000, immutable"
},
"/**.js": {
"Cache-Control": "public, max-age=31536000, immutable"
},
"/**.png": {
"Cache-Control": "public, max-age=31536000, immutable"
}
}
}
Push and deploy the Heroku app. The build log should look like:
-----> Building on the Heroku-20 stack
-----> Using buildpacks:
1. heroku/nodejs
2. https://github.com/heroku/heroku-buildpack-static
-----> Node.js app detected
-----> Creating runtime environment
-----> Installing binaries
-----> Restoring cache
-----> Installing dependencies
-----> Build
-----> Pruning devDependencies
-----> Caching build
-----> Build succeeded!
-----> Static HTML app detected
-----> Installed nginx 1.19.0 to /app/bin
-----> Discovering process types
Procfile declares types -> (none)
Default types for buildpack -> web
-----> Compressing...
-----> Launching...
Released v1
https://myappname.herokuapp.com/ deployed to Heroku
There’s no need for a Procfile since Heroku automatically creates a dyno for your static app:
web bin/boot