Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 7 additions & 75 deletions examples/prisma-postgres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,90 +64,22 @@ bun install

### 2. Create a Prisma Postgres instance

Run the following command in your terminal:
Run the following command to create a Prisma Postgres database and append the `DATABASE_URL` to your `.env`:

```
npx prisma init --db
npx create-db@latest --env >> .env
```

If you don't have a [Prisma Data Platform](https://console.prisma.io/) account yet, or if you are not logged in, the command will prompt you to log in using one of the available authentication providers. A browser window will open so you can log in or create an account. Return to the CLI after you have completed this step.

Once logged in (or if you were already logged in), the CLI will prompt you to:

1. Select a **region** (e.g. `us-east-1`)
1. Enter a **project name**

After successful creation, you will see output similar to the following:

<details>

<summary>CLI output</summary>

```terminal
Let's set up your Prisma Postgres database!
? Select your region: ap-northeast-1 - Asia Pacific (Tokyo)
? Enter a project name: testing-migration
✔ Success! Your Prisma Postgres database is ready ✅

We found an existing schema.prisma file in your current project directory.

--- Database URL ---

Connect Prisma ORM to your Prisma Postgres database with this URL:

prisma+postgres://accelerate.prisma-data.net/?api_key=ey...

--- Next steps ---

Go to https://pris.ly/ppg-init for detailed instructions.

1. Install and use the Prisma Accelerate extension
Prisma Postgres requires the Prisma Accelerate extension for querying. If you haven't already installed it, install it in your project:
npm install @prisma/extension-accelerate

...and add it to your Prisma Client instance:
import { withAccelerate } from "@prisma/extension-accelerate"

const prisma = new PrismaClient().$extends(withAccelerate())

2. Apply migrations
Run the following command to create and apply a migration:
npx prisma migrate dev

3. Manage your data
View and edit your data locally by running this command:
npx prisma studio

...or online in Console:
https://console.prisma.io/{workspaceId}/{projectId}/studio

4. Send queries from your app
If you already have an existing app with Prisma ORM, you can now run it and it will send queries against your newly created Prisma Postgres instance.

5. Learn more
For more info, visit the Prisma Postgres docs: https://pris.ly/ppg-docs
```

</details>

Locate and copy the database URL provided in the CLI output. Then, follow the instructions in the next step to create a `.env` file in the project root.

### 3. Setup your `.env` file

You now need to configure your database connection via an environment variable.

First, create an `.env` file:

```bash
touch .env
```

Then update the `.env` file by replacing the existing `DATABASE_URL` value with the one you previously copied. It will look similar to this:
This command writes the `DATABASE_URL` to your `.env`. Verify it contains a value like:

```bash
DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=PRISMA_POSTGRES_API_KEY"
```

If not, create `.env` and add the `DATABASE_URL` manually.

### 4. Migrate the database

Run the following commands to set up your database and Prisma schema:
Expand Down Expand Up @@ -232,7 +164,7 @@ Once the server is running, visit `http://localhost:3000` to start using the app

The app includes the following routes:

- `/`: Display the thee most recent posts
- `/`: Display the three most recent posts
- `/posts`: Paginated list view of all posts
- `/posts/new`: Create a new post
- `/users/new`: Create a new user
Expand All @@ -242,7 +174,7 @@ The app includes the following routes:

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fprisma-orm&env=DATABASE_URL&envDescription=Add%20your%20PRISMA%20POSTGRES%20database%20url&project-name=prisma-orm-app&repository-name=prisma-orm)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fprisma-postgres&env=DATABASE_URL&envDescription=Add%20your%20PRISMA%20POSTGRES%20database%20url&project-name=prisma-postgres-app&repository-name=prisma-postgres)

## Additional information

Expand Down
10 changes: 5 additions & 5 deletions examples/prisma-postgres/app/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ import Link from "next/link";

