How to run server-only code once on server startup in Next.js?
Asked Answered
F

1

7

I am trying to access my User objection.js model from getStaticProps and getStaticPaths.

However, I need to run

import Knex from "knex";
import knexfile from "./knexfile";
import { Model } from "objection";

function setupDB() {
  const db = Knex(knexfile[process.env.NODE_ENV]);
  Model.knex(db);
}

on server startup.

When I do

  const users = await User.query();

inside getStaticPaths, I get Error: no database connection available for a query. You need to bind the model class or the query to a knex instance. error.

I tried running setupDB() inside _app.js with typeof window === "undefined" check, but just importing Knex and objection in _app.js throws an error.

Where should I run this? I really really want to avoid extending server.js.

(I should add there was a discussion on next.js github, but not sure if there's a way to do it specific to Objection.js, or any recent development.

Frasco answered 15/8, 2021 at 16:49 Comment(0)
H
1

Next.js v13.2.0 provides a feature called instrumentationHook for that purpose in the App Router that runs when the server starts. To use it, set the instrumentationHook feature flag to true in next.config.js

// next.config.js

module.exports = {
  experimental: {
    instrumentationHook: true,
  },
}

Then create a app/instrumentation.{js,ts,...} file

// app/instrumentation.js

import Knex from "knex";
import knexfile from "./knexfile";
import { Model } from "objection";

function setupDB() {
  const db = Knex(knexfile[process.env.NODE_ENV]);
  Model.knex(db);
}

When you run next start (or node .next/server.js for standalone mode), this file will be executed once.

Homeric answered 25/4 at 4:8 Comment(3)
Will not work with any code. E.g. when you import some dependenices that webpack can not transpileTumular
What kind of code that webpack can't transpile?Homeric
NVM was my bad: - github.com/vercel/next.js/discussions/66938Tumular

© 2022 - 2024 — McMap. All rights reserved.