Create and Deploy a Next.js and FaunaDB-Powered Node.js App with ZEIT Now

Create a Next.js and FaunaDB-Powered Node.js App and deploy it with ZEIT Now.

FaunaDB is a serverless cloud database that gives you low-latency access to your app data around the world.

This guide walks you through creating a Next.js app that receives data from a Node.js API powered by FaunaDB, and how to deploy it with ZEIT Now.

Step 1: Connecting to FaunaDB

To start, you need to have created a FaunaDB account. Once logged in to FaunaDB, create a child database named zeit (names are case sensitive).

Creating a new database in the FaunaDB dashboard.

After clicking Save, you will be taken to the Database Overview page.

From here, the easiest way to create a demo schema with some data is to execute a Fauna Query Language (FQL) script file.

Select the Shell tab, then copy in this FQL script and click Run Query.

Adding data to a FaunaDB database from the dashboard using an FQL script.

After executing the script, the Collections page will present you with dummy data. You are now ready to create a connection to the database.

The Collections page on the FaunaDB dashboard after adding data to the database.

Step 2: Create an Access Key

Go to the Security page and create a new key. Enter the following data in the fields:

  • Database: zeit
  • Role: Admin
  • Key Name: access
  • Priority: 1

Once you have entered the required data, save. FaunaDB will then take you to the Keys page.

On the Keys page, you will receive a unique hash called a Secret. The Secret is your method of securely identifying yourself to the database.

Warning: This is the only time you will see this hash, so record it somewhere private. However, if the hash is lost, a new one can be created.

Create a Now Secret to store the access key received, this will be used later when accessing the database.

now secrets add FAUNADB_SECRET_KEY [your-access-key]

Adding the access key as a Now Secret.

Step 3: Creating Your Next.js App

Get started creating your Next.js by making a project directory with the required structure and moving into it:

mkdir -p faunadb-demo/pages/api && mkdir faunadb-demo/components && cd faunadb-demo

Creating and entering into the /faunadb-demo directory.

Next, initialize the project:

npm init -y

Initializing the project, this creates a package.json file.

Continue to install the FaunaDB JavaScript client which allows you to connect to, and query, the database, along with the required dependencies for Next.js:

npm i faunadb next react react-dom

Adding the faunadb, next, react and react-dom dependencies to the project.

Inside of the /pages directory, create an index.js file with the code below:

import { useEffect, useState } from 'react'
import Head from 'next/head'
import TableRow from '../components/TableRow'

export default () => {
  const [data, setData] = useState([])
  useEffect(() => {
    async function getData() {
      const res = await fetch('/api')
      const newData = await res.json()
      setData(newData)
    }
    getData()
  }, [])
  return (
    <main>
      <Head>
        <title>Next.js, FaunaDB and Node.js</title>
      </Head>
      <h1>Next.js, FaunaDB and Node.js</h1>
      <hr />
      <div className="container-scroll">
        <div className="container">
          <h2>Customer Data</h2>
          <div className="table">
            <h4>name</h4>
            <h4 className="telephone">telephone</h4>
            <h4 className="credit-card">credit card</h4>
          </div>
          {data.length > 0 ? (
            data.map(d => (
              <TableRow
                key={d.data.telephone}
                creditCard={d.data.creditCard.number}
                firstName={d.data.firstName}
                lastName={d.data.lastName}
                telephone={d.data.telephone}
              />
            ))
          ) : (
            <>
              <TableRow loading />
              <TableRow loading />
              <TableRow loading />
            </>
          )}
        </div>
      </div>
    </main>
  )
}

Adding a /pages/index.js file to the project.

Then, create a TableRow.js file inside of the /components directory with the code below:

export default ({ creditCard, firstName, loading, lastName, telephone }) => (
  <div className="table table-row">
    <p className={loading ? 'loading' : ''}>
      {firstName} {lastName}
    </p>{' '}
    <p className={`telephone ${loading ? 'loading' : ''}`}>{telephone}</p>
    <p className={`credit-card credit-card-number ${loading ? 'loading' : ''}`}>
      {creditCard && <img src="/icons/visa.svg" />}
      {creditCard}
    </p>
  </div>
)

Adding a /components/TableRow.js file to the project.

Add a build script to the package.json file which will tell ZEIT Now how to build your project:

{
  ...
  "scripts": {
    "build": "next build"
  }
}

Adding a build script to the package.json file.

Note: If you wish to use the same styles as the example app, you can find them here.

Step 4: Writing the Serverless Function

Create the Node.js API endpoint that will fetch the data from FaunaDB by adding an index.js file to the /pages/api directory.

The index.js file will act as the default endpoint for getting information from your database. The file should contain the following code:

const faunadb = require('faunadb')

// your secret hash
const secret = process.env.FAUNADB_SECRET_KEY
const q = faunadb.query
const client = new faunadb.Client({ secret })

module.exports = async (req, res) => {
  try {
    const dbs = await client.query(
      q.Map(
        // iterate each item in result
        q.Paginate(
          // make paginatable
          q.Match(
            // query index
            q.Index('all_customers') // specify source
          )
        ),
        ref => q.Get(ref) // lookup each result by its reference
      )
    )
    // ok
    res.status(200).json(dbs.data)
  } catch (e) {
    // something went wrong
    res.status(500).json({ error: e.message })
  }
}

An example /pages/api/index.js file that retrieves information from the database.

Create a now.json at the root of the project directory, this is used to make the Now Secret defined in step 2 available to the Serverless Function.

{
  "env": {
    "FAUNADB_SECRET_KEY": "@faunadb_secret_key"
  }
}

An example now.json file that makes a Now Secret available to the application.

Step 5: Deploying

With the project complete, you are ready to deploy it with ZEIT Now.

If you have not yet installed Now, you can do so by installing Now CLI.

You can now deploy the project with a single command:

now

Deploying the project with the now command.

You will be given a deployment URL, with which you can access the contents of the FaunaDB database at the /api endpoint.

To deploy your Next.js, Node.js, and FaunaDB project from a Git repository, you can use either Now for GitHub or Now for GitLab to have your project automatically deployed on every push, and aliased on push to master.



Written By
Written by danieltodonnelldanieltodonnell
Written by msweeneydevmsweeneydev
on September 19th 2019