Tauri Dotenvy Working Directory Fix
Problem
When adding dotenvy to a Tauri app to load environment variables, relative paths
like ../../.env fail because the working directory during cargo tauri dev is
not what you'd expect from the file structure.
Context / Trigger Conditions
Error symptoms:
GHOST_URL not setor similar "env var not set" errorsGhostClient::from_env()or API clients fail to initializedotenvy::from_filename("../../.env")returns Err- App works when env vars are exported manually but not via .env
Project structure:
project-root/
├── .env # Environment file here
├── Cargo.toml
├── crates/
└── ui/
├── src/
└── src-tauri/
├── Cargo.toml
└── src/
└── main.rs # dotenvy loaded here
Assumption (wrong):
Since main.rs is in ui/src-tauri/src/, you might think CWD is ui/src-tauri/
and use ../../.env to reach the project root.
Reality:
When cargo tauri dev runs, the working directory is the project root, not
ui/src-tauri/. So the path should just be .env.
Solution
Try multiple paths to handle different execution contexts:
fn main() {
// Load .env file - try multiple locations
// When running via `cargo tauri dev`, CWD is project root
// When running the binary directly, CWD varies
let env_paths = [
".env", // Project root (cargo tauri dev)
"../../.env", // From ui/src-tauri (if run directly)
"../.env", // From ui/ (if run from there)
];
let mut loaded = false;
for path in &env_paths {
if dotenvy::from_filename(path).is_ok() {
eprintln!("Loaded .env from: {}", path);
loaded = true;
break;
}
}
if !loaded {
eprintln!("Warning: Could not load .env file from any location");
}
tauri::Builder::default()
// ... rest of setup
}
Cargo.toml dependency:
[dependencies]
dotenvy = "0.15"
Verification
-
Add logging to see which path works:
eprintln!("Loaded .env from: {}", path); -
Check the Tauri dev output for the message:
Loaded .env from: .env -
Verify env vars are available:
println!("GHOST_URL = {:?}", std::env::var("GHOST_URL"));
Example
Before (fails):
fn main() {
// Wrong - assumes CWD is ui/src-tauri
if let Err(e) = dotenvy::from_filename("../../.env") {
eprintln!("Warning: Could not load .env: {}", e);
}
// ...
}
After (works):
fn main() {
// Correct - CWD is project root during cargo tauri dev
if let Err(e) = dotenvy::from_filename(".env") {
eprintln!("Warning: Could not load .env: {}", e);
}
// ...
}
Notes
- The working directory behavior is determined by how Tauri's dev command runs cargo
- In production builds, the working directory may be different (app installation dir)
- For production, consider embedding secrets differently or using a config file
- The multi-path approach handles both dev and various execution scenarios
- Always log which path was loaded to aid debugging
Related
- Tauri doesn't automatically load .env files - you must add dotenvy yourself
- This issue is separate from Tauri IPC (which only works in the webview)
- Environment variables set in the shell will override .env file values
