From f3f381006e76d225c7a7d7c5194a66f0ef963c3e Mon Sep 17 00:00:00 2001 From: Carly Thomas Date: Fri, 5 Dec 2025 16:06:47 -0800 Subject: [PATCH] fix: prevent Prisma from being bundled in client-side code - Converted top-level Prisma imports to dynamic imports in getServerSideProps - Fixes 'PrismaClient is unable to be run in the browser' error - Affected pages: dashboard v1/v2, classes, admin pages Pages updated: - pages/dashboard/v2/[id].js - pages/dashboard/v2/details/[id]/[studentEmail].js - pages/dashboard/[id].js - pages/classes/index.js - pages/admin/index.js - pages/admin/actions/[id].js Why this fix is needed: Next.js creates two bundles for each page - server (SSR) and client (navigation). Top-level imports are included in BOTH bundles. When users click Link components for client-side navigation, Next.js loads the client bundle which includes Prisma, causing 'PrismaClient is unable to be run in the browser' runtime errors. Dynamic imports inside getServerSideProps() ensure Prisma stays server-only, as getServerSideProps is completely stripped from the client bundle. --- pages/admin/actions/[id].js | 4 +++- pages/admin/index.js | 4 +++- pages/classes/index.js | 4 +++- pages/dashboard/[id].js | 4 +++- pages/dashboard/v2/[id].js | 4 +++- pages/dashboard/v2/details/[id]/[studentEmail].js | 4 +++- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/pages/admin/actions/[id].js b/pages/admin/actions/[id].js index 6624f652a..b5ea00007 100644 --- a/pages/admin/actions/[id].js +++ b/pages/admin/actions/[id].js @@ -1,10 +1,12 @@ import { getSession } from 'next-auth/react'; import Navbar from '../../../components/navbar'; import UpdateUserForm from '../../../components/updateUserForm'; -import prisma from '../../../prisma/prisma'; import redirectUser from '../../../util/redirectUser.js'; export async function getServerSideProps(context) { + // Dynamic import to prevent Prisma from being bundled for client + const { default: prisma } = await import('../../../prisma/prisma'); + const userSession = await getSession(context); if (!userSession) { return redirectUser('/error'); diff --git a/pages/admin/index.js b/pages/admin/index.js index ac5e996ca..0d9867762 100644 --- a/pages/admin/index.js +++ b/pages/admin/index.js @@ -3,11 +3,13 @@ import styles from '../../styles/Home.module.css'; import Navbar from '../../components/navbar'; import Link from 'next/link'; import { getSession } from 'next-auth/react'; -import prisma from '../../prisma/prisma'; import dynamic from 'next/dynamic'; import redirectUser from '../../util/redirectUser.js'; export async function getServerSideProps(ctx) { + // Dynamic import to prevent Prisma from being bundled for client + const { default: prisma } = await import('../../prisma/prisma'); + const userSession = await getSession(ctx); if (!userSession) { return redirectUser('/error'); diff --git a/pages/classes/index.js b/pages/classes/index.js index f9ddf876d..bb4bf41d3 100644 --- a/pages/classes/index.js +++ b/pages/classes/index.js @@ -1,4 +1,3 @@ -import prisma from '../../prisma/prisma'; import ClassInviteTable from '../../components/ClassInviteTable'; import Head from 'next/head'; import Navbar from '../../components/navbar'; @@ -11,6 +10,9 @@ import { useState } from 'react'; import redirectUser from '../../util/redirectUser.js'; export async function getServerSideProps(ctx) { + // Dynamic import to prevent Prisma from being bundled for client + const { default: prisma } = await import('../../prisma/prisma'); + const userSession = await getSession(ctx); if (!userSession) { return redirectUser('/error'); diff --git a/pages/dashboard/[id].js b/pages/dashboard/[id].js index b4f2e4c4a..d383b0885 100644 --- a/pages/dashboard/[id].js +++ b/pages/dashboard/[id].js @@ -2,7 +2,6 @@ import Head from 'next/head'; import Layout from '../../components/layout'; import Link from 'next/link'; import Navbar from '../../components/navbar'; -import prisma from '../../prisma/prisma'; import DashTabs from '../../components/dashtabs'; import { getSession } from 'next-auth/react'; import { @@ -15,6 +14,9 @@ import { import redirectUser from '../../util/redirectUser.js'; export async function getServerSideProps(context) { + // Dynamic import to prevent Prisma from being bundled for client + const { default: prisma } = await import('../../prisma/prisma'); + //making sure User is the teacher of this classsroom's dashboard const userSession = await getSession(context); if (!userSession) { diff --git a/pages/dashboard/v2/[id].js b/pages/dashboard/v2/[id].js index 706492318..34d71f3b5 100644 --- a/pages/dashboard/v2/[id].js +++ b/pages/dashboard/v2/[id].js @@ -1,7 +1,6 @@ import Head from 'next/head'; import Layout from '../../../components/layout'; import Link from 'next/link'; -import prisma from '../../../prisma/prisma'; import Navbar from '../../../components/navbar'; import { getSession } from 'next-auth/react'; import GlobalDashboardTable from '../../../components/dashtable_v2'; @@ -17,6 +16,9 @@ import { import redirectUser from '../../../util/redirectUser.js'; export async function getServerSideProps(context) { + // Dynamic import to prevent Prisma from being bundled for client + const { default: prisma } = await import('../../../prisma/prisma'); + //making sure User is the teacher of this classsroom's dashboard const userSession = await getSession(context); if (!userSession) { diff --git a/pages/dashboard/v2/details/[id]/[studentEmail].js b/pages/dashboard/v2/details/[id]/[studentEmail].js index 79f5c00b3..cac5d98ac 100644 --- a/pages/dashboard/v2/details/[id]/[studentEmail].js +++ b/pages/dashboard/v2/details/[id]/[studentEmail].js @@ -1,7 +1,6 @@ import Head from 'next/head'; import Layout from '../../../../../components/layout'; import Link from 'next/link'; -import prisma from '../../../../../prisma/prisma'; import Navbar from '../../../../../components/navbar'; import { getSession } from 'next-auth/react'; import { @@ -17,6 +16,9 @@ import styles from '../../../../../components/DetailsCSS.module.css'; import DetailsDashboard from '../../../../../components/DetailsDashboard'; export async function getServerSideProps(context) { + // Dynamic import to prevent Prisma from being bundled for client + const { default: prisma } = await import('../../../../../prisma/prisma'); + //making sure User is the teacher of this classsroom's dashboard const userSession = await getSession(context);