Attaching database to static site on Next.js and Vercel
Moeki Kawakami
Posted on November 8, 2022
I recently added a like button to my website.
In the past, if I wanted to add a little database processing to a static website, I either had to change the app implementation from a static site generator to a server-side framework like Ruby on Rails, or I had to have another DB server and hit API. Site functionality affected the entire architecture.
However, this experiment made us realize that Next.js and Vercel have a very application-first philosophy that can extend the functionality of a website without major architectural changes.
This is largely due to the fact that Vercel is able to receive the Rest API with Serverless Function.
Let's see.
First, we will implement the UI.
import { useState } from 'react'
import { MdThumbUp } from 'react-icons/md'
export default function Component(props) {
const [likeCount, setLikeCount] = useState(props.likeCount)
const [liked, setLiked] = useState(false)
const createLike = async () => {
if (liked === false) {
// TODO: create like
setLikeCount(likeCount + 1)
setLiked(true)
}
}
return (
<>
<span className={liked ? 'text-blue-500' : undefined}>
<span
onClick={createLike}
className="ml-4 mb-4 align-bottom cursor-pointer inline-block bg-white border-2 border-gray-800 rounded-full px-4">
<MdThumbUp className="inline mr-2" />
{likeCount}
</span>
</span>
<span className="inline-block ml-4 mb-4 align-bottom">
{liked && <span>Thank you!</span>}
</span>
</>
)
}
Where the DB is concerned, TODO: create like
const createLike = async () => {
if (liked === false) {
// TODO: create like
setLikeCount(likeCount + 1)
setLiked(true)
}
}
and likeCount
.
const [likeCount, setLikeCount] = useState(props.likeCount)
Now, we will prepare PostgreSQL and Prisma, an ORM made with Node.js.
yarn add prisma
This is prisma/schema.prisma
, schema file.
Like model is very simple.
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Like {
id Int @id @default(autoincrement())
}
And we will generate and aplly migrations.
yarn run prisma migrate dev
Next, we will generate prisma client to access database.
yarn run prisma generate
Then, we will implement the part that actually accesses the database.
If you export a function called getServerSideProps
(Server-Side Rendering) from a page, Next.js will pre-render this page on each request using the data returned by getServerSideProps
. So, we get like count on here and set props.
// pages/index.js
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export default function Home(props) {
//...
}
export async function getServerSideProps(context) {
const likeCount = await prisma.like.count()
return {
props: { likeCount: likeCount }
}
}
Then the update part of like. We will create post endpoint to create a like record
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export default async function handler(req, res) {
const like = await prisma.like.create()
res.status(201).json(like)
}
and add the fetching process to callback.
const createLike = async () => {
if (liked === false) {
fetch('/api/like/create')
setLikeCount(likeCount + 1)
setLiked(true)
}
}
This concludes the implementation part.
Next, let's set up Vercel to use Prisma and prepare a PostgreSQL server.
I have a PostgreSQL server at render.com.
Cloud Application Hosting for Developers | Render
Prisma has put together a method for deploying to
Vercel, so I will try to follow this.
How to deploy a Prisma app to Vercel
// package.json
{
"scripts": {
"vercel-build": "prisma generate && prisma migrate deploy && next build"
}
}
Then, we will environment variable for Prisma to Vercel.
That's it!
We were able to add DB-based functionality to our site without major architectural changes. It was a very freeing development experience, and I think I understand a little bit of what Next.js and Vercel are trying to do.
Thank you for reading.
Posted on November 8, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.