Next.js(App Router)でPrisma Clientを使用したところ、エラーに遭遇しました。
Componentが原因で起こったエラーっぽいですが、よくわからなかったのでまとめました!
バージョン
バージョン | |
Prisma | 5.2.0 |
Prisma Client | 5.2.0 |
Prisma Studio | 0.494.0 |
Node.js | 18.17.0 |
Next.js | 13.4.19 |
エラー内容
1 2 3 |
Unhandled Runtime Error Error: PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in `unknown`). If this is unexpected, please open an issue: https://github.com/prisma/prisma/issues |
エラー文をDeepLにかけると、
1 2 3 |
未処理のランタイム・エラー エラー エラー: PrismaClientはこのブラウザ環境では実行できません。 予期しないエラーが発生した場合は、https://github.com/prisma/prisma/issues。 |
原因を考える
エラー文をそのままググってもいいサイトが見つからなかったので、エラー文の意味を考えます。
「PrismaClientはこのブラウザ環境では実行できません。」
つまり、ブラウザ側(クライアント側)ではPrisma Clientが使えないってこと??
エラーが出ているコンポーネントを確認してみると、
確かにClient Componentになってるな…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
"use client"; import prisma from "@/lib/prisma"; export default function AddUser() { ... const fetchAsyncAddUser = async () => { ... await prisma.user.create({ data: { name: name, email: email, posts: { create: { title: postTitle }, }, profile: { create: { bio: profile }, }, }, }); }; ... } |
Prisma のHPを確認してみると、SSRやSSG、API Routesで使えるとのこと。
⇒CSRでは使えそうにないので、Client Componentでも使えなさそうです。
対応方針
- Client Component内に記述しているPrisma Clientを使用する処理をAPIにする
⇒Route Handlersを使う - そのAPIをClient Componentからたたくようにする
やってみる
修正前
・Client Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
"use client"; import prisma from "@/lib/prisma"; export default function AddUser() { ... const fetchAsyncAddUser = async () => { ... // ここからの処理をAPIへ await prisma.user.create({ data: { name: name, email: email, posts: { create: { title: postTitle }, }, profile: { create: { bio: profile }, }, }, }); // ここまで ... }; ... } |
修正後
・Clinet Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
"use client"; import prisma from "@/lib/prisma"; export default function AddUser() { ... const fetchAsyncAddUser = async () => { ... // APIのURL const url = "http://localhost:3000/api/user"; // リクエストパラメータ const params = { method: "POST", // JSON形式のデータのヘッダー headers: { "Content-Type": "application/json", }, // リクエストボディ body: JSON.stringify({ name: name, email: email, postTitle: postTitle, profile: profile, }), }; // APIへのリクエスト await fetch(url, params); ... }; ... } |
・API
⇒ ./src/app/api/user/route.ts に作成(URL:http://localhost:3000/api/user)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import { NextRequest, NextResponse } from "next/server"; import prisma from "@/lib/prisma"; export async function POST(req: NextRequest) { // リクエストボディを展開 const { name, email, postTitle, profile } = await req.json(); const res = await prisma.user.create({ data: { name: name, email: email, // ネストすることで参照先のテーブルに書き込める // Postテーブルに書き込む posts: { create: { title: postTitle }, }, // Profileテーブルに書き込む profile: { create: { bio: profile }, }, }, }); return NextResponse.json(res); } |
こんな感じでAPIを作成してそれをたたくようにしたらうまくいきましたーーー!!!
なので、やっぱりPrisma ClientはClinet Componentだと使えないみたいですね。。
エラー文からはブラウザでPrisma Clientが使えなさそうだったので、
APIかServer Componentで使用するしかなさそうです。
参考文献
Next.js Database with Prisma | Next-Generation ORM for SQL Databases
Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build Next.js apps with MySQL, PostgreSQL & SQL Server databases.
Routing: Route Handlers | Next.js
Create custom request handlers for a given route using the Web's Request and Response APIs.
fetchメソッドの基本的な使い方【クエリパラメータとリクエストボディの使い分け】
Fetch APIでJSON形式のデータを送信する | GRAYCODE JavaScript
Fetch APIのAjaxを使ってJSONデータをサーバーへ送信する方法について解説します。
コメント