Hosting Next JS App on Firebase.
With Firebase hosting, we can deploy the single-page web application, mobile app landing page, or progressive web app with single deploy command. This article is mostly about deploying the Next.js application on the firebase hosting service. The deployment of other React applications or static sites is very easy and straightforward however we need some custom changes on the next application as it involves SSR.
Let's get into it.
NextJS Application Installation
Create a Next Js application using yarn or npm and name the project
yarn create next-app
Here is the project structure of the installed app
To run the project locally
yarn dev
Now build and export the next project
next build && next export
We might through into the error because in pages/index.js
It uses the next/image
where next js default loader is not compatible with the next export. Update the next image to normal html image tab or use third party loader.
For now, we replace the next image with an HTML image tag and try the next export. It will successfully export the static HTML pages.
Firebase Project setup
Create a Firebase project from http://console.firebase.com and register the Firebase web app. To set up the process please follow here.
We also need to have Firebase CLI
to the local machine. It is very important to have a firebase running from the CLI where we will initialize the firebase project. For this, we need to have node JS installed on the system.
We need to log in to the firebase from the firebase CLI.
firebase login
We need to create a working directory of the project name to initialize the project in a respective project from the CLI.
firebase login
now on existing project, we will init the firebase
firebase init
To select hosting use the arrow down key and press space and hit enter
After that, we need to select the project firebase project using the existing project from the list, will show the list, and select the project.
It will ask which directory will you want to make a public directory press enter for now will change this latter.
It will write firebase.json and .firebaserc files into the root of the existing project. Here is the screenshot
Now To deploy the static file we need to modify the hosting directory because we have exported the file into our directory with next export
.
If we have multiple targets and projects.
.firebaserc
: It holds the setting for deploying targets
{
"projects": {
"default": "ready-to-work-d1465"
},
"targets": {
"ready-to-work-d1465": {
"hosting": {
"static-site": [
"static-site"
]
}
}
}
}
firebase.json
It is used for hosting and has a configuration for deployment.
{
"hosting": [
{
"target": "static-site",
"public": "out",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
]
}
To deploy we use a static app or react app.
firebase deploy --only hosting
However, we can have Next Application with SSR implementation so let’s see how we can deploy Next application on Firebase with SSR. So we will use cloud functions and hosting together for the deployment.
We need to Firebase init into the current project once again and then select functions options and select language and npm package installation at the same time. It will generate the functions folder and the configuration installations.
Now let's modify the firebase.json
file.
{
"hosting": [
{
"target": "t",
"public": "out",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "functions",
"function": "nextServer"
}
]
}
],
"functions": {
"source": "functions",
"runtime": "nodejs10",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
}
}
rewrites
rewrite rule used if the request to files or directories through URL doesn't exist on the public folder.nextServer
the cloud function is used to look for response.- Cloud function-related configuration is added indicating source and runtime.
Inside the functions directory in an index file, we will create the function name nextServer
to handle SSR.
const functions = require("firebase-functions");
const { default: next } = require('next');
const isDev = process.env.NODE_ENV !== 'production';const server = next({
dev: isDev,
//location of .next generated after running -> yarn build
conf: { distDir: '.next' },
});const nextjsHandle = server.getRequestHandler();
exports.nextServer = https.onRequest((req, res) => {
return server.prepare().then(() => nextjsHandle(req, res));
});
Let's use cross-env
the package to env support
yarn add cross-env
let’s create the deploy script in package.json
{
"name": "static-app",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"export": "next export",
"start": "next start",
"lint": "next lint",
"deploy": "yarn build && cross-env NODE_ENV=production firebase deploy --only functions,hosting"
},
"dependencies": {
"cross-env": "^7.0.2",
"next": "12.0.2",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"eslint": "7",
"eslint-config-next": "12.0.2"
}
}
yarn deploy
We have successfully deployed the next js application to firebase hosting.
Thank you. happy coding 🎉