【Firebase】既に作成済みのNext.jsのアプリをHostingで公開する方法

firebase-prograshi(プロぐらし)-kv Firebase
記事内に広告が含まれていることがあります。


Next.jsでアプリを作ったものの、いざ公開となると「Firebaseのどの設定が必要か」で迷う方は少なくありません。

本記事では、既存のNext.jsプロジェクトをFirebase Hostingで公開するための最短ルートを解説します。

Firebase CLIのセットアップから、SSG/SSRを維持したままデプロイするための注意点まで、ステップバイステップでご紹介します。


静的なHTMLを出力する

Firebase Hostingは事前(ビルド時)に作成した静的なHTMLファイルを公開するサーバーです。Next.jsでビルドしてHTMLを生成し、そのページをHostingサーバーに置きます。

静的なサイトを生成するのでSSG(Static Site Generation)と言います。


SSRとSSGの違い

ユーザーの操作などに合わせてサーバー側で処理を実行しHTMLを書き換える場合はFirebase Hostingでは対応できません。その場合はFirebase App Hostingを使う必要があります。

ユーザーリクエストごとにサーバー側でページを生成する方法をSSR(Server-Side Rendering)と言います。

SSGとSSRの違い

①SSG(静的にHTMLを生成する)
・事前にHTML生成 → サーバーなし → そのまま配信

②SSR(サーバー側でHTMLを生成する)
・ユーザー → サーバー → HTML生成 → 表示

【STEP1】next.config.tsの編集

プロジェクト直下にあるnext.config.tsを開きます。デフォルトは以下のようになっています。

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;


追記方法

ビルド時に静的なHTMLを生成するために output: 'export' を追記します。

また、通常のNext.jsはサーバー側で画像の圧縮やリサイズを行って画像を表示しています。このため、images: {unoptimized: true}で画像最適化機能もオフにします。

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  
  //SSGで静的HTMLを生成 
  output: 'export',
  images: {
    unoptimized: true, // 静的書き出しでは画像の最適化機能が使えないため
  },
};

export default nextConfig;


next.config.tsファイルとは何か?

next.config.tsはNext.jsの動作を決める設定ファイルです。例えば、以下のようなことができます。

・SSGにする
・画像最適化の設定をする
・環境変数を追加する
・リダイレクト設定をする


【STEP2】ビルドする

next.config.tsの設定を記述したら、静的なHTMLファイルをビルドします。

npm run build


以下のように処理が実行されます。

npm run build

> slp-app2@0.1.0 build
> next build

▲ Next.js 16.1.4 (Turbopack)
- Environments: .env.local

  Creating an optimized production build ...
✓ Compiled successfully in 2.8s
✓ Finished TypeScript in 4.4s
✓ Collecting page data using 19 workers in 533.4ms    
✓ Generating static pages using 19 workers (16/16) in 537.2ms
✓ Finalizing page optimization in 570.5ms    

Route (app)
┌ ○ /
├ ○ /_not-found
├ ○ /account
├ ○ /admin/usersList
├ ○ /forgot-password
├ ○ /login
├ ○ /note
├ ○ /register
├ ○ /summary
└ ○ /zustand


○  (Static)  prerendered as static content


プロジェクトディレクトリに「out」というフォルダが生成され、その中に静的なファイルが格納されます。

これが公開されるファイル群です。


(補足)静的なHTMLを直接するわけではない

ビルドで静的なHTMLを生成するといっても、Next.jsでApp Routerを使っている場合は各ページをhtmlやCSSで記述したファイルを生成するわけではありません。

静的なHTMLを生成する元となる「_PAGE_.txt」といった設計書をテキストファイルで生成します。

