Can't import server-only code from Instrumentation
Answered
Black Russian Terrier posted this in #help-forum
Black Russian TerrierOP
I was attempting to perform some server-side startup code via a register hook in Instrumentation, and found that importing a module that imports
Removing the import from
server-only fails. The error message is:You're importing a component that needs server-only. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.Removing the import from
instrumentation.ts fixes the issue. It seems like it should be possible to have instrumentation code that is NodeJS specific, but due to this being marked as a client component that isn't possible. Given the runtime differences between Edge and NodeJS, perhaps there should be runtime specific instrumentation.ts files, e.g. instrumentation.nodejs.ts or something so that it doesn't need to be marked as a client component.Answered by Black Russian Terrier
I'll file a separate feature/proposal request on github as that will likely be the only solution.
6 Replies
@Black Russian Terrier I was attempting to perform some server-side startup code via a register hook in Instrumentation, and found that importing a module that imports `server-only` fails. The error message is:
`You're importing a component that needs server-only. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.`
Removing the import from `instrumentation.ts` fixes the issue. It seems like it should be possible to have instrumentation code that is NodeJS specific, but due to this being marked as a client component that isn't possible. Given the runtime differences between Edge and NodeJS, perhaps there should be runtime specific `instrumentation.ts` files, e.g. `instrumentation.nodejs.ts` or something so that it doesn't need to be marked as a client component.
the imported package wants to be used in a [client component](https://nextjs.org/docs/app/building-your-application/rendering/client-components#using-client-components-in-nextjs), so either convert the whole file or just the part that the import for (better option)
the error is because to use it, you should be in client component, so your ideas don't make sense when you can split up what needs to be server rendered and can be client...
the error is because to use it, you should be in client component, so your ideas don't make sense when you can split up what needs to be server rendered and can be client...
Black Russian TerrierOP
That doesn't seem to be what happened in this case. Moving my server-side setup code outside
instrumentation.ts was all it took to prevent NextJS from attempting to package the code for client-side. NextJS complains that instrumentation.ts itself is marked as a Client Component. Moving code out of that file immediately fixes the error and its no longer a Client Component.Black Russian TerrierOP
I mean, I have a solution that works, but its less than ideal because NextJS recognizes all code in
instrumentation.ts as Client Component, which is unfortunate.So the question is unresolved, as this appears to be an undocumented consequence of supporting the edge runtime inside the same file. Perhaps if it supported the runtime export like other files do to indicate which runtime its in, rather than having the user use if toggles to determine the runtime (which is not statically analyzeable).
Black Russian TerrierOP
I'll file a separate feature/proposal request on github as that will likely be the only solution.
Answer