export default function Header() {
return (
<header className="w-full bg-white shadow-md py-4 px-8">
<header className="w-full bg-card shadow-md py-4 px-8 border-b border-border">
<nav className="flex justify-between items-center">
<Link
href="/"
className="text-xl font-bold text-gray-800 hover:text-blue-600 transition-colors"
className="text-xl font-bold text-foreground hover:text-primary transition-colors"
>
Superblog
</Link>
<div className="space-x-4">
<Link href="/posts" className="text-blue-600 hover:underline">
<Link href="/posts" className="text-primary hover:underline">
Posts
</Link>
<Link href="/posts/new" className="text-blue-600 hover:underline">
<Link href="/posts/new" className="text-primary hover:underline">
New Post
</Link>
<Link
href="/users/new"
className="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition"
className="bg-primary text-white px-4 py-2 rounded-lg hover:brightness-110 transition"
>
New User
</Link>
Expand Down
22 changes: 18 additions & 4 deletions examples/prisma-postgres/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss";

:root {
--background: #ffffff;
--foreground: #171717;
--primary: #2563eb; /* blue-600 */
--card: #ffffff;
--border: #e5e7eb; /* gray-200 */
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-primary: var(--primary);
--color-card: var(--card);
--color-border: var(--border);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
--primary: #60a5fa; /* blue-400 for dark */
--card: #0f1115;
--border: #374151; /* gray-700 */
}
}

body {
color: var(--foreground);
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
51 changes: 26 additions & 25 deletions examples/prisma-postgres/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,37 @@ export default async function Home() {
});

return (
<div className="min-h-screen bg-gray-50 flex flex-col items-center justify-center -mt-16 p-8">
<h1 className="text-5xl font-extrabold mb-12 text-[#333333]">
<div className="min-h-screen bg-background flex flex-col items-center justify-center -mt-16 p-8">
<h1 className="text-5xl font-extrabold mb-12 text-foreground">
Recent Posts
</h1>
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3 w-full max-w-6xl">
{posts.map((post) => (
<Link key={post.id} href={`/posts/${post.id}`} className="group">
<div className="border rounded-lg shadow-md bg-white p-6 hover:shadow-lg transition-shadow duration-300">
<h2 className="text-2xl font-semibold text-blue-600 group-hover:underline mb-2">
{post.title}
</h2>
<p className="text-sm text-gray-500">
by {post.author ? post.author.name : "Anonymous"}
</p>
<p className="text-xs text-gray-400 mb-4">
{new Date(post.createdAt).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}
</p>
<div className="relative">
<p className="text-gray-700 leading-relaxed line-clamp-2">
{post.content || "No content available."}
{posts &&
posts.map((post) => (
<Link key={post.id} href={`/posts/${post.id}`} className="group">
<div className="border rounded-lg shadow-md bg-card border-border p-6 hover:shadow-lg transition-shadow duration-300">
<h2 className="text-2xl font-semibold text-primary group-hover:underline mb-2">
{post.title}
</h2>
<p className="text-sm text-foreground/70">
by {post.author ? post.author.name : "Anonymous"}
</p>
<div className="absolute bottom-0 left-0 w-full h-12 bg-gradient-to-t from-gray-50 to-transparent" />
<p className="text-xs text-foreground/70 mb-4">
{new Date(post.createdAt).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}
</p>
<div className="relative">
<p className="text-foreground leading-relaxed line-clamp-2">
{post.content || "No content available."}
</p>
<div className="absolute bottom-0 left-0 w-full h-12 bg-linear-to-t from-background to-transparent" />
</div>
</div>
</div>
</Link>
))}
</Link>
))}
</div>
</div>
);
Expand Down
14 changes: 7 additions & 7 deletions examples/prisma-postgres/app/posts/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ export default async function Post({
}

return (
<div className="min-h-screen bg-gray-50 flex flex-col items-center justify-center p-8">
<article className="max-w-3xl w-full bg-white shadow-lg rounded-lg p-8">
<div className="min-h-screen bg-background flex flex-col items-center justify-center p-8">
<article className="max-w-3xl w-full bg-card border border-border shadow-lg rounded-lg p-8">
{/* Post Title */}
<h1 className="text-5xl font-extrabold text-blue-600 mb-4">
<h1 className="text-5xl font-extrabold text-primary mb-4">
{post.title}
</h1>

{/* Author Information */}
<p className="text-lg text-gray-600 mb-4">
<p className="text-lg text-foreground/70 mb-4">
by{" "}
<span className="font-medium text-gray-800">
<span className="font-medium text-foreground">
{post.author?.name || "Anonymous"}
</span>
</p>

{/* Content Section */}
<div className="text-lg text-gray-800 leading-relaxed space-y-6 border-t pt-6">
<div className="text-lg text-foreground leading-relaxed space-y-6 border-t border-border pt-6">
{post.content ? (
<p>{post.content}</p>
) : (
<p className="italic text-gray-500">
<p className="italic text-foreground/70">
No content available for this post.
</p>
)}
Expand Down
40 changes: 19 additions & 21 deletions examples/prisma-postgres/app/posts/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,18 @@ export default function NewPost() {
const title = formData.get("title") as string;
const content = formData.get("content") as string;

const postData = authorEmail
? {
title,
content,
author: {
connect: {
email: authorEmail,
},
},
}
: {
title,
content,
};
if (!authorEmail) {
throw new Error("Author email is required");
}

await prisma.post.create({
data: postData,
data: {
title,
content,
author: {
connect: { email: authorEmail },
},
},
});

revalidatePath("/posts");
Expand All @@ -38,15 +33,17 @@ export default function NewPost() {

return (
<div className="max-w-2xl mx-auto p-4">
<h1 className="text-2xl font-bold mb-6">Create New Post</h1>
<h1 className="text-2xl font-bold mb-6 text-foreground">
Create New Post
</h1>
<Form action={createPost} className="space-y-6">
<div>
<label
htmlFor="title"
className="flex text-lg font-medium mb-2 items-center"
>
Title
<span className="ml-2 px-2 py-1 text-xs font-semibold text-white bg-gray-500 rounded-lg">
<span className="ml-2 px-2 py-1 text-xs font-semibold text-white bg-foreground/70 rounded-lg">
Required
</span>
</label>
Expand All @@ -56,7 +53,7 @@ export default function NewPost() {
name="title"
required
placeholder="Enter your post title ..."
className="w-full px-4 py-2 border rounded-lg"
className="w-full px-4 py-2 border border-border bg-card text-foreground rounded-lg"
/>
</div>
<div>
Expand All @@ -68,7 +65,7 @@ export default function NewPost() {
name="content"
placeholder="Write your post content here ..."
rows={6}
className="w-full px-4 py-2 border rounded-lg"
className="w-full px-4 py-2 border border-border bg-card text-foreground rounded-lg"
/>
</div>
<div>
Expand All @@ -83,12 +80,13 @@ export default function NewPost() {
id="authorEmail"
name="authorEmail"
placeholder="Enter the email of the author here ..."
className="w-full px-4 py-2 border rounded-lg"
required
className="w-full px-4 py-2 border border-border bg-card text-foreground rounded-lg"
/>
</div>
<button
type="submit"
className="w-full bg-blue-500 text-white py-3 rounded-lg hover:bg-blue-600"
className="w-full bg-primary text-white py-3 rounded-lg hover:brightness-110"
>
Create Post
</button>
Expand Down
Loading
Loading