Nuxt结合Docker(Compose)部署时环境变量API_URL失效及window未定义问题排查
Let's tackle your two issues one by one with clear, actionable fixes:
First, let's break down why this happens: Nuxt handles environment variables differently for server-side vs client-side code. When running in production (like your Docker deployment), only variables prefixed with NUXT_ENV_ are automatically injected into the client-side bundle. Your current API_URL is only available to the server, so your client-side code can't access it—resulting in those incorrect request paths.
Fix Options:
You have two reliable paths here:
Option 1: Rename the environment variable
Update your Docker Compose config to useNUXT_ENV_API_URLinstead ofAPI_URL:environment: - NUXT_ENV_API_URL=https://xxx.xxx.de/api/api/v1/ - BASE_URL=https://xxx.xxx.de/Then in your Nuxt plugin, reference it as
process.env.NUXT_ENV_API_URL. This works because Nuxt automatically exposes anyNUXT_ENV_*variables to both server and client environments.Option 2: Use Nuxt's public runtime config
Keep your Docker variable asAPI_URL, but add this to yournuxt.config.js:export default { publicRuntimeConfig: { apiUrl: process.env.API_URL } }Then access it in your plugin or components via
this.$config.apiUrl(in Vue component context) orcontext.$config.apiUrl(in Nuxt plugins/middleware). This is a cleaner approach if you want to avoid prefixes and keep config centralized.
Why did it work locally? In dev mode, Nuxt exposes all environment variables to the client for convenience—this isn't the case in production for security reasons.
This is a classic SSR (Server-Side Rendering) gotcha: the window object only exists in the browser, but Nuxt runs your code on the server during SSR. The error lines (pages/index.js:398, 649, etc.) are trying to access window directly during server-side execution.
Fix Options:
- Wrap window access in a client-only check
Modify the code usingwindowto only run when on the client:if (process.client) { // Your window-dependent code goes here // Example: window.scrollTo(0, 0) } - Move window logic to client-side lifecycle hooks
If working in Vue components, place any window-related code in themountedhook (which only runs in the browser):export default { mounted() { // Safe to use window here window.someThirdPartyLib.init() } } - Mark problematic plugins as client-only
If the error comes from a third-party plugin, update yournuxt.config.jsto load it exclusively on the client:plugins: [ { src: '~/plugins/your-window-reliant-plugin.js', mode: 'client' } ]
Check the exact lines mentioned in the error log (pages/index.js:398, etc.)—those are the spots where you're referencing window without guarding against server-side execution.
内容的提问来源于stack exchange,提问作者Johannes Losch

