Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deploy Nuxt SSR app to firebase through cloud functions?

I followed this medium post as a guide to host my nuxt app on firebase hosting.

The deploy goes through, however, when I then visit the url I get a Cannot GET / error message. If I check the function logs I see that the function completes with a 404 error.

This is my functions/index.js

const functions = require('firebase-functions')
const admin = require("firebase-admin")
const { Nuxt } = require('nuxt-start')
const nuxtConfig = require('./nuxt.config.js')

admin.initializeApp()

const config = {
  ...nuxtConfig,
  dev: false,
  debug: true,
  buildDir: "nuxt",
  publicPath: "public",
}

const nuxt = new Nuxt(config)

exports.ssrapp = functions.https.onRequest(async (req, res) => {
  await nuxt.ready()
  nuxt.render(req, res)
})

And this is the firebase configuration

{
  "functions": {
    "source": "functions",
    "predeploy": [
      "npm --prefix src run build && rm -rf functions/nuxt && cp -r src/nuxt/ functions/nuxt/ && cp src/nuxt.config.js functions/"
    ]
  },
  "hosting": {
    "predeploy": [
      "rm -rf public/* && mkdir -p public/_nuxt && cp -a src/nuxt/dist/client/. public/_nuxt && cp -a src/static/. public/ && cp -a public_base/. public/"
    ],
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "ssrapp"
      }
    ]
  }
}

The project structure is this

/
 /src
 /functions
 /public
 /public_base

When I run firebase deploy I do see the content of /src being copied to /functions/nuxt. For the sake of testing I also have my /functions/package.json file include all the dependencies that I have in my /src/package.json file.

How can I get this app up and running? If you need any more details, let me know.

Update #1

I tried serving hosting and functions using the command firebase serve --only functions,hosting -p 5004.

Running the server like so gave me some more insights. Specifically I got this warning message at load time that then resulted in actual error message when loading the page.

WARN  Module @firebase/app not found. Silently ignoring module as programatic usage detected

I didn't install this package in the functions directory as I did not have it in my src directory either. However, after installing it inside /functions and restarting the dev server, that warning message was gone and with it also the error I was getting on page load.

I also spotted a couple of warnings that had to do with vue, vue-server-renderer and vue-template-compiler not running the same version.

Now everything seems to be working fine!

like image 686
ilrock Avatar asked Apr 06 '20 13:04

ilrock


People also ask

Does firebase hosting support SSR?

Now, we have SSR-ready server, but since Firebase hosting can only host static assets, you can't really start a node server there. So actually you can host your server with Firebase functions and it's free! Unless you do outbound networking (Google services are free) within your function.


2 Answers

Your config and structure look right.

I also did this about a year ago with my app and I ran into the same problem. It has to do with the function code itself. I also tried using nuxt.render(req, res) (Docs) but it never worked for me so I ended up using nuxt.renderRoute(route) (Docs) instead. This worked perfectly fine.

You could change your code to something like this:

const { Nuxt } = require('nuxt')

...

exports.ssrapp = functions.https.onRequest(async (req, res) => {
  await nuxt.ready()

  const result = await nuxt.renderRoute(req.path) // Returns { html, error, redirected }
  res.send(result.html) // Sends html as response
})

This worked for me. You should consider catching any errors though. I hope this solves your problem.

This is only a work-around, if anyone knows why nuxt.render isn't working, I would be interested to know. I wasted many hours because of this with my app...

like image 80
Florian Pallas Avatar answered Oct 18 '22 08:10

Florian Pallas


I tried serving hosting and functions locally using the command firebase serve --only functions,hosting -p 5004.

By doing this I was able to spot a bunch of warnings and errors such as

FATAL 

Vue packages version mismatch:

- [email protected]
- [email protected]

This may cause things to work incorrectly. Make sure to use the same version for both.

WARN  Module @firebase/app not found. Silently ignoring module as programatic usage detected

I then made sure that those vue packages were indeed running the same version. Then I also added the @firebase/app package in /functions/package.json (that however, is not present in /src/package.json.

I run the local server again and everything worked. I then deployed to firebase and everything was working as expected.

like image 38
ilrock Avatar answered Oct 18 '22 07:10

ilrock