How can I access `env.DB` in my Pages/Worker on production?

Steps to reproduce: 1. Clone https://github.com/cjxe/nextjs-d1-drizzle-cloudflare-pages 2. Follow README.md. 3. Run pnpm start or pnpm pages:prod. 4. Launch the web app using your favourite browser. Error:
[Error: Failed to retrieve the Cloudflare request context.]
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
digest: '3614312654'
}
[Error: Failed to retrieve the Cloudflare request context.]
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
digest: '3614312654'
}
I don't get this error when I run on dev due to how next.config.mjs is set up, but I can't make this work on production. The main issue is the Cloudflare pages return an error when it tries running getRequestContext().env.DB in src/server/db/index.ts.
GitHub
GitHub - cjxe/nextjs-d1-drizzle-cloudflare-pages
Contribute to cjxe/nextjs-d1-drizzle-cloudflare-pages development by creating an account on GitHub.
29 Replies
laurent
laurentā€¢6mo ago
src/db/

import * as schema from "@/db/schema/schema";
import { getRequestContext } from "@cloudflare>/next-on-pages";
import { drizzle } from "drizzle-orm/d1";
export const runtime = "edge";

function getDB() {
if (process.env.NODE_ENV === "development") {
const { env } = getRequestContext();
//@ts-ignore
return drizzle(env.DB, { schema });
}
// Production
//@ts-ignore
return drizzle(process.env.DB, { schema });
}

export const db = getDB();
src/db/

import * as schema from "@/db/schema/schema";
import { getRequestContext } from "@cloudflare>/next-on-pages";
import { drizzle } from "drizzle-orm/d1";
export const runtime = "edge";

function getDB() {
if (process.env.NODE_ENV === "development") {
const { env } = getRequestContext();
//@ts-ignore
return drizzle(env.DB, { schema });
}
// Production
//@ts-ignore
return drizzle(process.env.DB, { schema });
}

export const db = getDB();
wrangler.toml

