Replies: 19 comments 17 replies
-
You may want to use a custom server if you need to initialize custom jobs/services vital to a connection; otherwise, off-load them to a microservice. However, if you're trying to avoid a custom server, another approach I've found is to store the This will also work if you're using Click to expand exampledatabase/index.js const bluebird = require("bluebird");
const monitor = require("pg-monitor");
const pgPromise = require("pg-promise");
const initOptions = { promiseLib: bluebird, noWarnings: false }; // Database options
const pgp = pgPromise(initOptions); // initialize pg-promise with options
const { NODE_ENV, DB, DBHOST, DBPASSWORD, DBPORT, DBUSER } = process.env;
if (NODE_ENV === "development") {
monitor.attach(initOptions, ["query", "error"]);
} else {
monitor.attach(initOptions, ["error"]);
}
module.exports = pgp({
database: DB,
host: DBHOST,
password: DBPASSWORD,
port: DBPORT,
user: DBUSER,
}); database/connection.js const getConfig = require("next/config");
const { db } = getConfig().publicRuntimeConfig;
module.exports = db; next.config.js require('dotenv').config()
const db = require("./database");
module.exports = {
publicRuntimeConfig: {
db
}
}; |
Beta Was this translation helpful? Give feedback.
-
Mmmh thanks @mattcarlotta, I hadn't seen this I've had a look at the docs. Is there a reason why you would put your |
Beta Was this translation helpful? Give feedback.
-
Depends on how you're using |
Beta Was this translation helpful? Give feedback.
-
So after some testing, it turns out one cannot easily do what you recommend @mattcarlotta because it is impossible to have a |
Beta Was this translation helpful? Give feedback.
-
Some other use cases for something like an 'preServerStart' hook:
These use cases sometimes come up when making small tools or hack projects. For cases like these it would be nice to not have to use a custom server, but to instead hook into the server start-up. |
Beta Was this translation helpful? Give feedback.
-
I was able to hack together a solution for this that works extremely well at the moment but due to relying on nextjs internals it may break in the future. It works with typescript and hot module reloading. Here's what you'll have to do to get this working:
|
Beta Was this translation helpful? Give feedback.
-
I just need an entry to setup logger. |
Beta Was this translation helpful? Give feedback.
-
well, using typescript it's not that elegant, but we did: Install @babel/register In your next.config.js:
Inject into the webpack config (abbreviated for clarity):
this loads "our" bootstrap process in ./server/index.ts where we init crons and mongoose. And yes, so far it seems to be working because our /api routes use that connection 😆 EDIT: That's only for dev server, please see below |
Beta Was this translation helpful? Give feedback.
-
Here's a gist for a cleaner example, working with dev and production: packages to install:
start inside your project root with debug with |
Beta Was this translation helpful? Give feedback.
-
WORKAROUND here, my friends!
That's it! (Why thumb down? 🤔 It's hacky obviously, I know, but this workaround works safely) |
Beta Was this translation helpful? Give feedback.
-
I hope this solution will solve your problem. This is an example of the startup function in next JS with not custom server This repository run startup function without using custom server. // before next loading
console.log(process.env.ENV_TEST, '[expected]: undefined') // undefined
// after next loading
const command = process.argv[2]
if (['dev', 'start'].includes(command)) {
require('./node_modules/next/dist/bin/next')
check(init)
}
// function
// function
// function
// next loading check
/** @param {Function} fn */
function check(fn) {
setTimeout(() => {
if (!('LOAD_CHECK' in process.env)) {
setTimeout(check, 0, fn)
return
}
fn()
}, 50)
}
// after init function
function init() {
switch (command) {
case 'dev': {
// here dev script
console.log('run dev')
break
}
case 'start': {
// here start script
console.log('run start')
break
}
}
// commons script
console.log(process.env.ENV_TEST, '[expected]: Hello!!') // 'Hello!!'
} For more information, see the app.js in this repository |
Beta Was this translation helpful? Give feedback.
-
Any updates on this issue? I would rather not hack in a solution like some of the answers above but it seems that it's the only answer at this point in time :( |
Beta Was this translation helpful? Give feedback.
-
I'm currently building a next app with a apollo-graphql server and a webhook handler |
Beta Was this translation helpful? Give feedback.
-
This seems like a sensible, feasible feature that lots of people want. Could someone on the Next.js team tell us if this will be implemented, and if not, why not? |
Beta Was this translation helpful? Give feedback.
-
It's been more than 2 years since this issue was created. I do not understand why the Vercel team is looking into this issue. |
Beta Was this translation helpful? Give feedback.
-
After trying all the methods, I've found using a custom server to be the best and most reliable solution. What most people seem to be wanting out of this is to implement long-running tasks/background processes that just won't work on Vercel due to the ephemeral/serverless nature of the deployment. So if you still need it, then a custom server (deployed outside Vercel) would be the best option, imo. Running a custom server is trivial. Instead of doing //server,js
const express = require('express')
const next = require('next')
startBackgroundProcess()
doWhatever()
const app = next({ dev: false })
const handler = app.getRequestHandler()
await app.prepare()
const server = express()
server.all('*', handler)
server.listen(3000) |
Beta Was this translation helpful? Give feedback.
-
Hey folks, wanted to mention this solution. I know it's not perfect, but it should unblock you from running code before the Next.js server starts without needing to eject out of the default server.
Source and credit: https://jake.tl/notes/2021-04-04-nextjs-preload-hack |
Beta Was this translation helpful? Give feedback.
-
+1 Still no native solution |
Beta Was this translation helpful? Give feedback.
-
I believe...there is now a solution? Last week, version 13.3.2 made changes for: Looking at the history, version 13.2.0 added the initial support: Checking out the docs from last week:
I haven't tried it myself yet, but this may be what we were looking for. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Feature request
Is your feature request related to a problem? Please describe.
In almost all the applications, we need to write code that needs to be run only once when the server starts in order to initialize "global" elements:
In the current version, we don't see how to do it. There are some hacky ways of initializing these but they do not seem 100% reliable. (i.e. : https://www.codeoftheprogrammer.com/2020/01/16/postgresql-from-nextjs-api-route/)
Describe the solution you'd like
It would be very handy to be able to define a file where all this initialization code can be added following the example of
_app.js
or_document.js
.It could be called
_init.(js|ts)
. When present, thenext
command would execute it before starting the actual server. Here is what it would look like:Describe alternatives you've considered
As an alternative, we can implement global code initialization using
NodeJS.Global
but it seems too hacky : https://www.codeoftheprogrammer.com/2020/01/16/postgresql-from-nextjs-api-route/.Additional context
Might be related in some way to #8969
Beta Was this translation helpful? Give feedback.
All reactions