mongodbnext.jsenvironment-variables

Why environment variables inside .env.local will show undefined when I am using them in the directory called api located at root directory in next.js


I am new to Web Development and next.js and I am trying to figure out that when i console.log my environment variables inside my page.jsx it shows the values correctly but when i try to console.log them in my router.js inside the api directory then they come as undefined also when i pass my mongodb connection string which I saved in .env.local and pass it to mongoose.connect() in router.js it shows the following:

MongooseError: The uri parameter to openUri() must be a string, got "undefined".

router.js code:

import mongoose from "mongoose";
import { Dishes } from "./model.js";
import { NextResponse } from "next/server.js";
import * as dotenv from 'dotenv';

dotenv.config();

const ConnectDB = async () => { 
    await mongoose.connect(process.env.MONGO_STRING);
    const data = await Dishes.find();
    console.log("Db connected successfully");
    return NextResponse.json({result:data});
}

console.log(process.env.MONGO_STRING);
ConnectDB();

.env.local:

MONGO_STRING=mongodb+srv://<my username>:<my pass>@cluster0.i4i4snw.mongodb.net/

Package.json:

{
  "name": "project-swadi",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "dotenv": "^16.3.1",
    "mongoose": "^8.0.0",
    "next": "13.5.6",
    "react": "^18",
    "react-dom": "^18",
    "react-icons": "^4.11.0",
    "swiper": "^11.0.2"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10",
    "eslint": "^8",
    "eslint-config-next": "13.5.6",
    "postcss": "^8",
    "tailwindcss": "^3",
    "typescript": "^5"
  },
  "type": "module"
}

next project structure


Solution

  • Since your .env.local file is in the root, the api folder might be looking in the wrong place. Generally you call the config at the earliest entry point and you only call it once for the entire project (for me, that would be my app.js in the root with package.json). Since you have an app and an api folder in the same project, I'm curious how it is being served.

    Also, multiple .env files can be cumbersome so I would just use a main .env file and then you copy .env.local or .env.prod or whatever INTO that main .env when you want to use that connection. I believe dotenv is always looking for .env and nothing else.

    Here is something I have used to test to make sure everything is referenced properly.

    const dotenv = require('dotenv');
    const result = dotenv.config();
    if (result.error) {
      throw result.error; // this will tell you if something is wrong or missing
    }
    
    // if the code above throws an error, this can be used instead to find a specific .env if it is in another location
    require('dotenv').config({ path: '/path/to/your/.env.local' });