先執行以下指令,使用supabase、typescript和tailwind初始化下一個js專案:npx create-next-app@latest
。選擇所有預設選項:
執行以下命令安裝 prisma:
npm install prisma --save-dev
安裝 prisma 後,執行以下命令來初始化架構檔案和 .env 檔案:
npx 棱鏡熱
現在應該有一個 .env 檔案。您應該加入您的database_url 將 prisma 連接到您的資料庫。應該看起來像這樣:
// .env
DATABASE_URL=url
在你的 schema.prisma 中你應該要加入你的模型,我現在只是使用一些隨機模型:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Post {
id String @default(cuid()) @id
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId String?
}
model User {
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")
posts Post[]
@@map(name: "users")
}
現在您可以執行以下命令將資料庫與架構同步:
npx prisma 資料庫推送
為了在客戶端存取 prisma,您需要安裝 prisma 用戶端。您可以透過執行以下命令來執行此操作:
npm 安裝@prisma/client
您的客戶端也必須與您的架構同步,您可以透過執行以下命令來做到這一點:
npx prisma 生成
當您執行“npx prisma db push”時,會自動呼叫產生指令。
為了存取 prisma 用戶端,您需要建立它的一個實例,因此在 src 目錄中建立一個名為 lib 的新資料夾,並在其中新增一個名為 prisma.ts 的新檔案。
// prisma.ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default prisma;
現在您可以在任何檔案中匯入相同的 Prisma 實例。
首先執行以下命令開始設定 shadcn:
npx shadcn-ui@latest init
我選擇了以下選項:
打字稿:是的
風格:預設
底色: 板岩色
全域 CSS:src/app/globals.css
CSS 變數:是
順風配置:tailwind.config.ts
元件:@/元件(預設)
utils:@/lib/utils(預設)
反應伺服器元件:是
寫入 Components.json:是
接下來執行以下命令來設定下一個主題:
npm 安裝下一個主題
然後將一個名為 theme-provider.tsx 的檔案加入到您的元件庫中並新增以下程式碼:
// theme-provider.tsx
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
設定完提供者後,您需要將其新增至 layout.tsx 中,以便在整個應用程式上實現它。使用主題提供者包裝 {children},如下所示:
// layout.tsx
return (
<html lang="en" suppressHydrationWarning>
<body className={inter.className}>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
現在前往 shadcn 主題頁。然後選擇您要使用的主題並按複製程式碼。然後將複製的程式碼加入您的 globals.css 中,如下所示:
// globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 224 71.4% 4.1%;
--card: 0 0% 100%;
--card-foreground: 224 71.4% 4.1%;
--popover: 0 0% 100%;
--popover-foreground: 224 71.4% 4.1%;
--primary: 262.1 83.3% 57.8%;
--primary-foreground: 210 20% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
--muted: 220 14.3% 95.9%;
--muted-foreground: 220 8.9% 46.1%;
--accent: 220 14.3% 95.9%;
--accent-foreground: 220.9 39.3% 11%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 20% 98%;
--border: 220 13% 91%;
--input: 220 13% 91%;
--ring: 262.1 83.3% 57.8%;
--radius: 0.5rem;
}
.dark {
--background: 224 71.4% 4.1%;
--foreground: 210 20% 98%;
--card: 224 71.4% 4.1%;
--card-foreground: 210 20% 98%;
--popover: 224 71.4% 4.1%;
--popover-foreground: 210 20% 98%;
--primary: 263.4 70% 50.4%;
--primary-foreground: 210 20% 98%;
--secondary: 215 27.9% 16.9%;
--secondary-foreground: 210 20% 98%;
--muted: 215 27.9% 16.9%;
--muted-foreground: 217.9 10.6% 64.9%;
--accent: 215 27.9% 16.9%;
--accent-foreground: 210 20% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 20% 98%;
--border: 215 27.9% 16.9%;
--input: 215 27.9% 16.9%;
--ring: 263.4 70% 50.4%;
}
}
現在您應該能夠在專案中使用 shadcn 元件和主題。
第一步是建立一個新的 SUPABASE 專案。接下來,安裝 next.js 驗證幫助程式庫:
npm install @supabase/auth-helpers-nextjs @supabase/supabase-js
現在您必須將您的 supabase url 和您的匿名金鑰新增至您的 .env 檔案中。您的 .env 檔案現在應如下所示:
// .env
DATABASE_URL=url
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
我們將使用 supabase cli 根據我們的架構產生類型。使用以下命令安裝 cli:
npm install supabase --save-dev
為了登入 supabase,請執行“npx supabase login”,它會自動讓您登入。
現在我們可以透過執行以下命令來產生我們的類型:
npx supabase gen types typescript --project-id YOUR_PROJECT_ID > src/lib/database.types.ts
應該在您的 lib 資料夾中新增文件,其中包含基於您的架構的類型。
現在在專案的根目錄中建立一個 middleware.ts 檔案並新增以下程式碼:
import { createMiddlewareClient } from "@supabase/auth-helpers-nextjs";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import type { Database } from "@/lib/database.types";
export async function middleware(req: NextRequest) {
const res = NextResponse.next();
const supabase = createMiddlewareClient<Database>({ req, res });
await supabase.auth.getSession();
return res;
}
現在,在應用程式目錄中建立一個名為 auth 的新資料夾,然後在 auth 中建立另一個名為callback 的資料夾,最後建立一個名為route.ts 的檔案。在該文件中加入以下程式碼:
// app/auth/callback/route.ts
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import type { Database } from "@/lib/database.types";
export async function GET(request: NextRequest) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get("code");
if (code) {
const cookieStore = cookies();
const supabase = createRouteHandlerClient<Database>({
cookies: () => cookieStore,
});
await supabase.auth.exchangeCodeForSession(code);
}
// URL to redirect to after sign in process completes
return NextResponse.redirect(requestUrl.origin);
}
透過該設置,我們可以建立一個登入頁面。在應用程式目錄中建立一個名為「login with page.tsx」的新資料夾。
// app/login/page.tsx
"use client";
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
import { useRouter } from "next/navigation";
import { useState } from "react";
import type { Database } from "@/lib/database.types";
export default function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const router = useRouter();
const supabase = createClientComponentClient<Database>();
const handleSignUp = async () => {
await supabase.auth.signUp({
email,
password,
options: {
emailRedirectTo: `${location.origin}/auth/callback`,
},
});
router.refresh();
};
const handleSignIn = async () => {
await supabase.auth.signInWithPassword({
email,
password,
});
router.refresh();
};
const handleSignOut = async () => {
await supabase.auth.signOut();
router.refresh();
};
return (
<>
<input
name="email"
onChange={(e) => setEmail(e.target.value)}
value={email}
/>
<input
type="password"
name="password"
onChange={(e) => setPassword(e.target.value)}
value={password}
/>
<button onClick={handleSignUp}>Sign up</button>
<button onClick={handleSignIn}>Sign in</button>
<button onClick={handleSignOut}>Sign out</button>
</>
);
}
現在,在 auth 目錄中建立一個名為「sign-up」的新資料夾,並在該檔案中建立一個「route.ts」。新增以下程式碼:
// app/auth/sign-up/route.ts
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import type { Database } from "@/lib/database.types";
export async function POST(request: Request) {
const requestUrl = new URL(request.url);
const formData = await request.formData();
const email = String(formData.get("email"));
const password = String(formData.get("password"));
const cookieStore = cookies();
const supabase = createRouteHandlerClient<Database>({
cookies: () => cookieStore,
});
await supabase.auth.signUp({
email,
password,
options: {
emailRedirectTo: `${requestUrl.origin}/auth/callback`,
},
});
return NextResponse.redirect(requestUrl.origin, {
status: 301,
});
}
在同一位置建立另一個名為「登入」的資料夾。
// app/auth/login/route.ts
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import type { Database } from "@/lib/database.types";
export async function POST(request: Request) {
const requestUrl = new URL(request.url);
const formData = await request.formData();
const email = String(formData.get("email"));
const password = String(formData.get("password"));
const cookieStore = cookies();
const supabase = createRouteHandlerClient<Database>({
cookies: () => cookieStore,
});
await supabase.auth.signInWithPassword({
email,
password,
});
return NextResponse.redirect(requestUrl.origin, {
status: 301,
});
}
最後在同一位置新增註銷路由。
// app/auth/logout/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'
import type { Database } from '@/lib/database.types'
export async function POST(request: Request) {
const requestUrl = new URL(request.url)
const cookieStore = cookies()
const supabase = createRouteHandlerClient<Database>({ cookies: () => cookieStore })
await supabase.auth.signOut()
return NextResponse.redirect(`${requestUrl.origin}/login`, {
status: 301,
})
}
現在,當您導航至 localhost http://localhost:3000/login 時,應該有基本的登入登出註冊功能。
現在我們有了一些帶有 prisma shadcn 和 supabase auth 設定的下一個 js 應用程式的基本樣板。
原文出處:https://dev.to/isaacdyor/setting-up-nextjs-project-with-prisma-200j