This is an expansion of the
functions-nextjsexample so you should read it's README first as I will only cover differences here and not Next.js specifics of SSR/SSG.
Host a Next.js app on Firebase using Firebase Hosting and Google Cloud Run rewrite rules.
- Setup Firebase, Google Cloud and Next.js
- Install and Run
- Improvements over Cloud Functions example
- Caveats
- Future
gcloud auth loginfirebase loginfirebase initor select an existing project withfirebase use --add- create a new Web App within the project to host your site. See instructions here.
- update
firebase.jsonwith your new Apps hosting target- replace the
hosting.siteTODO_YOUR_WEB_APP_DEPLOY_TARGET_HEREwith your web apps value.
- replace the
- populate Firestore with test data:
- create a collection called
posts - create documents with auto-generated IDs and the following fields:
- field:
title. Value:A title - field:
blurb. Value:A blurb - field:
content. Value:<p>Some HTML <em>content</em></p>
- field:
- create a collection called
- replace
TODO_YOUR_PROJECT_ID_HEREinnext.config.jswith your project's ID - enable Google Cloud Run
- enable Google Cloud Build
- update your Firebase project to Blaze plan
# development
npm install
npm run dev
# or
yarn
yarn dev
# build docker image, deploy to cloud run, deploy public assets to firebase
npm run deployAfter deploying, you can continue to add Posts to your Firestore collection and the app will render them without needing to redeploy!
- no custom Next.js server
- this caused much confusion as Next.js directs people to run development mode with the custom server, but I discouraged this as it was intended as a simple wrapper for Cloud Functions usage and not for dev mode.
next startwas not able to be used which is required for some Next.js features and excluded them from use (serverless mode).
- no need to copy the
.next/directory after build into thefunctionsdirectory to be uploaded to the Cloud Functions environment. This was confusing and is explicit and clear with Docker. - simplified folder structure
- simplified build and deploy scripts in
package.json - no issues with duplicate static file serving (images/css)
- easier to add Firebase Functions to the project as the
functionsfolder will be ignored:┌ components/ | └ ... ├ functions/ <-- All other backend functions | ├ firebase.json <-- Contains only Functions config. | ├ package.json | ├ tsconfig.json | ├ src/ | | └ index.ts <-- main source file for your Cloud Functions | └ lib/ Cloud Function prefixing to avoid clashes | ├ index.js <-- compiled JavaScript code | └ index.js.map <-- source map for debugging ├ helpers/ | └ ... ├ pages/ | └ ... ├ public/ | └ ... ├ .dockerignore <-- Ignore all dirs except those required for Cloud Run Next.js app ├ .gitignore ├ .tool-versions <-- move this here. See https://asdf-vm.com ├ Dockerfile <-- Cloud Run Next.js Image ├ firebase.json <-- Contains Hosting with Deploy Targets ├ firestore.rules ├ next.config.js ├ package-lock.json └ package.json
- Deployment is more involved with Cloud Run not being integrated into the
firebase deployworkflow.- requires
gcloud - takes more time since Cloud Functions do not perform an
npm installwhereas we must do so with Cloud Run
- requires
- Since
next buildoccurs in the Cloud Run build on Google Cloud Build, we don't have the Next.js Automatic Static Optimization files to bubble up and push to Firebase Hosting. This is a small optimization.