T
TanStackβ€’2mo ago
wise-white

Using Nitro with ViteJs (Server side env undefined)

vite.config.js
import { defineConfig } from 'vite';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import tsConfigPaths from 'vite-tsconfig-paths';
import tailwindcss from '@tailwindcss/vite';
import viteReact from '@vitejs/plugin-react';
import pkg from './package.json';
import path from 'path';
import { nitro } from 'nitro/vite';
import dotenv from "dotenv";

dotenv.config();

export default defineConfig(async () => {
return {
plugins: [
tsConfigPaths({
projects: ['./tsconfig.json'],
}),
tanstackStart(),
nitro(),
viteReact(),
tailwindcss(),
],
nitro: {
preset: 'aws-amplify',
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@workspace/ui': path.resolve(__dirname, '../../packages/ui/src'),
},
},
define: {
APP_VERSION: JSON.stringify(pkg.version),
},
};
});
import { defineConfig } from 'vite';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import tsConfigPaths from 'vite-tsconfig-paths';
import tailwindcss from '@tailwindcss/vite';
import viteReact from '@vitejs/plugin-react';
import pkg from './package.json';
import path from 'path';
import { nitro } from 'nitro/vite';
import dotenv from "dotenv";

dotenv.config();

export default defineConfig(async () => {
return {
plugins: [
tsConfigPaths({
projects: ['./tsconfig.json'],
}),
tanstackStart(),
nitro(),
viteReact(),
tailwindcss(),
],
nitro: {
preset: 'aws-amplify',
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@workspace/ui': path.resolve(__dirname, '../../packages/ui/src'),
},
},
define: {
APP_VERSION: JSON.stringify(pkg.version),
},
};
});
server code
export const fetchAuthedSessionFn = createServerFn().handler(async () => {
console.log('env client', import.meta.env.VITE_APP_EMPLOYER_COMPANY_KEY);
console.log('env server', process.env.AUTH_TOKEN_KEY);

return fetchServerSessionFn({
data: { key: process.env.AUTH_TOKEN_KEY },
});
});
export const fetchAuthedSessionFn = createServerFn().handler(async () => {
console.log('env client', import.meta.env.VITE_APP_EMPLOYER_COMPANY_KEY);
console.log('env server', process.env.AUTH_TOKEN_KEY);

return fetchServerSessionFn({
data: { key: process.env.AUTH_TOKEN_KEY },
});
});
import.meta.env.VITE_APP_EMPLOYER_COMPANY_KEY ==> works But process.env.AUTH_TOKEN_KEY does not work what am I doing wrong here packages "@tanstack/react-start": "1.132.56" "vite": "^7.1.1" "nitro": "3.0.1-alpha.0"
14 Replies
metropolitan-bronze
metropolitan-bronzeβ€’2mo ago
does this happen without nitro as well?
wise-white
wise-whiteOPβ€’2mo ago
I try running the build locally. with vite after building it output in a dist/ folder. How do i run to test with vite alone? With the nitro i simply run node .amplify-hosting/compute/default/server.js and i am able to preview the app. But without nitro running node dist/server/server.js does not work how do i get to preview the vite to see if the env works without the nitro?
metropolitan-bronze
metropolitan-bronzeβ€’2mo ago
e.g. like this
pnpx srvx --prod -s ../client dist/server/server.js
pnpx srvx --prod -s ../client dist/server/server.js
wise-white
wise-whiteOPβ€’2mo ago
Thanks. env works without nitro server env is working without nitro πŸ‘πŸ½
metropolitan-bronze
metropolitan-bronzeβ€’2mo ago
can you please create an issue at https://github.com/nitrojs/nitro/ ? maybe this is a bug or needs a different config
GitHub
GitHub - nitrojs/nitro: Next Generation Server Toolkit. Create web ...
Next Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer. - nitrojs/nitro
wise-white
wise-whiteOPβ€’2mo ago
I am trying to setup Dockerfile with srvx Here’s the final runner stage of my Dockerfile for a TanStack Start + Vite SSR app. I’m using the srvx to serve the built app. Would appreciate help on anything I might be missing. It's a monorepo project
# ───── Runner Stage: Use srvx to serve the SSR app ─────
FROM base AS runner

WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nitro

USER nitro

COPY --from=installer /app/apps/tanstackapp/dist ./dist
COPY --from=installer /app/apps/tanstackapp/package.json ./package.json

# Expose the default SSR port
EXPOSE 3000

# Entrypoint with srvx (no Nitro)
CMD ["pnpx", "srvx", "--prod", "-s", "./client", "dist/server/server.js"]
# ───── Runner Stage: Use srvx to serve the SSR app ─────
FROM base AS runner

WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nitro

USER nitro

COPY --from=installer /app/apps/tanstackapp/dist ./dist
COPY --from=installer /app/apps/tanstackapp/package.json ./package.json

# Expose the default SSR port
EXPOSE 3000

# Entrypoint with srvx (no Nitro)
CMD ["pnpx", "srvx", "--prod", "-s", "./client", "dist/server/server.js"]
Fix for env variables not loading with Nitro v2/v3 in TanStack Start If your server-side environment variables aren't loading with @tanstack/react-start ^1.133.4 and Nitro, here's what worked for me: What I finally Tried doing: Load dotenv in your server entry file src/server.ts instead of vite.config
// src/server.ts
import dotenv from 'dotenv';
dotenv.config(); // This makes all .env vars available server-side

import handler from '@tanstack/react-start/server-entry'

export default {
fetch(request: Request) {
return handler.fetch(request)
},
}
// src/server.ts
import dotenv from 'dotenv';
dotenv.config(); // This makes all .env vars available server-side

import handler from '@tanstack/react-start/server-entry'

export default {
fetch(request: Request) {
return handler.fetch(request)
},
}
My working vite.config.js: with Nitro deploying to aws-amplify
import { defineConfig } from 'vite';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import { nitroV2Plugin } from '@tanstack/nitro-v2-vite-plugin';
// other imports...

// No dotenv here - not needed!

export default defineConfig(async () => {
return {
server: {
port: 3000,
},
plugins: [
tanstackStart(),
nitroV2Plugin({ preset: 'aws-amplify' }), // or your preset
// other plugins...
],
};
});
import { defineConfig } from 'vite';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import { nitroV2Plugin } from '@tanstack/nitro-v2-vite-plugin';
// other imports...

// No dotenv here - not needed!

export default defineConfig(async () => {
return {
server: {
port: 3000,
},
plugins: [
tanstackStart(),
nitroV2Plugin({ preset: 'aws-amplify' }), // or your preset
// other plugins...
],
};
});
Now process.env.YOUR_VAR works in all server functions and API routes. Client-side VITE_* vars still work normally through import.meta.env. Hope this helps someone! πŸš€
itchy-amethyst
itchy-amethystβ€’2mo ago
i have this problem too!!
absent-sapphire
absent-sapphireβ€’2mo ago
same issue @Manuel Schiller if I clone tanstack start basic and do this it outputs in dist folder which you cannot run using the default start command
metropolitan-bronze
metropolitan-bronzeβ€’2mo ago
the examples are not updated yet. create a new project using create-start-app for now please or just follow the hosting dogs
like-gold
like-goldβ€’4w ago
Also having this issue, but when trying to load .env in server.ts I get the error that this file doesn't exist.
xenial-black
xenial-blackβ€’3w ago
Heyy, bumping this thread as I've got a start app to deploy on amplify and I'm also stuck on reading the env at runtime. @Daniel Mantey is calling dotenv.config() really all you needed to make it work? I'm confued as there's no .env file in the build artifacts, I don't get how this works for you (doesn't work for me :D)
wise-white
wise-whiteOPβ€’3w ago
Did u try setting up the Environment variables in the AWS amplify console
xenial-black
xenial-blackβ€’3w ago
Yep, no luck But we also have some secrets we should probably not put there, I think we'll just fetch them from ssm at runtime @Daniel Mantey can you share your amplify.yml (if it doesn't contain any private stuff :D)
fair-rose
fair-roseβ€’2w ago
thank you ! now i have env variables injected properly.

Did you find this page helpful?