-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Doesn't work with next.js Edge runtime #3206
Comments
Yeah it would probably...how does one reproduce this issue locally? If running in node then |
Set up a basic And then assume to use CloudFlare Pages requires a next.js app to specify that all backend endpoints will be using the edge runtime. There's a further complication that |
I am trying to use Prisma, PrismaPg and Pg.
Call Stack
https://vercel.com/docs/functions/runtimes/edge-runtime#unsupported-apis I know it's not really an issue related to Pg but I wanted to inform here anyway. |
I am using Next.js and Drizzle, and get the same: |
This patch fixes for me. Specifically: prevents the error
diff --git a/node_modules/pg/lib/crypto/utils-webcrypto.js b/node_modules/pg/lib/crypto/utils-webcrypto.js
index 0433f01..588066e 100644
--- a/node_modules/pg/lib/crypto/utils-webcrypto.js
+++ b/node_modules/pg/lib/crypto/utils-webcrypto.js
@@ -13,7 +13,10 @@ module.exports = {
* The Web Crypto API - grabbed from the Node.js library or the global
* @type Crypto
*/
-const webCrypto = nodeCrypto.webcrypto || globalThis.crypto
+
+// PATCH: Don't break under Next.js Edge runtime production build
+const webCrypto = ("webcrypto" in nodeCrypto ? nodeCrypto.webcrypto : undefined) ?? globalThis.crypto
+
/**
* The SubtleCrypto API for low level crypto operations.
* @type SubtleCrypto (I opted to use runtime-agnostic Feature Detection for |
Quick note from @prisma that this affects some of our users and is being reported to us: prisma/prisma#24430 (This issue has a reproduction, but that includes Prisma, Next.js and next-auth - that is probably a bit more than what you are asking for @brianc. I am pretty sure just trying to use We would love to see this fixed and released, so that Prisma users wanting to use |
k i'll get this looked at today if I have time! |
@janpio @andyjy @etodanik would one of y'all be able to provide me w/ more concrete steps to follow to set up a local reproduction? I did So i tested it at http://localhost:3000/api/hello and it worked. great. then I went into the route file and added export const runtime = 'edge' and now its erroring when I hit the route: So I'm doing something wrong, but not sure what. This is the full contents of my // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
type Data = {
name: string;
};
export const runtime = 'edge'
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>,
) {
res.status(200).json({ name: "John Doe" });
} |
@brianc here you go - reproduction for pages router: |
amazing, ty |
@andyjy when i applied your patch to the crypto file I now get this:
|
Update: 🤦♂️ sorry, I realised that while the patch I shared above indeed prevents the Next.js local edge runtime compilation error, I'm not actually executing the (I remembered I'm actually serving my API routes that use Sorry for the incorrect/misleading post previously! Thinking ahead to whether/how it's possible to get things actually working under the Next.js Edge runtime locally - it would probably(?) require breaking out of Next.js' local Edge Runtime "sandbox" to access If I get an actually-working prototype then I'll share back. |
Tiny PR to @andyjy's repro to show the same problem with a Next.js middleware, the common case where Prisma users run into this: andyjy/mre-pg-nextjs-edge#1
Semi informed comment from the sidelines: Afaik the Cloudflare Workers support for |
absolutely no problem! I'll continue to noodle on this....might take a bit of time to do a similar retrofit that the CF stuff did. I'm also about to go out of town for a bit so...hang tight - i'll get there eventually! |
🤔 |
Yes - having looked into it more, I also realised you're essentially correct - that lack of TCP socket support is a blocker for the Next.js/Vercel Edge Runtime. Despite running on Cloudflare Workers behind the scenes (still ?) - when deploying to Vercel, Edge runtime code that references What I assume is possible is deploying a Next.js app using the Edge runtime directly to Cloudflare. With no Vercel / Edge Runtime wrapper, the bundled code should just work on Cloudflare Workers. And if someone wishes to do that, it is technically possible to:
Potentially handy if anyone really wants to develop using Next.js + The reproduction repo is now updated with a proof of concept for both (1) and (2). I haven't deployed to Cloudflare directly but see no reason why this wouldn't work (potentially with a bit more tweaking to get the output bundle correct) /nerd-snipe over |
Thanks for the validation of my thought, I was not sure if I was really mixing things up now. Note, that will probably make this a lot more confusing instead of helping, as it makes it more complex: For Cloudflare Pages there is an additional package Probably means no easy way to use |
@janpio here's the reproduction repo deployed directly to cloudflare via @cloudflare/next-on-pages .. it works(!) - connecting to a Neon database using node-postgres:
The (currently super ugly..) patches to 🎉 |
@janpio ..and here it is deployed to Cloudflare with Prisma added (via Pages router API route: https://d2ff1a42.mre-pg-nextjs-edge.pages.dev/api/hello-app |
Ok wow, that is pretty wild @andyjy - amazing! Do I understand correctly that you seem a way to make |
Exactly! And specifically those changes are:
I believe this fixes cloudflare/next-on-pages#605 (The patches linked above are still a bit of a messy proof-of-concept - in particular there are some "unhappy paths" in The changes in my patches would also need a bit more love before they can be merged into Re: Vercel:
Yes - at least, I observe that when pushing bundled code to Vercel that includes (It's the same error if I push any code referencing e.g. As I understand it - Vercel's Edge runtime product specifically supports their Edge Runtime API that is designed to be runnable under various V8-powered environments - AFAIK they don't particualrly publicise the fact it's Cloudflare Workers under the hood (and could host their Vercel Edge functions elsewhere under non-Cloudflare at any time - for all I know they may do already!). So at this point while it may be worth asking a friendly contact at Vercel about the possibility of bypassing the |
Shared that workaround over at |
Hi! I'm back from my trip - will be looking into this tomorrow morning! Thanks for all the help & research...I'll dive in tomorrow with some 👀 and 🔨 |
ugg...reading up on the edge runtime vm trying to come up w/ a way to write some test for this within the repo. A bit complicated. Definitely open to ideas & help on this or a PR w/ the patch (though yeah I looked at it, it needs a bit more massaging). Thanks for the work so far @andyjy! |
Same issues here using Drizzle with node-postgres and next-auth which use as DB adapter drizzle/pg. What I did is to do a dummy next-auth adapter stripping DB import { AUTH_MAX_AGE } from '$/auth/constants';
import Google from 'next-auth/providers/google'
import NextAuth from 'next-auth'
import { NextResponse } from 'next/server';
import { NextAuthRequest } from 'node_modules/next-auth/lib';
// Make here the dummny next-auth without PostgreSQL dependency
const { auth } = NextAuth({
session: { strategy: 'jwt', maxAge: AUTH_MAX_AGE },
providers: [Google]
})
export default auth((_req: NextAuthRequest) => {
return NextResponse.next();
})
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
} Not sure if this works but at least in development the page load |
If you are going to use JWT as strategy you probably don't need to use an adapter for your Next Auth so you probably don't need to use Pg either. |
I still need to use PG adapter for storing users and accounts |
For those hitting this issue as part of a next-auth / auth js 5 integration, this document helped me understand the situation better: https://authjs.dev/guides/edge-compatibility """ As edge runtimes have matured and become more popular, however, people have gotten creative and implemented various solutions to this problem. One such common solution is to put some sort of API server in front of the database whose goal is to translate database queries sent to it via HTTP into a protocol the database can understand. This allows the client side to only have to make HTTP requests to the API server, which is something that every edge runtime supports. My workaround was to expose an API to pg that an auth.ts callback can hit from edge. I think I'd still prefer using pg in edge runtime (sounds like Brian is close to a solution), but maybe this is working as intended if node-postgres is designed for the node.js runtime, which Vercel's Edge runtime doesn't (or only partially) uses |
But you still can have middleware if you use |
This is sufficent: import { MiddlewareConfig, NextResponse } from "next/server";
import { PagePath } from "@/enums";
import NextAuth from "next-auth";
const { auth } = NextAuth({ providers: [] });
export const middleware = auth(async (req) => {
const path = new URL(req.url).pathname;
const session = await auth();
const isSigninPage = path === PagePath.SIGNIN.toString();
const isRootPage = path === PagePath.ROOT.toString();
const isAPIRoute = path.startsWith("/api");
if (session && isSigninPage) {
return NextResponse.redirect(new URL(PagePath.ROOT, req.url));
}
if (!session && !(isRootPage || isSigninPage || isAPIRoute)) {
return NextResponse.redirect(new URL(PagePath.SIGNIN, req.url));
}
});
export const config: MiddlewareConfig = {
matcher: ["/((?!api|_next/static|_next/image\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)"],
}; BUT you have to ensure that you are using the JWT strategy and never access the DB during the middleware, here is auth.ts: import NextAuth, { DefaultSession } from "next-auth";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { getDatabaseClient } from "db/connection";
import { accounts, sessions, users, verificationTokens } from "db/schema";
import { User } from "@/types/database-types";
import { eq } from "drizzle-orm";
import Google from "next-auth/providers/google";
import Resend from "next-auth/providers/resend";
declare module "next-auth" {
/**
* Returned by `auth`, `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
user: User & DefaultSession["user"];
}
}
export const { handlers, signIn, signOut, auth } = NextAuth({
adapter: DrizzleAdapter(getDatabaseClient(), {
usersTable: users,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
session: { strategy: "jwt" },
callbacks: {
session: async ({ session }) => {
const db = getDatabaseClient();
const user = await db.query.users.findFirst({
where: eq(users.email, session.user.email),
});
session.user = { ...user, ...session.user };
return session;
},
},
providers: [Google, Resend],
}); |
Hello there ! import { Pool } from 'pg';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@prisma/client';
const pool = new Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter }); but as soon as I make a database call, I get this kind of error :
As you can see, the error originates from the "pg" library. I'm gonna be completely honest and tell you that I don't really know what the "pg" is (although I guess it allows to connect to postgres databases without using TCP). I'm gonna try to create a minimal repo that recreates this behaviour asap, but reading this whole issue comments I did not see a solution come out yet. Have a nice day, and do not hesitate to ping me if you manage to get results on this matter. |
Minimal repro of my situation here : https://github.com/the-me-0/node-pg-minimal-repro |
@the-me-0 In order to use Prisma with Next.js Edge, you need to use a supported Prisma Driver Adapter/database combination here: Note that page says:
In other words, |
I did read this page yesterday, and I am aware that pg cannot run in nextjs's edge runtime. But this issue is still open, so isn't that a thing "pg" is aiming to fix ? If so, my repro could help. If not, this issue should be closed. I needed pg to work in this edge runtime because no other solution really cut it for me (fortunately, I found a way around, documented on the prisma issue : prisma/prisma#24430 (comment)), as I have a local DB running on docker and that's what I'm trying to connect to. I'll admit that I did not try to use other drivers proposed by the prisma documentation, as I did not know if they would work for my "localhost" set-up. I don't even know what's a cloudflare worker is tbh so I went for the option that seemed to be the simplest, node-postgres. Maybe other adapters like neon would have done the work and I just lost a lot of time for nothing, but in any case I got something to work now. |
For all who uses drizzle ORM with Hope it's gonna be possibile in your projects ! |
I'm writing an app on
next.js
which I plan to deploy to CloudFlare Pages + Workers. I know there's CloudFlare support, but when running the local development server of next.js, I get the following errors:Would it make sense to generalize CloudFlare Workers detection into a broader Edge detection that also includes node edge runtime?
The text was updated successfully, but these errors were encountered: