見出し画像

Hosting Next JS App on Firebase.

クリエイター : Bishal Bhattarai , 株式会社readytowork ネパール支店長

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 CLIto 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 🎉