Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions .github/workflows/build_reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ env:
# disable backtrace for test snapshots
RUST_BACKTRACE: 0

TURBO_TEAM: 'vercel'
TURBO_TEAM: 'vtest314-next-e2e-tests'
TURBO_CACHE: 'remote:rw'
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TOKEN: ${{ secrets.TURBO_REMOTE_CACHE_TOKEN }}

NEXT_TELEMETRY_DISABLED: 1
# allow not skipping install-native postinstall script if we don't have a binary available already
Expand Down
7 changes: 6 additions & 1 deletion examples/with-mysql/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
# env files
.env
.env*.local

# vercel
Expand All @@ -38,3 +40,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# prisma
/lib/generated/
67 changes: 30 additions & 37 deletions examples/with-mysql/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Next.js + MySQL
# Next.js + PlanetScale MySQL

This is a [Next.js](https://nextjs.org/) project that uses [Prisma](https://www.prisma.io/) to connect to a [PlanetScale](https://planetscale.com/) MySQL database and [Tailwind CSS](https://tailwindcss.com/) for styling.
This is a [Next.js](https://nextjs.org/) project that uses [Prisma](https://www.prisma.io/) to connect to a [PlanetScale MySQL database](https://planetscale.com/) and [Tailwind CSS](https://tailwindcss.com/) for styling.

> **Using PlanetScale Postgres?** Check out the [Next.js and Postgres Starter Template](https://github.com/vercel/postgres-next-starter) for a PostgreSQL-based template.

## Demo

Expand All @@ -16,24 +18,27 @@ https://next-mysql.vercel.app
pscale auth login
```

## Set up the database
## Set Up the Database

Create a new database with the following command:

```sh
pscale database create <DATABASE_NAME>
pscale database create <DATABASE_NAME> --engine mysql
```

> A branch, `main`, was automatically created when you created your database, so you can use that for `BRANCH_NAME` in the steps below.

## Set up the starter Next.js app
## Set Up the Starter Next.js App

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:
Run [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with your preferred package manager to bootstrap the example:

```bash
npx create-next-app --example with-mysql nextjs-mysql
```

<details>
<summary>Or use yarn / pnpm / bun</summary>

```bash
yarn create next-app --example with-mysql nextjs-mysql
```
Expand All @@ -42,6 +47,12 @@ yarn create next-app --example with-mysql nextjs-mysql
pnpm create next-app --example with-mysql nextjs-mysql
```

```bash
bunx create-next-app --example with-mysql nextjs-mysql
```

</details>

Next, you'll need to create a database username and password through the CLI to connect to your application. If you'd prefer to use the dashboard for this step, you can find those instructions in the [Connection Strings documentation](https://docs.planetscale.com/concepts/connection-strings#creating-a-password) and then come back here to finish setup.

First, create your `.env` file by renaming the `.env.example` file to `.env`:
Expand All @@ -61,12 +72,12 @@ pscale password create <DATABASE_NAME> <BRANCH_NAME> <PASSWORD_NAME>
Take note of the values returned to you, as you won't be able to see this password again.

```text
Password production-password was successfully created.
Password <PASSWORD_NAME> was successfully created in <DIRECTORY_NAME>.
Please save the values below as they will not be shown again

NAME USERNAME ACCESS HOST URL ROLE PLAIN TEXT
--------------------- -------------- ----------------------------------- ------------------ -------------------------------------------------------
production-password xxxxxxxxxxxxx xxxxxx.us-east-2.psdb.cloud Can Read & Write pscale_pw_xxxxxxx
NAME USERNAME ACCESS HOST URL ROLE PLAIN TEXT
---------------- -------------- ----------------------------- ----------------- -----------------------------
<PASSWORD_NAME> xxxxxxxxxxxxx xxxxxx.us-east-2.psdb.cloud Can Read & Write pscale_pw_xxxxxxx
```

You'll use these properties to construct your connection string, which will be the value for `DATABASE_URL` in your `.env` file. Update the `DATABASE_URL` property with your connection string in the following format:
Expand All @@ -75,53 +86,35 @@ You'll use these properties to construct your connection string, which will be t
mysql://<USERNAME>:<PLAIN_TEXT_PASSWORD>@<ACCESS_HOST_URL>/<DATABASE_NAME>?sslaccept=strict
```

Push the database schema to your PlanetScale database using Prisma.

```bash
npx prisma db push
```

```bash
yarn prisma db push
```
Generate the Prisma Client:

```bash
pnpm prisma
npx prisma generate
```

Run the seed script to populate your database with `Product` and `Category` data.
Push the database schema to your PlanetScale database using Prisma:

```bash
npm run seed
npx prisma db push
```

```bash
yarn seed
```
Run the seed script to populate your database with `Product` and `Category` data:

```bash
pnpm seed
npx prisma db seed
```

## Run the App

Run the app with following command:
Run the app with the following command:

```bash
npm run dev
```

```bash
yarn dev
```

```bash
pnpm dev
```

Open your browser at [localhost:3000](localhost:3000) to see the running application.
Open your browser at [localhost:3000](http://localhost:3000) to see the running application.

## Deploy your own
## Deploy Your Own

After you've got your application running locally, it's time to deploy it. To do so, you'll need to promote your database branch (`main` by default) to be the production branch ([read the branching documentation for more information](https://docs.planetscale.com/concepts/branching)).

Expand Down
1 change: 1 addition & 0 deletions examples/with-mysql/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "tailwindcss";
19 changes: 19 additions & 0 deletions examples/with-mysql/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Metadata } from "next";
import "./globals.css";

export const metadata: Metadata = {
title: "PlanetScale MySQL + Next.js",
description: "A Next.js app using Prisma with PlanetScale MySQL",
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
24 changes: 24 additions & 0 deletions examples/with-mysql/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import prisma from "@/lib/prisma";
import { Product } from "@/components/Product";

export default async function Home() {
const products = await prisma.product.findMany({
include: {
category: true,
},
});

return (
<main className="p-10 mx-auto max-w-4xl">
<h1 className="text-6xl font-bold mb-4 text-center">Next.js Starter</h1>
<p className="mb-20 text-xl text-center">
Shop from the hottest items in the world
</p>
<div className="grid md:grid-cols-3 sm:grid-cols-2 grid-cols-1 justify-items-center gap-4">
{products.map((product) => (
<Product key={product.id} product={product} />
))}
</div>
</main>
);
}
31 changes: 0 additions & 31 deletions examples/with-mysql/components/Product.js

This file was deleted.

37 changes: 37 additions & 0 deletions examples/with-mysql/components/Product.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Image from "next/image";
import type {
Product as ProductType,
Category,
} from "@/lib/generated/prisma/client";

type ProductWithCategory = ProductType & {
category: Category | null;
};

export function Product({ product }: { product: ProductWithCategory }) {
const { name, description, price, image, category } = product;

return (
<div className="max-w-[250px] rounded overflow-hidden shadow-lg">
<Image
className="w-full object-cover"
width={250}
height={250}
src={image}
alt={name}
/>
<div className="px-6 py-4">
<div className="font-bold text-xl mb-2">{name}</div>
<p className="text-gray-700 text-base">{description}</p>
<p className="text-gray-900 text-xl">${price.toString()}</p>
</div>
<div className="px-6 pt-4 pb-2">
{category && (
<span className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">
{category.name}
</span>
)}
</div>
</div>
);
}
14 changes: 0 additions & 14 deletions examples/with-mysql/lib/prisma.js

This file was deleted.

21 changes: 21 additions & 0 deletions examples/with-mysql/lib/prisma.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PrismaPlanetScale } from "@prisma/adapter-planetscale";
import { PrismaClient } from "./generated/prisma/client";
import { fetch as undiciFetch } from "undici";

const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};

function createPrismaClient() {
const adapter = new PrismaPlanetScale({
url: process.env.DATABASE_URL,
fetch: undiciFetch,
});
return new PrismaClient({ adapter });
}

const prisma = globalForPrisma.prisma ?? createPrismaClient();

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;

export default prisma;
4 changes: 0 additions & 4 deletions examples/with-mysql/next.config.js

This file was deleted.

7 changes: 7 additions & 0 deletions examples/with-mysql/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
/* config options here */
};

export default nextConfig;
27 changes: 19 additions & 8 deletions examples/with-mysql/package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
{
"type": "module",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"seed": "node prisma/seed.js"
"lint": "next lint"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"dependencies": {
"@prisma/client": "3.10.0",
"@prisma/adapter-planetscale": "latest",
"@prisma/client": "latest",
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
"react": "^19.0.0",
"react-dom": "^19.0.0",
"undici": "^7"
},
"devDependencies": {
"autoprefixer": "10.4.2",
"postcss": "8.4.7",
"prisma": "3.10.0",
"tailwindcss": "3.0.23"
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"dotenv": "^16",
"prisma": "latest",
"tailwindcss": "^4",
"tsx": "^4",
"typescript": "^5"
}
}
5 changes: 0 additions & 5 deletions examples/with-mysql/pages/_app.js

This file was deleted.

16 changes: 0 additions & 16 deletions examples/with-mysql/pages/api/products.js

This file was deleted.

Loading
Loading