
Nuxt.js (v2), Firestore & SSR 🔥
This article will help you integrate Firebase Firestore into a Nuxt.js project while keeping the server-side rendering capabilities that come with the amazing Universal SSR mode of Nuxt.js.
And all of this without the need for any additional libraries other than Google’s own Firebase SDK.
❗️️️️️️❗️️️️️️ Update: If you like it even simpler: I wrote a small Nuxt module nuxt-fire (now @nuxtjs/firebase)
that has made it to be an official nuxtjs module and makes integrating Firebase into your Nuxt 2.0 project even easier!
Check it out: https://firebase.nuxtjs.org
❗️️ This article is based on Nuxt.js v2.x and might not be valid for older versions. For an article covering the same for Nuxt.js v1.x, check out the following article:
https://medium.com/@pascalluther/nuxt-js-v1-firestore-and-ssr-73e3140574fc
1) Install Nuxt.js
⏭ skip to section 2 if you already have a Nuxt.js project running ⏭
Follow the instructions on the link below to create a basic nuxt app:
https://github.com/nuxt/create-nuxt-app
npx create-nuxt-app <my-project>
❗️️ Make sure to replace “<project-name>” with your project-name!
You can choose which options you like yourself, but make sure to have rendering mode “universal” applied so it is a SSR project.
? Project name nuxt2-firestore
? Project description My ultimate Nuxt.js project
? Use a custom server framework none
? Use a custom UI framework none
? Choose rendering mode Universal ❗️️❗️️❗️️
? Use axios module no
? Use eslint no
? Use prettier no
? Author name Pascal
? Choose a package manager npm
After following the installation instruction you should be able to run your project and see the following:

2) Install the Firebase SDK
⏭ skip to section 3 if you already have the Firebase SDK installed ⏭
Now let’s install the Firebase SDK. Do this with the following command:
npm install firebase --save
This is all the dependencies you will need. In your packages.json file you should see the below:
"dependencies": {
"cross-env": "^5.2.0",
"firebase": "^5.5.6",
"nuxt": "^2.0.0"
},
The starter template comes with Nuxt v.2.0.0. Change that to ^2.2.0 or higher and then run npm install to update to a more recent version, just for the sake of not using a rather old version.
This article was written with the following two versions:
"dependencies": {
"cross-env": "^5.2.0",
"firebase": "^5.5.6",
"nuxt": "^2.2.0"
},
3) Initiate the Firebase SDK
Now let’s finally write some code. 🎉
We want to make sure that the Firebase SDK is initiated on the server, so the server can get data from Firestore and render it before it gets sent to the client.
In your /plugins folder, create a file called firebase.js and add the following code:
import firebase from 'firebase/app'
import 'firebase/firestore'if (!firebase.apps.length) { const config = {
apiKey: '<replace this>',
authDomain: '<replace this>',
databaseURL: '<replace this>',
projectId: '<replace this>',
storageBucket: '<replace this>',
messagingSenderId: '<replace this>'
} firebase.initializeApp(config)
firebase.firestore().settings({timestampsInSnapshots: true})
}const fireDb = firebase.firestore()export {fireDb}
❗️️ Make sure to replace “<replace this>” with your Firebase credentials. I will refrain from explaining how to setup a Firebase project and getting the credentials, since this is well documented in the Firebase docs here.
Now we add the plugin to our nuxt.config.js like so:
plugins: [
'~/plugins/firebase.js'
],
4) Write to Firestore
Now we can already write something to Firestore! 🤩
Delete all content in your pages/index.vue file and replace it with the following:
<template>
<section class="container"><div>
<h2>
Write to Firestore.
</h2>
<div>
<button @click="writeToFirestore" :disabled="writeSuccessful">
<span v-if="!writeSuccessful">Write now</span>
<span v-else>Successful!</span>
</button>
</div>
</div></section>
</template><script>
import {fireDb} from '~/plugins/firebase.js' export default {
data() {
return {
writeSuccessful: false
}
},
methods: {
async writeToFirestore() {
const ref = fireDb.collection("test").doc("test")
const document = {
text: "This is a test message."
} try {
await ref.set(document)
} catch (e) {
// TODO: error handling
console.error(e)
}
this.writeSuccessful = true
}
}
}
</script><style>
.container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
Your app should now look like this:

