Why is a file that is not required by any vue component get loaded client-side ?
Hey all,
I'm working on a nuxt project and was trying to get a typesafe env object working with arktype (though I have since switched to zod). It works great server-side, but apparently it also gets loaded on the client and throws because the values do not exist in that context (which is expected). The thing I don't get is why it gets loaded there in the first place xD.
Trying to use better-auth & drizzle, if it helps. The only thing I'm importing on the client side is the better-auth client, but in that file I'm not using that validated env.
Has anyone had the same issue ?
Nuxi info:
11 Replies
Hi @Matteo G. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
It's a common point of confusion in Nuxt projects: files or modules that you expect to be server-only sometimes end up in the client bundle. This usually happens due to how imports are handled and how Nuxt (and Vite) perform code-splitting and prefetching.
Here are the main reasons this can occur:
1. Imports Are Not Context-Aware by Default
If you import a file or module in a place that is used both server-side and client-side (for example, in a composable or a plugin that is not explicitly server-only), Nuxt will include it in both bundles. Even if you don't use the env object in your client code, if the import exists in a file that is loaded client-side, it will be bundled and executed there. 2. Prefetching and Code-Splitting
Nuxt (and Vite) may prefetch or preload chunks for performance reasons, which can result in files being loaded even if they're not strictly required immediately. This is a performance optimization, not a bug. For example, dynamic imports in application hooks can cause files to be loaded twice (once for prefetch, once for use), as discussed in this issue. 3. How to Prevent This
- Make sure that any code or modules that should only run server-side are only imported in server-only contexts. In Nuxt, you can use
Nuxt's environment variables from
If a file is being loaded client-side when you expect it to be server-only, it's likely because it is imported (directly or indirectly) in a file that is included in the client bundle. Double-check your import paths and use Nuxt's server/client file conventions to control where code is executed. This is a common pitfall, especially when validating env variables or using libraries that are not browser-compatible. If you need more specific help, try to isolate where the import is happening and ensure it's only in server-only files or plugins. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
If you import a file or module in a place that is used both server-side and client-side (for example, in a composable or a plugin that is not explicitly server-only), Nuxt will include it in both bundles. Even if you don't use the env object in your client code, if the import exists in a file that is loaded client-side, it will be bundled and executed there. 2. Prefetching and Code-Splitting
Nuxt (and Vite) may prefetch or preload chunks for performance reasons, which can result in files being loaded even if they're not strictly required immediately. This is a performance optimization, not a bug. For example, dynamic imports in application hooks can cause files to be loaded twice (once for prefetch, once for use), as discussed in this issue. 3. How to Prevent This
- Make sure that any code or modules that should only run server-side are only imported in server-only contexts. In Nuxt, you can use
.server.ts
or .server.js
file extensions, or place code in the server/
directory.
- For plugins, use the .server
or .client
suffix or specify the mode in your nuxt.config
to control where they are loaded (plugins documentation).
- Avoid importing server-only code in files that are shared with the client.
4. Environment VariablesNuxt's environment variables from
.env
files are only available at build and dev time, and should be accessed via runtime config in your application code. They are not available client-side unless explicitly exposed, so trying to access them directly on the client will fail as you observed (.env documentation).
Summary:If a file is being loaded client-side when you expect it to be server-only, it's likely because it is imported (directly or indirectly) in a file that is included in the client bundle. Double-check your import paths and use Nuxt's server/client file conventions to control where code is executed. This is a common pitfall, especially when validating env variables or using libraries that are not browser-compatible. If you need more specific help, try to isolate where the import is happening and ensure it's only in server-only files or plugins. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@189947320261935105> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai the file is located in the
lib
folder, so I think it should not be bundled client side by default, right ?Let me check the knowledge base for you again. One moment! :books:
----------------------
You're correct that, by default, files in the lib/ folder are not automatically bundled or auto-imported by Nuxt on the client side. However, if a file from lib/ is imported (directly or indirectly) by any code that is executed client-side—such as a plugin, composable, or component—then it will be included in the client bundle.
The knowledge sources confirm that Nuxt auto-imports from certain directories like components/, composables/, and utils/, but not lib/ by default. Files in lib/ require manual imports, and will only be included in the client bundle if something client-side imports them, either directly or through a chain of imports. If you want to auto-import from a custom folder like lib/, you would need to explicitly configure this in your nuxt.config, but otherwise, manual imports are required and control where the code is bundled and executed Docs: Auto-imports Stack Overflow: Arbitrary code in Nuxt 3.
So, if your lib/ file is being loaded client-side, it's likely because it is being imported somewhere in code that runs on the client. Double-check your import paths and usage to ensure it's only used server-side if that's your intention.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
<@189947320261935105> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai would having that import in nuxt.config.ts bundle it client-side ?
Let me check the knowledge base for you again. One moment! :books:
----------------------
No, importing a file in your
nuxt.config.ts
will not cause it to be bundled client-side. The nuxt.config.ts
file is only used at build time and is not included in the client or server runtime bundles. Its imports are processed by Node.js (or the build tool) when Nuxt starts or builds your project, and do not affect the client bundle.
This is supported by the documentation, which explains that nuxt.config.ts
is used to configure your Nuxt application and is not part of the runtime code that gets shipped to the client or server Nuxt Configuration Docs.
So, you can safely import files in nuxt.config.ts
without worrying about them being included in the client bundle.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@189947320261935105> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai after further analysis, it appears the error originates from importing the "env" file from a middleware to check for authenticated users. Is there a way to avoid this ?
Let me check the knowledge base for you again. One moment! :books:
----------------------
If you import your "env" file (which likely contains server-only logic or secrets) directly in middleware, it will be bundled and executed both on the server and the client, since Nuxt middleware runs in both contexts by default. This is why you see errors client-side—those values do not exist there.
How to avoid this:
You can conditionally import or use your "env" file only on the server side by checking the execution context in your middleware. The Nuxt documentation recommends using
To avoid client-side errors, always guard server-only imports or logic in middleware with
import.meta.server
to ensure code only runs on the server:
Alternatively, you can structure your middleware so that server-only code is not executed or imported on the client. This approach is shown in the Nuxt middleware documentation:
Summary:To avoid client-side errors, always guard server-only imports or logic in middleware with
import.meta.server
. This ensures your "env" file is only used where it is valid and available Docs: Middleware Execution Context.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@189947320261935105> Kapa.ai is still learning and improving, please let me know how I did by reacting below.