With some additional configuration, you can build on the basic framework-aware CLI functionality to extend integration support to frameworks other than Angular and Next.js.
Before you begin
Before you get started deploying your app to Firebase, review the following requirements and options:
- Firebase CLI version 12.1.0 or later. Make sure to install the CLI using your preferred method.
- Optional: Billing enabled on your Firebase project (required if you plan to use SSR)
Initialize Firebase
To get started, initialize Firebase for your framework project.
Use the Firebase CLI for a new project, or modify firebase.json
for an
existing project.
Initialize a new project
- In the Firebase CLI, enable the web frameworks preview:
firebase experiments:enable webframeworks
Run the initialization command from the CLI and then follow the prompts:
firebase init hosting
Answer yes to "Do you want to use a web framework? (experimental)"
Choose your hosting source directory; this could be an existing web app.
If prompted, choose Express.js / custom
Initialize an existing project
Change your hosting config in firebase.json
to have a source
option, rather
than a public
option. For example:
{
"hosting": {
"source": "./path-to-your-express-directory"
}
}
Serve static content
Before deploying static content, you'll need to configure your application.
Configure
In order to know how to deploy your application, the Firebase CLI needs to be
able to both build your app and know where your tooling places the assets
destined for Hosting. This is accomplished with the npm build script and CJS
directories directive in package.json
.
Given the following package.json:
{
"name": "express-app",
"version": "0.0.0",
"scripts": {
"build": "spack",
"static": "cp static/* dist",
"prerender": "ts-node prerender.ts"
},
…
}
The Firebase CLI only calls your build script, so you’ll need to ensure that your build script is exhaustive.
{
"name": "express-app",
"version": "0.0.0",
"scripts": {
"build": "spack && npm run static && npm run prerender",
"static": "cp static/* dist",
"prerender": "ts-node prerender.ts"
},
…
}
If your framework doesn’t support pre-rendering out of the box, consider using a tool like Rendertron. Rendertron will allow you to make headless Chrome requests against a local instance of your app, so you can save the resulting HTML to be served on Hosting.
Finally, different frameworks and build tools store their artifacts in different
places. Use directories.serve
to tell the CLI where your build script is
outputting the resulting artifacts:
{
"name": "express-app",
"version": "0.0.0",
"scripts": {
"build": "spack && npm run static && npm run prerender",
"static": "cp static/* dist",
"prerender": "ts-node prerender.ts"
},
"directories": {
"serve": "dist"
},
…
}
Deploy
After configuring your app, you can serve static content with the standard deployment command:
firebase deploy
Serve Dynamic Content
To serve your Express app on Cloud Functions for Firebase, ensure that your Express app (or express-style URL handler) is exported in such a way that Firebase can find it after your library has been npm packed.
To accomplish this, ensure that your files
directive includes everything
needed for the server, and that your main entry point is set up correctly in
package.json
:
{
"name": "express-app",
"version": "0.0.0",
"scripts": {
"build": "spack && npm run static && npm run prerender",
"static": "cp static/* dist",
"prerender": "ts-node tools/prerender.ts"
},
"directories": {
"serve": "dist"
},
"files": ["dist", "server.js"],
"main": "server.js",
...
}
Export your express app from a function named app
:
// server.js
export function app() {
const server = express();
…
return server;
}
Or if you’d rather export an express-style URL handler, name it handle
:
export function handle(req, res) {
res.send(‘hello world’);
}
Deploy
firebase deploy
This deploys your static content to Firebase Hosting and allows Firebase to fall back to your Express app hosted on Cloud Functions for Firebase.
Optional: integrate with Firebase Authentication
The web framework-aware Firebase deploy tooling will automatically keep client
and server state in sync using cookies. To access the authentication context,
the Express res.locals
object optionally contains an authenticated Firebase
App instance (firebaseApp
) and the currently signed in User (currentUser
).