Ive been trying to do entirely Server Side Pages with the new Nextjs 13 App Directory, and every time i try and use DB calls on the server using Server Actions but for whatever reason it only seems to notice when i use fetch. the MongoDB library and the SurrealDB library seem to be completely ignored as a backend request and no matter what i do, i cannot get Next to recognise these as serverside requests even if i stick async infront of them.
#Did Vercel just forget that some other backend libraries dont use fetch?
41 messages · Page 1 of 1 (latest)
yes, ive used force-dynamic in the pages in question and enabled server actions in next config
nothing i do can get serverside stuff to work
Did you set your environment variables? db connections are fully supported.
i believe so. connection strings work, but the problem is its trying to pre-render the page
#0 1.403 - info Creating an optimized production build...
#0 16.69 - info Compiled successfully
#0 16.69 - info Linting and checking validity of types...
#0 18.60 - info Collecting page data...
#0 30.65 - info Generating static pages (0/4)
#0 30.88 - info Generating static pages (1/4)
#0 30.88 - info Generating static pages (2/4)
#0 30.94 - info Generating static pages (3/4)
#0 91.30 - warn Restarted static page generation for /blog because it took more than 60 seconds
#0 91.30 - warn See more info here https://nextjs.org/docs/messages/static-page-generation-timeout
#0 151.8 - warn Restarted static page generation for /blog because it took more than 60 seconds
#0 212.2
#0 212.2 > Build error occurred
#0 212.2 Error: Static page generation for /blog is still timing out after 3 attempts. See more info here https://nextjs.org/docs/messages/static-page-generation-timeout
#0 212.2 at onRestart (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/build/index.js:671:39)
#0 212.2 at Worker.exportPage (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/lib/worker.js:88:40)
#0 212.2 at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
#0 212.2 at async /app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/export/index.js:516:32
#0 212.2 at async Span.traceAsyncFn (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/trace/trace.js:103:20)
#0 212.2 at async Promise.all (index 2)
#0 212.2 at async /app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/export/index.js:507:9
#0 212.2 at async Span.traceAsyncFn (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/trace/trace.js:103:20)
#0 212.2 at async /app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/build/index.js:1488:21
#0 212.2 at async Span.traceAsyncFn (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/trace/trace.js:103:20)
#0 212.2 at async /app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/build/index.js:1344:17
#0 212.2 at async Span.traceAsyncFn (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/trace/trace.js:103:20)
#0 212.2 at async build (/app/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/build/index.js:145:29)
#0 212.3 ELIFECYCLE Command failed with exit code 1.
------
failed to solve: executor failed running [/bin/sh -c pnpm run build]: exit code: 1
of course, it cant pre render a db connection, the db dosent exist yet
and i dont want it to pre-render the page
import { CollectionPromise } from "#/lib/withMongodb"
import "server-only"
export const dynamic = 'force-dynamic'
async function getPages(){
const pages = await CollectionPromise("blog")
const posts = await pages.find().toArray()
return posts
}
const Page = async (props:any) => {
const query = props.searchParams
const pages = await getPages()
return(
<>
{pages.map((page, index)=>{
<div key={index}>
{page.title}
</div>
})}
</>
)
}
export default Page
I think you might be missing a step in your mongo config, You should be calling something like db.Pages.find() directly from your server action.
There's an example here for pages, but the same concept applies in App. https://jasonwatmore.com/next-js-13-mongodb-user-registration-and-login-tutorial-with-example-app#db-js
thats handled in CollectionPromise. it instantiates the connection, selects the collection, then returns the collection, it throws if it fails
also im not using mongoose
im using the raw mongoDB library
hate mongoose
You need to export the client, not just the collection promise
Because the page is being compiled as a single serverless function
This isn't like other node frameworks
so i have to create a client in every single server component?
i cant create a function that does it for me and call that?
also why is this trying to get me to do a fetch request to the server its already running on?!
thats redundant
just initiate the call during page compile after request
,,,
im so confused
No, you just need to export the client from your db.js, or whatever it's called
You're exporting "collectionpromise" but I'm not sure what that is.
import "server-only"
import { Collection, Db, MongoClient } from "mongodb"
export async function DbPromise():Promise<Db>{
const client = new MongoClient("mongodb://url:27017")
try{
await client.connect();
return client.db("litelotus")
}catch(e){
throw(e)
}
}
export async function CollectionPromise(collection: string):Promise<Collection>{
const db = await DbPromise()
try{
return db.collection(collection)
}catch(e){
throw(e)
}
}
You should be able to just export client.db('litelotus') and use that directly
when i did that it didnt work, thats why i made collectionPromise
you mean the DbPromise() function?
const client = new MongoClient(...)
export const db = client.db('litelotus')
cant do that, that keeps a db connection open perpetually
mongo will eventually kill it
You'd probably have to make a global as well
https://www.prisma.io/docs/guides/other/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices#solution
should kill the connection once the serverless function ends. It's rare now to have to manage pooling or the connection directly.
Most examples I'm finding with mongodb and nextjs are using prisma as well, might be easier to use it than using the mongodb library directly
it appears this is for use with get serverside props not the app folder, it still fails to build a production build of the app