How to host Nuxt.js application on firebase with a single command
Tags: nuxt, vue, firebase, webdev
Published: 2020-01-12 11:23:36

---
title: How to host Nuxt.js application on firebase with a single command
published: true
description: A tutorial and insights into problems I came to when trying to build a simple community website where people would share individually found deals.
tags: nuxt, vue.js, firebase, webdevelopment
cover_image: https://i.ibb.co/Ttwb8F0/firebase-nuxt-header-dev-to.png
---

# Introduction

I wished to copy a famous website that is lingering across Europe where people share their found deals with others and like that save money (its pepper.com in case anyone is wondering (not that i'm doing this as an ad or anything)). 

Therefore I set myself with a task - to learn Nuxt.js as it is a server side rendered (SSR) framework that encapsulates a Node.js server with Vue.js and renders content that is possible to be crawled by google's crawlers in order to be indexed and listed on the search giant.

You can check the demo at:
>https://dealas-962d3.firebaseapp.com/

You can fine the full repository at:
>https://github.com/slushnys/dealas

## Challenges I faced in order to finish my application

- Understanding the lifecycles of SSR and how to inject data into a page for it to be rendered and be indexed.
- Understand firebase functions.
- Learn how to host the code and functions to the cloud on google firebase.

## What I have learned

### Async data

Even though it's pretty clear in the documentation of nuxt.js (https://nuxtjs.org/guide/async-data) that this method is to retrieve the data of certain resource before the component is rendered.

Also, at that point of time you don't have the access to `this` within that method, as per documentation:

`
You do `NOT` have access of the component instance through `this` inside asyncData because it is called before initiating the component.
`

Another thing I learned the hard way is that the asyncData method for retrieving information is only called for a `page` being rendered, not a regular component where you might try to be filling a select box with data from your api.

### Firebase functions

> For this part you will need to install firebase under your global npm packages ```npm i -g firebase-tools``` don't forget to login to firebase after with ```firebase login```

I had previous experience with running google cloud functions with `python` language, however I've never made myself learn how do javascript functions run on demand in Google Cloud Platform. This was about to change because i was determined to have my website deployments automated so i wouldn't need to manually do all that work.

```javascript
// functions/index.js

const functions = require("firebase-functions");
const { Nuxt } = require("nuxt-start");

const nuxtConfig = require("./nuxt.config.js");

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

const nuxt = new Nuxt(config);

let isReady = false;

async function handleRequest(req, res) {
  if (!isReady) {
    try {
      isReady = await nuxt.ready();
    } catch (error) {
      process.exit(1);
    }
  }
  await nuxt.render(req, res);
}

exports.ssrapp = functions.https.onRequest(handleRequest);

```

You might think what is that `nuxt-start` pacakge you see at the beginning of the index.js file 🤔 Well it's a package that takes away the overhead and lets you start the package without many dependencies in production.

On top of that, we don't want to render the unfinished page, therefore on our request handler function `handleRequest` we wait to see if nuxt is ready and render the full page only then when it is.

Exporting ssrapp is the most important for our application to work on cloud as the each request will be handled by our `handleRequest` function which is assigned to our google functions `onRequest` event listener.

But wait... who's going to call the ssrapp function when it's on the cloud and when will google cloud function know which function to call?

#### Firebase configuration

In this section I'll discuss my learning points on deploying nuxt to the cloud which in my case - was my biggest painpoint to figuring out why my application doesn't work. Lets first take a look at my `./firebase.json` configuration file.

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

```

There are different configurations for different services here as you can see by the keys of this dictionary, it includes - firestore, functions and hosting.


>**firestore** keys' value includes the rules that you can set up for your firestore real time database. This should include your configuration to disable users reading your database for malicious purposes.

>**functions** keys' value includes predeploy command, exactly this caused me the most of my troubles as I've taken this configuration from other tutorial I tried to apply to my use case. This resulted in my application crashing and not properly rendering when deployed. 

>**hosting** keys' value includes the predeployment script that takes files and uploads them to firebase hosting with a rewrite of source function to be the one we defined in our index.js file as `ssrapp`.

*The reason my deployments were failing:* this was actually pretty simple yet took me the longest to figure out. I have overwritten my `nuxt.config.js` buildDir default value of .nuxt/ to `../nuxt/`. This in result caused some errors building some packages of 3rd party libraries I was using (especially Vuetify). I really hope this saves time to someone who's trying to deploy their website on firebase.

I haven't figured put much time soon after to figure out why the deployments weren't successful with a custom build directory of nuxt after I finally deployed my application, therefore I'm not going to contemplate on this.

# Conclusion

It was a fun experience creating a Nuxt.js web application which is quite a powerful tool that one can use for basically any development needs, from a small website, to a bigger and meaner application release to production. Firebase also gives a very flexible real time database events that your application can listen on demand whenever certain action happens.

What challenges have you faced while trying to use Nuxt or Firebase? Let me know in the comment section.

#### Bonus

I've experimented with TypeScript so I refactored the repository to have typescript implementation of nuxt and new Vue 3 composition-api including it in `ikelti.vue` file if anyones interested in checking out how that integrates, i would be keep to receive some feedback.