When clicking on “Write now”, the button should change to “Successful!” and there should be a collection “test” with a document named “test” in your Firestore database:

❗️️ If this did not work, make sure your project and Firestore is set up properly. You might have to setup an instance of Firestore first. Also, make sure that your security rules are defined as public (but change that later on!).
5) Read from Firestore
Now let’s read what we wrote to the Firestore!
Add a second <div> below the “Write to Firestore”-Div like so:
<div>
<h2>
Read from Firestore.
</h2>
<div>
<button @click="readFromFirestore" :disabled="readSuccessful">
<span v-if="!readSuccessful">Read now</span>
<span v-else>Successful!</span>
</button>
<p>{{text}}</p>
</div>
</div>
Add the attributes readSuccessful and text to your data, so it looks like this:
data() {
return {
writeSuccessful: false,
readSuccessful: false,
text: ""
}
},
And finally add a method to read the data from Firestore like below:
async readFromFirestore() {
const ref = fireDb.collection("test").doc("test") let snap
try {
snap = await ref.get()
} catch (e) {
// TODO: error handling
console.error(e)
}
this.text = snap.data().text
this.readSuccessful = true
}
Now try it out!
After clicking both buttons, your app should look like this:

That’s it. You can now already read and write to Firebase Firestore with Nuxt.js!
But wait… that is a client side request to Firestore. 😱 That has nothing to do with SSR.
Well, read on.
6) Server-side Rendering (SSR)
If you want your page to render the data from Firestore already on server-side, simply do it as you are used to with Nuxt.js — by adding an asyncData function like so (more Infos here):
async asyncData({app, params, error}) {
const ref = fireDb.collection("test").doc("test") let snap
try {
snap = await ref.get()
} catch (e) {
// TODO: error handling
console.error(e)
}
return {
text: snap.data().text
}
},
Now if you reload your page, the call to Firebase will be done server side.
That’s already it! We successfully implemented Nuxt.js with Firebase Firestore! 🎉🎉
Additional Content
Entire index.vue:
<template>
<section class="container"> <div>
<h2>
Write to Firestore.
</h2>
<div>
<button @click="writeToFirestore" :disabled="writeSuccessful">
<span v-if="!writeSuccessful">Write now</span>
<span v-else>Successful!</span>
</button>
</div>
</div> <div>
<h2>
Read from Firestore.
</h2>
<div>
<button @click="readFromFirestore" :disabled="readSuccessful">
<span v-if="!readSuccessful">Read now</span>
<span v-else>Successful!</span>
</button>
<p>{{text}}</p>
</div>
</div> </section>
</template><script>
import {fireDb} from '~/plugins/firebase.js' export default {
data() {
return {
writeSuccessful: false,
readSuccessful: false,
text: ""
}
},
async asyncData({app, params, error}) {
const ref = fireDb.collection("test").doc("test") let snap
try {
snap = await ref.get()
} catch (e) {
// TODO: error handling
console.error(e)
}
return {
text: snap.data().text
}
},
methods: {
async writeToFirestore() {
const ref = fireDb.collection("test").doc("test")
const document = {
text: "This is a test message."
} try {
await ref.set(document)
} catch (e) {
// TODO: error handling
console.error(e)
}
this.writeSuccessful = true
},
async readFromFirestore() {
const ref = fireDb.collection("test").doc("test") let snap
try {
snap = await ref.get()
} catch (e) {
// TODO: error handling
console.error(e)
}
this.text = snap.data().text
this.readSuccessful = true
}
}
}
</script><style>
.container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
Links:
- See entire code on GitHub:
https://github.com/lupas/nuxt2-firestore
Thanks & Credits to:
- The amazing Nuxt.js framework
- Google Firestore
- nuxt/create-nuxt-app
- Not sure anymore, but might have gotten a hint by Adriano Resende’s answer on StackOverflow, so thanks to him just in case ;-)