Deploy React.js web apps generated with create-react-app. Automates deployment with the built-in bundler and serves it up via Nginx. See the introductory blog post and entry in Heroku elements.
- Heroku
- git
- Node.js
- create-react-app
npm install -g create-react-app
Ensure requirements are met, then execute the following in a terminal.
✏️ Replace $APP_NAME
with a name for your unique app.
create-react-app $APP_NAME
cd $APP_NAME
git init
heroku create $APP_NAME --buildpack https://github.com/zauberware/create-react-app-buildpack.git
git add .
git commit -m "Start with create-react-app"
git push heroku master
heroku open
For explanation about these steps, continue reading the next section.
create-react-app my-app
cd my-app
git init
At this point, this new repo is local, only on your computer. Eventually, you may want to push to Github.
heroku create $APP_NAME --buildpack https://github.com/zauberware/create-react-app-buildpack.git
✏️ Replace $APP_NAME
with a name for your unique app.
This command:
- sets the app name & its URL
https://my-app-name.herokuapp.com
- sets the buildpack to deploy a
create-react-app
app - configures the
heroku
remote in the local git repo, sogit push heroku master
will push to this new Heroku app.
git add .
git commit -m "Start with create-react-app"
git push heroku master
heroku open
Find the app on your dashboard.
Work with your app locally using npm start
. See: create-react-app docs
Then, commit & deploy ♻️
Eventually, to share, collaborate, or simply back-up your code, create an empty repo at Github, and then follow the instructions shown on the repo to push an existing repository from the command line.
The web server may be configured via the static buildpack.
The default static.json
, if it does not exist in the repo, is:
{ "root": "build/" }
By default, React Router (not included) uses hash-based URLs like https://example.com/index.html#/users/me/edit
. This is nice & easy when getting started with local development, but for a public app you probably want real URLs like https://example.com/users/me/edit
.
Create a static.json
file to configure the web server for clean browserHistory
URLs with React Router:
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
Enforce secure connections by automatically redirecting insecure requests to https://, in static.json
:
{
"https_only": true
}
Prevent downgrade attacks with HTTP strict transport security. Add HSTS "headers"
to static.json
:
{
"headers": {
"/**": {
"Strict-Transport-Security": "max-age=7776000"
}
}
}
max-age
is the number of seconds to enforce HTTPS since the last connection; the example is 90-days
REACT_APP_*
environment variables are supported with this buildpack.
🤐 Be careful not to export secrets. These values may be accessed by anyone who can see the React app.
heroku config:set REACT_APP_HELLO='I love sushi!'
Requires at least create-react-app 0.7. Earlier versions only support Compile-time.
Create a .env
file that sets a variable per line:
REACT_APP_API_URL=http://api.example.com
REACT_APP_CLIENT_ID=XyzxYzxyZ
Two versions of variables are supported. In addition to compile-time variables applied during build the app supports variables set at runtime, applied as each web dyno starts-up.
Requirement | Compile-time | Runtime |
---|---|---|
never changes for a build | ✓ | |
support for continuous delivery | ✓ | |
updates immediately when setting new config vars | ✓ | |
different values for staging & production (in a pipeline) | ✓ | |
ex: REACT_APP_BUILD_VERSION (static fact about the bundle) |
✓ | |
ex: REACT_APP_DEBUG_ASSERTIONS (prune code from bundle) |
✓ | |
ex: REACT_APP_API_URL (transient, external reference) |
✓ | |
ex: REACT_APP_FILEPICKER_API_KEY (Add-on config vars) |
✓ |
♻️ The app must be re-deployed for compiled changes to take effect.
heroku config:set REACT_APP_HELLO='I love sushi!'
git commit --allow-empty -m "Set REACT_APP_HELLO config var"
git push heroku master
🤐 Be careful not to export secrets. These values may be accessed by anyone who can see the React app.
Use a custom .profile.d
script to make variables visible to the React app by prefixing them with REACT_APP_
.
- create
.profile.d/000-react-app-exports.sh
- make it executable
chmod +x .profile.d/000-react-app-exports.sh
- add an
export
line for each variable:
export REACT_APP_ADDON_CONFIG=${ADDON_CONFIG:-}
- set-up & use Runtime configuration to access the variables
For example, to use the API key for the Filestack JS image uploader:
export REACT_APP_FILEPICKER_API_KEY=${FILEPICKER_API_KEY:-}
This buildpack will never intentionally cause previously deployed apps to become undeployable. Using master as directed in the main instructions will always deploy an app with the most recent version of this buildpack.
Releases are tagged, so you can lock an app to a specific version, if that kind of determinism pleases you:
heroku buildpacks:set https://github.com/zauberware/create-react-app-buildpack.git#v1.2.1
✏️ Replace v1.2.1
with the desired release tag.
♻️ Then, commit & deploy to rebuild on the new buildpack version.
This buildpack composes several buildpacks (specified in .buildpacks
) to support no-configuration deployment on Heroku:
- complete Node.js enviroment to support the webpack build
node_modules
cached between deployments
- enables runtime environment variables
- generates the default
static.json
- performs the production build for create-react-app,
npm run build
- Nginx web server
- handy static website & SPA (single-page app) customization options
Some kind feedback pointed out that this buildpack is not necessarily specific to create-react-app
.
This buildpack can deploy any SPA [single-page app] as long as it meets the following requirements:
npm run build
performs the transpile/bundling- the file
build/index.html
or the root specified instatic.json
exists at runtime.