[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "prod-dbname"
database_id = "123



[[env.production.d1_databases]]
database_id = "123"
binding = "DB"
database_name = "DB"
wrangler.toml

[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "prod-dbname"
database_id = "123



[[env.production.d1_databases]]
database_id = "123"
binding = "DB"
database_name = "DB"
lettucebaran
lettucebaranOPā€¢6mo ago
Thanks for the reply! I made your suggested changes, and the terminal threw this error: TypeError: Cannot read properties of undefined (reading 'prepare') šŸ˜µā€šŸ’«
laurent
laurentā€¢6mo ago
what's calling the database? how is it imported?
laurent
laurentā€¢6mo ago
can you try a simple api route like that? the db is the one exported above
import { db } from "@/db/drizzleDB";
import { cities } from "@/db/schema/schema";
import type { NextRequest } from "next/server";

export const runtime = "edge";

export async function GET(request: NextRequest) {

const result = await db.select().from(cities);

return Response.json({ result });
}
import { db } from "@/db/drizzleDB";
import { cities } from "@/db/schema/schema";
import type { NextRequest } from "next/server";

export const runtime = "edge";

export async function GET(request: NextRequest) {

const result = await db.select().from(cities);

return Response.json({ result });
}
lettucebaran
lettucebaranOPā€¢6mo ago
sure, 2 secs how would you like me to fetch in the front end, navigate to the endpoint in the browser?
laurent
laurentā€¢6mo ago
to test the api route you use something like postman and call GET localhost:3000/api/something I use thunder client in vscode
lettucebaran
lettucebaranOPā€¢6mo ago
No description
lettucebaran
lettucebaranOPā€¢6mo ago
i am getting the same error both thunder client and my browser returned the same
laurent
laurentā€¢6mo ago
are you exporting the db object as I showed you?
lettucebaran
lettucebaranOPā€¢6mo ago
i mean the server returned the sam error, the browser and thunder client returned "500 internal server error"
lettucebaran
lettucebaranOPā€¢6mo ago
No description
laurent
laurentā€¢6mo ago
did you double check your wrangler.toml values for the db?
lettucebaran
lettucebaranOPā€¢6mo ago
i am shaking
[[d1_databases]] # <-- i had to rename this from `env.production.d1_databases` to `d1_databases`
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "TBA" # When you create your D1 DB, you choose the name
database_id = "TBA"
preview_database_id = "DB"
[[d1_databases]] # <-- i had to rename this from `env.production.d1_databases` to `d1_databases`
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "TBA" # When you create your D1 DB, you choose the name
database_id = "TBA"
preview_database_id = "DB"
thank you very much
laurent
laurentā€¢6mo ago
do you see a database there?
No description
lettucebaran
lettucebaranOPā€¢6mo ago
i even got the api response
lettucebaran
lettucebaranOPā€¢6mo ago
No description
lettucebaran
lettucebaranOPā€¢6mo ago
No description
laurent
laurentā€¢6mo ago
ah ok good!
lettucebaran
lettucebaranOPā€¢6mo ago
whats your wrangler command to connect to the production database?
laurent
laurentā€¢6mo ago
I copied it above
lettucebaran
lettucebaranOPā€¢6mo ago
oh i meant something like
pnpm wrangler pages dev --env production .vercel/output/static
pnpm wrangler pages dev --env production .vercel/output/static
laurent
laurentā€¢6mo ago
I don't think you can
No description
lettucebaran
lettucebaranOPā€¢6mo ago
hm, thats a shame
Coolio85
Coolio85ā€¢6mo ago
This might sound simple, but did you update these values for the d1 database you want to bind?
lettucebaran
lettucebaranOPā€¢6mo ago
yeah that's my template and i was trying to find what was wrong with it, but thanks for checking in
Coolio85
Coolio85ā€¢6mo ago
šŸ‘ only saying because I've definitely not done that before :hide_the_pain: :laughingpepe: One thing I can suggest, is try getting rid of the conditional regarding process.env.NODE_ENV, my nextjs pages project looks similar to this
import { getRequestContext } from "@cloudflare/next-on-pages"
import { PrismaClient } from '@prisma/client'
import { PrismaD1 } from '@prisma/adapter-d1'

const getDb = (): PrismaClient => {
const binding = getRequestContext().env.DB;

const adapter = new PrismaD1(binding)
const prisma = new PrismaClient({ adapter })

return prisma;
}

export default getDb;
import { getRequestContext } from "@cloudflare/next-on-pages"
import { PrismaClient } from '@prisma/client'
import { PrismaD1 } from '@prisma/adapter-d1'

const getDb = (): PrismaClient => {
const binding = getRequestContext().env.DB;

const adapter = new PrismaD1(binding)
const prisma = new PrismaClient({ adapter })

return prisma;
}

export default getDb;
With a wrangler file of
[[d1_databases]]
binding = "DB"
database_name = "name"
database_id = "[ID]"
preview_database_id = "[ID]"

[[env.preview.d1_databases]]
binding = "DB"
database_name = "name"
database_id = "[ID]"
preview_database_id = "[ID]"
[[d1_databases]]
binding = "DB"
database_name = "name"
database_id = "[ID]"
preview_database_id = "[ID]"

[[env.preview.d1_databases]]
binding = "DB"
database_name = "name"
database_id = "[ID]"
preview_database_id = "[ID]"
lettucebaran
lettucebaranOPā€¢6mo ago
i tried it, and for some reason @cloudflare/next-on-pages throws an error, so I left the conditione unrelated to this thread, but did you manage to view the preview or prod database using drizzle-kit studio?
// drizzle.config.ts
import { env } from '@/env';

/*
* NOTE: Workaround to make drizzle studio work with D1.
* https://kevinkipp.com/blog/going-full-stack-on-astro-with-cloudflare-d1-and-drizzle/
* Github discussion: https://github.com/drizzle-team/drizzle-orm/discussions/1545#discussioncomment-8115423
*/
export default env.LOCAL_DB_PATH
? { // i can see the local database
schema: './src/server/db/schema.ts',
driver: 'd1',
dialect: 'sqlite',
dbCredentials: {
url: env.LOCAL_DB_PATH,
},
}
: { // i can't see the db on d1
schema: './src/server/db/schema.ts',
out: './migrations',
driver: 'd1',
dbCredentials: {
wranglerConfigPath:
new URL('wrangler.toml', import.meta.url).pathname + env.WRANGLER_CONFIG
? ` ${env.WRANGLER_CONFIG}`
: '',
dbName: env.DB_NAME!,
},
};
// drizzle.config.ts
import { env } from '@/env';

/*
* NOTE: Workaround to make drizzle studio work with D1.
* https://kevinkipp.com/blog/going-full-stack-on-astro-with-cloudflare-d1-and-drizzle/
* Github discussion: https://github.com/drizzle-team/drizzle-orm/discussions/1545#discussioncomment-8115423
*/
export default env.LOCAL_DB_PATH
? { // i can see the local database
schema: './src/server/db/schema.ts',
driver: 'd1',
dialect: 'sqlite',
dbCredentials: {
url: env.LOCAL_DB_PATH,
},
}
: { // i can't see the db on d1
schema: './src/server/db/schema.ts',
out: './migrations',
driver: 'd1',
dbCredentials: {
wranglerConfigPath:
new URL('wrangler.toml', import.meta.url).pathname + env.WRANGLER_CONFIG
? ` ${env.WRANGLER_CONFIG}`
: '',
dbName: env.DB_NAME!,
},
};
UPDATE: the issue is fixed with drizzle-kit v0.21.3, THANK YOU! ā¤ļø
Want results from more Discord servers?
Add your server