1:"$Sreact.fragment"
2:I[47257,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/d2be314c3ece3fbe.js"],"ClientPageRoot"]
3:I[85519,["/_next/static/chunks/04ba8192d8c255d2.js","/_next/static/chunks/1aca79680532db84.js","/_next/static/chunks/27b96a136334d0f2.js","/_next/static/chunks/3a00c3c0186f4f2e.js","/_next/static/chunks/c15def08ddfadd63.js","/_next/static/chunks/2eac6b6da0874c5a.js","/_next/static/chunks/884c2946376f8e31.js"],"default"]
6:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/d2be314c3ece3fbe.js"],"OutletBoundary"]
7:"$Sreact.suspense"
0:{"buildId":"2x6-Oor_T22VuT7i9gcu6","rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","script","script-0",{"src":"/_next/static/chunks/c15def08ddfadd63.js","async":true}],["$","script","script-1",{"src":"/_next/static/chunks/2eac6b6da0874c5a.js","async":true}],["$","script","script-2",{"src":"/_next/static/chunks/884c2946376f8e31.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"loading":null,"isPartial":false}
4:{}
5:"$0:rsc:props:children:0:props:serverProvidedParams:params"
8:null
RSCデータ

このテキストファイルをRSC(React Server Components)データといいます。

Next.jsが大本となるHTMLを作成し、RSCデータ(設計書)を元にHTMLを生成し、JSと合わせて出力します。

HTML(骨組み)
 + 
RSCデータ(設計図)
 +
JS(動き)
 ↓
完成


1:”$Sreact.fragment”

ReactのFragment(<>…</>)のことです。


2: I[47257, […], “ClientPageRoot”]
コンポーネントID、読み込むJSファイルを指定しています。


7: “$Sreact.suspense”
ReactのSuspense(ローディング制御)です。

0:{“buildId”:”2×6-Oor_T22VuT7i9gcu6″}

ビルドごとの識別IDです。


【STEP3】Firebase Hostingの初期化

次にFirebase Hostingを初期化します。なお、既に他のfirebaseの設定を入れていたとしても、この操作で追加/編集されるのはFirebase Hostingの部分のみです。

初期設定のコマンドを実行します。

firebase init hosting

対話型で進めていきます。

(質問1)上書きOKかの確認

You're about to initialize a Firebase project in this directory:

  C:\Users\~

Before we get started, keep in mind:

  ※既存のFirebaseの設定ファイルがあるけど、hostingの設定を追加してもいいですか?
  * You are initializing within an existing Firebase project directory

? Are you ready to proceed? (Y/n)



(質問2)公開ディレクトリの設定(※out)

SSGで公開するので「out」を指定します(※publicではありません!)

? What do you want to use as your public directory? out



(質問3)SPAの設定

? Configure as a single-page app (rewrite all urls to /index.html)? (Y/n)

SSGでWEBサイトを作成する場合、Noにします。


(質問4)Githubで自動化するか?

? Set up automatic builds and deploys with GitHub? (Y/n)

githubのリモートレポジトリにpushしたときに自動でビルドする場合はYes。テスト環境で手動で試したい場合はNoとします。


(質問5)index.htmlを上書きさせない!(※Noにする)

? File out/index.html already exists. Overwrite? (y/N)

Firebase initは少しおせっかいな仕様になっていて、とりあえずWEBサイトが表示されるようにout/index.htmlを上書きするか確認してきます。Yesにするとせっかく作ったindex.htmlが上書きされてしまうのでNoを選択します。


最後に結果が出力されます。

  • Wrote configuration info to firebase.json
  • Wrote project information to .firebaserc
  • Firebase initialization complete!

以上で設定は完了です。


【STEP4】デプロイする

ローカルでFirebase Hostingの設定が完了したら、デプロイして公開します。

Firestore など他の設定に影響を与えないよう、オプションでHosting だけを指定してデプロイします。

firebase deploy --only hosting


デプロイが実行されます。公開URLも表示されます。

firebase deploy --only hosting

=== Deploying to 'test-7521e'...

i  deploying hosting
i  hosting[XXXX]: beginning deploy...
i  hosting[XXXX]: found 168 files in out
+  hosting[XXXX]: : file upload complete
i  hosting[XXXX]: finalizing version...
+  hosting[XXXX]: version finalized
i  hosting[XXXX]: releasing new version...
+  hosting[XXXX]: release complete

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/XXXX/overview
Hosting URL: https://XXXX.web.app


タイトルとURLをコピーしました