Dec 13, 2024

How to Make MongoDB Connection in Next.js: A Complete Guide

In a Next.js application, connecting to MongoDB efficiently requires a few key considerations due to its server-side rendering (SSR) capabilities. You want to ensure that the connection to MongoDB is established only once during the server lifecycle and reused across requests to avoid redundant connections.

Here’s a step-by-step guide to establishing a MongoDB connection in Next.js:

 

Step 1: Install Mongoose

First, you need to install Mongoose, which is a popular ODM (Object Data Modeling) library for MongoDB. It provides a more structured approach to interacting with MongoDB in Node.js environments.

Run the following command to install Mongoose:

pnpm install mongoose

 

Step 2: Create a MongoDB Connection Utility

In a Next.js application, you typically want to manage the database connection in a separate utility file. This utility should check whether the MongoDB connection already exists (to avoid creating a new one on every request) and only establish a new connection when necessary.

Create a new file inside the lib directory (e.g., lib/mongo.ts or lib/mongodb.ts).

// lib/db.ts or lib/mongodb.ts

import mongoose from "mongoose";

type ConnectionObject = {
    isConnected?: number;
};

// The connection object will hold the connection status
const connection: ConnectionObject = {};

// Function to connect to MongoDB
const connDb = async (): Promise<void> => {
    // Check if MongoDB is already connected to avoid redundant connections
    if (connection.isConnected) {
        console.log("MongoDB is already connected");
        return;
    }

    try {
        // Establish connection to the MongoDB database
        const db = await mongoose.connect(process.env.MONGO_URI || "");
        
        // Store the connection status in the connection object
        connection.isConnected = db.connections[0].readyState;
        
        console.log("MongoDB connected successfully");
    } catch (error) {
        console.error("Failed to connect to MongoDB:", error);
        process.exit(1); // Exit the application if connection fails
    }
};

export default connDb;

 

Explanation

1. Connection Type Declaration:

type ConnectionObject = {
    isConnected?: number;
};

We define a ConnectionObject type with an optional isConnected property. The isConnected property is used to track the connection state. It can be either 0 (disconnected), 1 (connected), or 2 (connecting), based on Mongoose's internal connection states.

 

2. Connection Object Initialization:

const connection: ConnectionObject = {};

We initialize a connection object to hold the isConnected status. This object will help ensure that we don’t establish a new database connection if one is already active.

 

3. Database Connection Logic:

  • Check Connection Status: Before attempting to establish a new connection, we check the connection.isConnected status. If isConnected is truthy (i.e., a value of 1 or true), the connection is considered active, and we log a message without trying to reconnect.
  • Establish Connection: If the connection is not active, we use mongoose.connect() to establish a connection to the database. The connection string is retrieved from the environment variable MONGO_URI, which should be stored securely in .env.local.
  • Error Handling: If the connection fails, we catch the error and log it. The process is then terminated using process.exit(1) to ensure that no further operations are executed with a failed database connection.

 

4. Exporting the Function:

export default connDb;

The connDb function is exported so it can be used across the application, such as in API routes or server-side code.

 

Conclusion

By following this approach, you ensure that your Next.js application only establishes a MongoDB connection when necessary, optimizing resource usage and preventing unnecessary overhead. This TypeScript solution provides clear type safety and error handling while working efficiently with MongoDB in server-side environments.