next.js icon indicating copy to clipboard operation
next.js copied to clipboard

allow importing "server-only" modules in `next.config.js`

Open stefanprobst opened this issue 1 year ago • 2 comments

Link to the code that reproduces this issue

https://github.com/stefanprobst/issue-next-config-server-import

To Reproduce

  1. clone https://github.com/stefanprobst/issue-next-config-server-import and run pnpm install
  2. pnpm run dev
  3. see error message:
 ⨯ Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error

> Build error occurred
Error: This module cannot be imported from a Client Component module. It should only be used from a Server Component.

Current vs. Expected behavior

i am trying to import a module which has import "server-only"; into next.config.js and get the following error:

 ⨯ Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error

> Build error occurred
Error: This module cannot be imported from a Client Component module. It should only be used from a Server Component.

i had assumed that next.config.js would not be read client side.

i also checked whether next.config.js is actually read client-side by adding the following code in next.config.js (and everything still worked, so i guess importing from server-only modules should be ok):

if (typeof document !== "undefined") {
  throw new Error("Reading next.config.js on the client.");
}

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #202403151937 SMP PREEMPT_DYNAMIC Fri Mar 15 19:52:22 UTC 2024
  Available memory (MB): 31401
  Available CPU cores: 16
Binaries:
  Node: 20.12.2
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 9.0.6
Relevant Packages:
  next: 14.3.0-canary.57 // Latest available version is detected (14.3.0-canary.57).
  eslint-config-next: N/A
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.4.5
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Module Resolution

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

also see this discussion: https://github.com/vercel/next.js/discussions/65605#discussioncomment-9393115

stefanprobst avatar May 11 '24 18:05 stefanprobst

I would also want this.

I'm migrating from pages to app directory and my pages depend on publicRuntimeConfig. For my publicRuntimeConfig to work, I'm importing ~/server/env.js which I would very much like to have import 'server-only' in now that the boundary between server and client is more fuzzy

KATT avatar Jun 10 '24 15:06 KATT

@huozhi could you clarify whether this is indeed an issue, or if this is intended behavior? thank you!

stefanprobst avatar Jun 28 '24 08:06 stefanprobst

ok so the docs state:

next.config.js is a regular Node.js module ... It gets used by the Next.js server and build phases, and it's not included in the browser build.

stefanprobst avatar Jul 15 '24 09:07 stefanprobst

A slightly hacky workaround I'm using for now:

try {
  require("server-only");
} catch (err) {
  if (err && typeof err === "object" && "code" in err && err.code === "MODULE_NOT_FOUND") {
  } else {
    throw err;
  }
}

But yea, it would be nice if it just worked.

Edit: My workaround only works if server-only is not explicitly included in the package.json.

Armster15 avatar Jul 20 '24 21:07 Armster15

+1 for this feature, I want to mark my server configuration as server only, but I want to check it on build.

ScreamZ avatar Oct 02 '24 09:10 ScreamZ

+1 - I am trying to import a "server only" file to validate server environment variables in next.config so that it validates at build time

napter avatar Feb 10 '25 17:02 napter

server-only actually means react-server-only, which when the environment will pick up react-server export condition of an export from a package, which is mostly designed for RSC. next.config.js is not bundled and it's loading modules through the default node.js export order, where react-server condition is not preferred. Hence it's actually just the default runtime, not "server-only", more like not "react server" only

huozhi avatar Feb 11 '25 02:02 huozhi

thanks for the explanation @huozhi! i guess this is working as intended then.

stefanprobst avatar Feb 12 '25 16:02 stefanprobst

@huozhi @stefanprobst - Is there any workaround? Is it possible to do anything so that "server-only" doesn't trigger when imported from the config file?

napter avatar Feb 24 '25 17:02 napter

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Mar 11 '25 12:03 github-actions[bot]