I little over a year ago my friends and I released a little app called Carbon, and since then it has gone through a ton of development and upgrades.
Before our latest upgrade, the entire site was deployed as a Next.js monolith with Now, ZEIT’s deployment platform. Our server rendered our Next.js app, handled a number of API endpoints, and also spun up a puppeteer process for our Safari support. Really, it handled more than it should. It really never made sense to have the two coupled, but we needed to ensure a few things were possible before we could make the split.
We needed to support somewhat dynamic routing, since our /**
endpoint is how we load GitHub Gist’s into Carbon. This is not possible with a static export of Next.js on its own, however, ZEIT recently released static rewriting in Now.
We utilized this functionality, updating our now.json
to include the necessary rewrites and set our type to static
. Since ZEIT recently announced static builds with Docker, even if you are using a Dockerfile to build your app (like we are), your deployment will still be marked as a static build if you have type: 'static'
.
For our case, we just needed to add RUN next export -o /public
to our Dockerfile and our static build was ready to be deployed. If you are also using Next.js, follow this example to get started.
Once we knew all the Gist links would use our index.html
, we needed to move the data fetching from getInitalProps
to componentDidMount
, since Next.js will call getInitialProps
at export time, and no longer at runtime. This was a relatively seamless transition, since we could just wrap the component with withRouter
in order to get the necessary url and query props, and we were already setting state values in componentDidMount
:
The main reason for separating our frontend app from our backend API was to reduce the deployment headache when dealing with puppeteer issues (puppeteer is always having issues on Alpine Linux). However, we found there are tons of other reasons for deploying statically with Now:
Our frontend is updated a lot more often then our backend, so separating it from our backend meant we could deploy app changes without having to deal with potential issues in our backend stack getting in the way.
Deploying statically does not count towards your maximum number of instances running on Now. This enables awesome things like the Now + GitHub integration with very little headache. All of our PRs are now easily verified, manually by visiting the link and with our Cypress acceptance tests.
Our site’s latency improved from over 2 seconds to 25 milliseconds in areas like Mumbai. Considering our second largest population of users by Country is China, this means massive gains for our users.
If you are interested in seeing the exact code changes we made, you can check out the entire transformation in this pull request.
Mike Fix is a partner at dawn, a holistic product studio dedicated to ambitious creation. Mike, and dawn, have built products in the past for companies big and small. If you or your company need help building with Next.js, Now or React, do not hesitate to reach out at [email protected].