Newsletter with vercel

article cover

Go to your vercel dash board and choose the project which needs to be added with newsletter

A visual depiction of what is being written about

❌ Unsupported block (column_list)❌ Unsupported block (column_list)❌ Unsupported block (column_list)

You have create your vercel postgres successfully now copy your environment variables generated by vecel and lets set it in our project .env

A visual depiction of what is being written about

create a .env.local file in root directory of your project then copy the snippet and paste it in your .env.local file.

We are using prisma so we need to add the values of environment variable to our schema.prisma file.

In your existing project install the following Vercel Postgres & Prisma package

POWERSHELL
yarn add @vercel/postgres prisma
Since we are not going to write our own raw SQL code we will be using Prisma as our ORM.

To maintain our database schema we will create a prisma folder which contains prisma configuration file schema.prisma

Add the following model definitions to our schema.prisma

SCHEME
// schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["jsonProtocol"]
}
datasource db {
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL") // uses connection pooling
directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
shadowDatabaseUrl = env("POSTGRES_URL_NON_POOLING") // used for migrations
}
model Newsletter {
id String @default(cuid()) @id
name String?
email String? @unique
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @updatedAt @map(name: "updated_at")
}

Run this commend in your terminal to push the Prisma schema state to the database

POWERSHELL
npx prisma db push

We should see the following output:

SCHEME
Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma
Your database is now in sync with your Prisma schema. Done in 5.24s

We may get this error requesting us to install @prisma/client for now we will ignore it.

Error: Could not resolve @prisma/client in the current project. Please install it with [object Promise], and rerun npx prisma generate 🙏.

Now let's try adding some dummy data into our database using Prisma Studio

POWERSHELL
npx prisma studio

The prisma studio will be running on port http://localhost:5555/ after executing prisma studio commend

A visual depiction of what is being written about

Click on Newsletter table and Add record now to verify it works go to your vercel dashboard stores/postgres and select Newsletter table it will list out all available data's

A visual depiction of what is being written about

To access our database from Next.js we use Prisma Client.

POWERSHELL
yarn add @prisma/client

We need to run this commend every time when ever we update our prisma schema file is updated.

POWERSHELL
npx prisma generate

We should see the following output in our terminal:

POWERSHELL
Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma
✔ Generated Prisma Client (4.15.0 | library) to .\node_modules\@prisma\client in 66ms
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client
```
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
```

Create lib Folder and add prisma.ts file in it.

Add the following code:

TYPESCRIPT
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
let prisma: PrismaClient;
if (process.env.NODE_ENV === 'production') {
prisma = new PrismaClient();
} else {
if (!global.prisma) {
global.prisma = new PrismaClient();
}
prisma = global.prisma;
}
export default prisma;
We can import this file whenever we need to access our databases

Let's start by creating components/SubscriptionForm.tsx then add the following code

TYPESCRIPT
import { useState } from "react";
export default function SubscriptionForm() {
const [email, setEmail] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await fetch("/api/subscribe", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email }),
});
if (response.ok) {
setEmail("");
alert("Subscription successful!");
} else {
alert("An error occurred while subscribing. Please try again.");
}
} catch (error) {
alert("An error occurred while subscribing. Please try again.");
}
};
return (
<form onSubmit={handleSubmit}>
<div className="grid md:grid-cols-3 gird-cols-1 gap-4 items-center ">
<div className="md:ml-auto md:mb-6 ">
<p className="text-slate-800">
<strong>Sign up for my newsletter</strong>
</p>
</div>
<input
type="email"
placeholder="Enter your email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="
form-control
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none
"
/>
</div>
<div className="md:mr-auto mb-6">
<button
type="submit"
className="inline-block px-6 py-2 border-2
border-white text-white font-medium text-xs leading-tight
uppercase rounded hover:bg-neutral-700 bg-slate-900
focus:outline-none focus:ring-0 transition duration-150 ease-in-out"
>
Subscribe
</button>
</div>
</form>
);
}

Here what we do is getting the users mail id and sending to /api/subscribe as a post request in body then if the mail is updated in database we will show a alert

Create pages/api/subscribe.ts and add the following code which does the create operation in database using PrismaClient

TYPESCRIPT
import type { NextApiRequest, NextApiResponse } from 'next';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === 'POST') {
const { email } = req.body;
if (!email) {
return res.status(400).json({ error: 'Email is required' });
}
try {
const subscriber = await prisma.newsletter.create({
data: {
email
}
});
res.status(201).json({ message: 'Email added to the newsletter successfully.' });
} catch (error) {
return res.status(500).json({ error: 'An error occurred while adding the email to the newsletter.' });
}
} else {
res.status(405).json({ error: `The HTTP ${req.method} method is not supported at this route.` });
}
}

Now import the SubscriptionForm to where you need your get user's mail id

Example: pages/index.js
TYPESCRIPT
import SubscriptionForm from '../components/SubscriptionForm';
export default function HomePage() {
return (
<div>
<h1>Welcome to My Newsletter</h1>
<SubscriptionForm />
</div>
);
}

A visual depiction of what is being written about

A visual depiction of what is being written about

Go to your vercel storage dashboard and verify if the data is been updated.

A visual depiction of what is being written about

Share this article

Related articles