Build a Blog API with Express and MongoDB

Connect a Next.js frontend to an Express API backed by MongoDB.

Introduction

30 Second Summary

Every website you visit with blog posts, product listings, or user profiles pulls that content from a database somewhere behind the scenes. A static page can only show what was hard-coded when it was built.

In this project, you will build an Express API connected to a MongoDB database that stores and serves blog articles to your Love Agency Next.js frontend.

What You'll Build

Open your browser to localhost:3000/blog and you'll see a list of real blog articles, each with a title, summary, and publication date. Run a curl command to create a new article, refresh the blog page, and watch it appear instantly.

By the end of this project, you'll have:

  • An Express API with GET and POST endpoints for blog articles that you can test with curl.
  • A MongoDB database storing article documents with title, content, summary, and timestamps.
  • Your Next.js Blog page fetching and rendering live data from the API with no page reload needed.
  • Secret Mission: Build a Services API endpoint and wire the Services page to display matchmaking packages from the database.

Are there any prerequisites?

This project assumes you have completed Project 1 (Build a Website with Next.js) and have the love-agency Next.js project on your Desktop. You should also have VS Code and Node.js already installed.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters. You're adding a backend to Love Agency so your Blog page can display real articles stored in MongoDB and served through an Express API.

Set Up MongoDB and Your Express Project

Your Next.js frontend has no way to store or retrieve data right now. Every page shows static content or placeholder text like "Articles coming soon."

You need two things before any page can display dynamic content: a database to hold articles and an API server to serve them. In this step, you'll install MongoDB as your database and create an Express API server that connects to it.

In this step, get ready to:
  • Install MongoDB Community Edition 8.0 and verify it's running.
  • Create a new Express project alongside your Next.js app.
  • Write a server file that connects to MongoDB and listens on port 4000.
Install MongoDB Community Edition 8.0

MongoDB is a document database that stores data as flexible JSON-like objects. Your Express API will read and write article data to MongoDB.

  • Check if MongoDB is already installed by running this command in your terminal:
mongod --version

✔️ I see version 8.0 or higher

MongoDB is already installed. Skip ahead to starting the service below.

ⓧ I see an older version

You have an older version of MongoDB installed. Install version 8.0 by running these commands:

brew tap mongodb/brew
brew install mongodb-community@8.0

What do these commands do?

The first command adds MongoDB's official Homebrew tap (a collection of install formulas). The second installs MongoDB Community Edition 8.0, which includes the mongod server and the mongosh shell.

ⓧ Command not found

MongoDB is not installed yet. Install it by running these commands:

brew tap mongodb/brew
brew install mongodb-community@8.0

What do these commands do?

The first command adds MongoDB's official Homebrew tap (a collection of install formulas). The second installs MongoDB Community Edition 8.0, which includes the mongod server and the mongosh shell.

🙋‍♀️ Seeing 'brew: command not found'?

Homebrew needs to be installed first. Visit brew.sh and follow the one-line install command, then retry the commands above.

Help me troubleshoot my Homebrew installation

  • Start the MongoDB service by running:
brew services start mongodb-community@8.0

What does this do?

This starts MongoDB as a background service that persists across reboots. You won't need to manually start it again.

  • Verify MongoDB is running by launching the MongoDB shell:
mongosh

You should see connection information and a test> prompt. This confirms MongoDB is running and accepting connections.

  • Exit the shell by typing:
exit

Seeing 'connection refused' in mongosh?

The MongoDB service may not have started properly. Open a new terminal tab and run brew services list to check. If mongodb-community@8.0 is not started, run brew services restart mongodb-community@8.0 and try again.

Help me fix my MongoDB connection issue

Create the Express project folder and install dependencies

Your API needs its own project folder, separate from the Next.js app. You'll create it on the Desktop right alongside your existing love-agency folder.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your API project folder and move into it by running these commands:
mkdir love-agency-api
cd love-agency-api
  • Confirm the folder exists by running:
ls ~/Desktop

You should see both love-agency and love-agency-api listed side by side.

  • Initialize a new Node.js project by running:
npm init -y

You'll see the generated package.json printed in your terminal. This file tracks your project's name, version, and dependencies.

  • Install the three packages your API needs by running:
npm install express mongoose cors

What are these packages?

  • express is the web framework that handles HTTP requests and routes.
  • mongoose is an ODM (Object Data Modeling) library that lets you define schemas and interact with MongoDB using JavaScript objects.
  • cors enables Cross-Origin Resource Sharing so your Next.js frontend can make requests to this API.

The install output shows the package versions. You should see express, mongoose, and cors listed as added packages.

Seeing 'npm: command not found'?

This means Node.js is not available in your current terminal session. Close and reopen your terminal, then run node --version to confirm Node.js is accessible before retrying.

Help me fix my npm installation issue

  • Open the love-agency-api folder in VS Code. Press Cmd+Shift+P (macOS) or Ctrl+Shift+P (Windows) to open the Command Palette.
  • Type File: Open Folder and press Enter.
  • Select the love-agency-api folder on your Desktop.
  • Open package.json from the Explorer sidebar. Update three fields to match your project:
  • Change "description" from "" to "Express API for Love Agency".
  • Change "main" from "index.js" to "server.js".
  • Replace the entire "scripts" section with:
"scripts": {
  "start": "node server.js",
  "dev": "node --watch server.js"
}

Why node --watch?

Node.js 22 has a built-in --watch mode that automatically restarts your server when you save changes. No extra tools needed.

  • Save package.json.

✔️ Awesome, I've got everything!

Great. Double check you've saved package.json and move on.

ⓧ I'd like to double check the full code

Your package.json should look exactly like this:

{
  "name": "love-agency-api",
  "version": "1.0.0",
  "description": "Express API for Love Agency",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "node --watch server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "2.8.6",
    "express": "5.2.1",
    "mongoose": "9.7.4"
  }
}
Create the server file and connect to MongoDB

This is the entry point for your API. It imports your packages, connects to MongoDB, and starts listening for requests.

  • Create a new file called server.js in the root of your love-agency-api folder. Paste the following code into it:
// Import dependencies
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');

// Create Express app and set port
const app = express();
const PORT = 4000;

// Enable CORS so the frontend can make requests
app.use(cors());

// Connect to MongoDB
mongoose.connect('mongodb://127.0.0.1:27017/love-agency')
  .then(() => console.log('Connected to MongoDB'))
  .catch((err) => console.error('MongoDB connection error:', err));

// Start the server
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

What does this code do?

  • app.use(cors()) allows requests from other origins (like your Next.js app on port 3000) to reach this API on port 4000.
  • mongoose.connect(...) opens a connection to a MongoDB database called love-agency. If the database doesn't exist yet, MongoDB creates it automatically when you first write data.
  • app.listen(PORT, ...) starts the Express server on port 4000 and prints a confirmation message.
  • Save server.js.

Before you start the server, what do you expect to see printed in the terminal if everything is working?

  • Start your server by running this command in the VS Code terminal:
node --watch server.js

You should see two messages printed:

Connected to MongoDB
Server running on http://localhost:4000

This confirms your Express server is running on port 4000 and successfully connected to MongoDB.

Seeing 'MongoDB connection error'?

Make sure MongoDB is still running. Open a new terminal tab and run brew services list to check. If mongodb-community@8.0 is not started, run brew services start mongodb-community@8.0 and restart your server.

Help me fix my MongoDB connection error in Express

✔️ Awesome, I've got everything!

Great. Double check you've saved server.js and your server is running.

ⓧ I'd like to double check the full code

Your server.js should look exactly like this (comments are optional):

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');

const app = express();
const PORT = 4000;

app.use(cors());

mongoose.connect('mongodb://127.0.0.1:27017/love-agency')
  .then(() => console.log('Connected to MongoDB'))
  .catch((err) => console.error('MongoDB connection error:', err));

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

Your database is running and your API server is alive. Next up, you'll define what an article looks like and build the endpoint that serves them.

Build the Article Schema and GET Endpoint

Your Express server is connected to MongoDB and running on port 4000. But if you hit the API right now, there's nothing for it to return.

You need two things: a data model that defines what a blog article looks like, and an endpoint that retrieves articles from the database. In this step you'll build both, then seed a test article to prove data flows from MongoDB through your API.

In this step, get ready to:
  • Create a Mongoose Article schema with title, content, summary, and automatic timestamps.
  • Build a GET endpoint that retrieves articles from the database.
  • Seed a test article and verify the endpoint serves it as JSON.
Create the Article schema

A Mongoose schema defines the shape of documents stored in a MongoDB collection. It declares what fields an article must have and what types those fields are.

  • Create a models folder inside your love-agency-api project by running this command:
mkdir models
  • Create a new file called Article.js inside the models folder and paste this code:
const mongoose = require('mongoose');

const articleSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
  },
  content: {
    type: String,
    required: true,
  },
  summary: {
    type: String,
    required: true,
  },
}, {
  timestamps: true,
});

module.exports = mongoose.model('Article', articleSchema);

What does this code do?

This file defines the shape of every article document in your database.

  • title, content, and summary are all required String fields. MongoDB will reject any article missing one of them.
  • timestamps: true tells Mongoose to automatically add createdAt and updatedAt fields to every document.
  • The last line exports a Mongoose model named Article that you can use to query and create documents.
  • Save models/Article.js.
  • Confirm the file exists by running:
ls models

You should see Article.js in the output.

✔️ Awesome, I've got everything!

Great. Make sure models/Article.js is saved before moving on.

ⓧ I'd like to double check the full code

const mongoose = require('mongoose');

const articleSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
  },
  content: {
    type: String,
    required: true,
  },
  summary: {
    type: String,
    required: true,
  },
}, {
  timestamps: true,
});

module.exports = mongoose.model('Article', articleSchema);
Create the GET endpoint for articles

An Express Router lets you group related endpoints into their own file. You'll create a router that handles all requests to /api/articles.

  • Create a routes folder inside your love-agency-api project by running:
mkdir routes
  • Create a new file called articles.js inside the routes folder and paste this code:
const express = require('express');
const router = express.Router();
const Article = require('../models/Article');

router.get('/', async (req, res) => {
  const articles = await Article.find().sort({ createdAt: -1 });
  res.json(articles);
});

module.exports = router;

What does this code do?

This file defines a single GET route that returns all articles as JSON.

  • Article.find() queries every document in the articles collection.
  • .sort({ createdAt: -1 }) orders results by newest first (descending timestamp).
  • res.json(articles) sends the results back to the client as a JSON response.
  • Save routes/articles.js.

✔️ Awesome, I've got everything!

Great. Make sure routes/articles.js is saved before moving on.

ⓧ I'd like to double check the full code

const express = require('express');
const router = express.Router();
const Article = require('../models/Article');

router.get('/', async (req, res) => {
  const articles = await Article.find().sort({ createdAt: -1 });
  res.json(articles);
});

module.exports = router;

The route file exists, but Express doesn't know about it yet. You need to register it in server.js.

  • In server.js, find this line near the top:
const cors = require('cors');
  • Add this new line directly below it:
const articlesRouter = require('./routes/articles');
  • Now scroll down and find the mongoose.connect block. After the closing .catch(...) line, add this:
app.use('/api/articles', articlesRouter);

What does app.use do here?

app.use('/api/articles', articlesRouter) mounts your router at the /api/articles path. Any GET request to http://localhost:4000/api/articles now hits the router.get('/') handler you just wrote.

  • Save server.js. Your node --watch process detects the change and automatically restarts the server.
  • Verify the endpoint works by running this in a separate terminal:
curl http://localhost:4000/api/articles

You should see [] printed in your terminal. That's an empty JSON array, which makes sense because you haven't added any articles to the database yet.

Seeing an error instead of []?

  • If you see Cannot find module './routes/articles', double check that routes/articles.js exists and the filename matches exactly (lowercase, no typos).
  • If you see Connection refused, your server may not be running. Switch back to the terminal running node --watch server.js and check for errors.
  • Make sure the require line in server.js uses './routes/articles' with the dot-slash prefix.

Still stuck? Help me debug why my /api/articles endpoint isn't returning an empty array.

✔️ Awesome, I've got everything!

Great. Confirm you see Connected to MongoDB and Server running on http://localhost:4000 in the terminal running your server.

ⓧ I'd like to double check the full code

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const articlesRouter = require('./routes/articles');

const app = express();
const PORT = 4000;

app.use(cors());

mongoose.connect('mongodb://127.0.0.1:27017/love-agency')
  .then(() => console.log('Connected to MongoDB'))
  .catch((err) => console.error('MongoDB connection error:', err));

app.use('/api/articles', articlesRouter);

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});
Seed a test article and verify the endpoint

The endpoint works but the database is empty. You'll insert a test article directly through the MongoDB shell to prove data flows all the way through your API.

  • Open a new terminal window and start the MongoDB shell by running:
mongosh
  • Switch to the love-agency database by running:
use love-agency
  • Insert a test article by running:
db.articles.insertOne({ title: "Finding Love in the Digital Age", content: "In today's connected world, finding meaningful relationships requires a balance of technology and authenticity.", summary: "A guide to navigating modern dating with confidence." })

You should see a response containing acknowledged: true and an insertedId. That confirms the article is stored.

  • Exit the MongoDB shell by running:
exit

Before you run the next command, what do you think the API will return now? Will it still be an empty array, or something different?

  • Test your prediction by running this in your regular terminal:
curl http://localhost:4000/api/articles

You should see your test article returned as JSON, complete with a title, summary, createdAt timestamp, and an auto-generated _id. Data is flowing from MongoDB through your Express API.

Still seeing an empty array?

  • Make sure you ran use love-agency before the insertOne command. Without it, the article goes into the wrong database.
  • Check that the mongoose.connect URL in server.js uses love-agency as the database name (after the last /).
  • Confirm MongoDB is still running with brew services list and look for mongodb-community showing started.

Need more help? Help me figure out why my seeded article isn't showing up in the API response.

Your API now serves articles from MongoDB. Next up, you'll build the POST endpoint so you can create articles through the API instead of using the database shell directly.

Add the POST Endpoint to Create Articles

Your GET endpoint works and returns articles from the database. Now you need a way to create articles through the API without opening mongosh every time.

In this step, you'll build a POST endpoint and hit a wall that every Express developer encounters. The fix teaches you one of the most important concepts in Express: how middleware works.

In this step, get ready to:
  • Attempt to POST a new article and discover that Express does not parse JSON by default.
  • Add express.json() middleware and understand why order matters.
  • Successfully create an article via POST and verify it appears in the GET response.
Add a POST route and attempt to create an article

Before you can POST data, you need a route handler that accepts article data from the request body and saves it to MongoDB.

  • In VS Code, open routes/articles.js in your love-agency-api project.
  • Find the line that says module.exports = router; and add this POST route above it:
router.post('/', async (req, res) => {
  // Create a new Article from the incoming request data
  const article = new Article({
    title: req.body.title,
    content: req.body.content,
    summary: req.body.summary,
  });
  // Save the article to MongoDB
  const saved = await article.save();
  // Return the saved article with a 201 Created status
  res.status(201).json(saved);
});

What does this code do?

This route handler listens for POST requests at /api/articles. When a request arrives, it pulls title, content, and summary from req.body and creates a new Mongoose document.

The 201 status code tells the client that a new resource was created. The saved document comes back with an _id and timestamps that MongoDB generated automatically.

  • Save routes/articles.js. Your server restarts automatically thanks to node --watch.

Now try creating an article. Before you run this command, ask yourself: do you think Express will be able to read the JSON data you send?

  • Open a new terminal window (keep your server running in the other one) and attempt to create an article by running this POST request:
curl -X POST http://localhost:4000/api/articles -H "Content-Type: application/json" -d '{"title": "Finding Love Online", "content": "Online dating has changed how people connect across the world.", "summary": "A look at modern dating trends."}'

You'll see an error response instead of a shiny new article. Your server terminal shows something about a TypeError accessing properties of undefined. This is intentional.

Why did this fail?

Express does not parse JSON request bodies by default. When your curl command sent JSON data, Express received the raw bytes but never decoded them. So req.body is undefined.

Trying to access req.body.title on undefined throws a TypeError. Express 5 catches rejected promises in async handlers and returns a 500 error to the client.

Add express.json() middleware to parse request bodies

Middleware in Express is code that runs between receiving a request and executing your route handler. You need a middleware that reads incoming JSON and makes it available on req.body.

  • Switch back to server.js in VS Code.
  • Find this line:
app.use(cors());
  • Add this line directly below it:
app.use(express.json());
  • Your middleware section should now look like this:
app.use(cors());
app.use(express.json());

Why does middleware order matter?

Express runs middleware in the order you register it. express.json() must come BEFORE your route handlers. If it came after, the routes would still see undefined for req.body because the parser hasn't run yet.

Think of it like a conveyor belt: cors() adds CORS headers first, then express.json() decodes the JSON body, and finally your route handler uses the decoded data.

  • Save server.js. Your server restarts automatically.

Server not restarting?

If your server didn't restart, check the terminal where it's running. Make sure you see the "Connected to MongoDB" message again. If not, stop it with Ctrl+C and restart with npm run dev.

Help me troubleshoot why node --watch isn't restarting

Create an article and verify it appears

The JSON parser is in place. Time to try that POST request again.

Before you run the command below, what do you expect to see this time?

  • Run the same curl POST command again:
curl -X POST http://localhost:4000/api/articles -H "Content-Type: application/json" -d '{"title": "Finding Love Online", "content": "Online dating has changed how people connect across the world.", "summary": "A look at modern dating trends."}'

This time you'll see the new article returned as JSON, complete with an _id, createdAt, and updatedAt fields that MongoDB generated.

  • Now verify both articles exist by running:
curl http://localhost:4000/api/articles

You should see an array with two articles: the test article you seeded with mongosh in the previous step and the one you just created via POST.

Still seeing an error on POST?

Make sure app.use(express.json()) appears BEFORE app.use('/api/articles', articlesRouter) in server.js. Order matters.

Also confirm you included the -H "Content-Type: application/json" header in your curl command. Without it, Express does not know the body is JSON.

Help me debug why my POST request is still failing

✔️ Awesome, I've got everything!

Great. Double check you've saved both files.

ⓧ I'd like to double check the full code

Here is the full routes/articles.js with both the GET and POST routes:

const express = require('express');
const router = express.Router();
const Article = require('../models/Article');

router.get('/', async (req, res) => {
  const articles = await Article.find().sort({ createdAt: -1 });
  res.json(articles);
});

router.post('/', async (req, res) => {
  const article = new Article({
    title: req.body.title,
    content: req.body.content,
    summary: req.body.summary,
  });
  const saved = await article.save();
  res.status(201).json(saved);
});

module.exports = router;

Here is the full server.js with the express.json() middleware added:

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const articlesRouter = require('./routes/articles');

const app = express();
const PORT = 4000;

app.use(cors());
app.use(express.json());

mongoose.connect('mongodb://127.0.0.1:27017/love-agency')
  .then(() => console.log('Connected to MongoDB'))
  .catch((err) => console.error('MongoDB connection error:', err));

app.use('/api/articles', articlesRouter);

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

You can now create articles from the command line and read them back through the API. Next up, you'll wire your Next.js Blog page to this API so your frontend displays real articles from the database.

Wire Your Next.js Blog Page to the API

Your API can store and serve articles. But your Blog page still says "Articles coming soon" because it has no idea the API exists.

In this step, you will connect your Next.js frontend to the Express API. The Blog page will fetch real articles from MongoDB and display them as cards.

In this step, get ready to:
  • Fetch blog articles from the API using a Server Component.
  • Display each article as a card with title, summary, and formatted date.
  • Confirm new articles appear instantly after creation.
Update the Blog page to fetch articles

Next.js Server Components can fetch data directly inside the component function. No useEffect, no client-side loading spinner. The server fetches the data before sending the page to the browser.

  • In VS Code, open src/app/blog/page.tsx inside your love-agency project.
  • Select all the existing code and replace it with the following imports, metadata, and Article interface:
import type { Metadata } from "next";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";

export const metadata: Metadata = {
  title: "Blog - Love Agency",
  description: "Read our latest articles about dating, relationships, and love.",
};

interface Article {
  _id: string;
  title: string;
  content: string;
  summary: string;
  createdAt: string;
}

What does this code do?

  • The Card imports bring in the shadcn components you already installed in Project 1. You will use them to render each article.
  • The metadata export sets the page title and description for search engines.
  • The Article interface defines the shape of data coming back from your API so TypeScript can check your code.
Display each article as a card

Now you need the component function that fetches articles and renders them. This is where the async keyword makes the magic happen. The function awaits the API response before returning any JSX.

  • Below the Article interface, add the BlogPage component function:
export default async function BlogPage() {
  const res = await fetch("http://localhost:4000/api/articles", {
    cache: "no-store",
  });
  const articles: Article[] = await res.json();

  return (
    <div className="max-w-4xl mx-auto py-16 px-4">
      <h1 className="text-3xl font-bold mb-8">Blog</h1>
      {articles.length === 0 ? (
        <p className="text-gray-600">No articles yet. Check back soon!</p>
      ) : (
        <div className="grid gap-6">
          {articles.map((article) => (
            <Card key={article._id}>
              <CardHeader>
                <CardTitle>{article.title}</CardTitle>
                <p className="text-sm text-gray-500">
                  {new Date(article.createdAt).toLocaleDateString("en-US", {
                    year: "numeric",
                    month: "long",
                    day: "numeric",
                  })}
                </p>
              </CardHeader>
              <CardContent>
                <p className="text-gray-600">{article.summary}</p>
              </CardContent>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}

What does this code do?

  • fetch("http://localhost:4000/api/articles", { cache: "no-store" }) calls your Express API on every request. The no-store option tells Next.js to never cache the response, so you always see fresh data.
  • The async keyword on the function makes this a Server Component that fetches data on the server before sending HTML to the browser.
  • The ternary checks if articles.length === 0 and shows a fallback message. Otherwise it maps over articles and renders each one as a Card with the title, formatted date, and summary.
  • toLocaleDateString("en-US", ...) turns the raw timestamp into a readable format like "July 15, 2026".
  • Save page.tsx.
  • Make sure your Express API is still running in its terminal (you should see Connected to MongoDB in that terminal).
  • Open a new terminal window for the Next.js dev server. Move into your love-agency folder and start it by running:
cd ~/Desktop/love-agency
npm run dev

Before you check the browser, think about what you expect to see. Do you think the Blog page will show your articles, or will something go wrong?

  • Open your browser and visit http://localhost:3000/blog.

You should see your articles displayed as cards. Each card has the article title in bold, a formatted date below it, and the summary text in the card body.

Seeing a blank page or error?

  • Check that your Express API is still running on port 4000. The Next.js server fetches from localhost:4000 at render time. If the API is down, the fetch fails.
  • Make sure MongoDB is running. Run brew services list and confirm mongodb-community shows as started.
  • Confirm you saved page.tsx after pasting both code blocks. An incomplete file will not compile.

help me debug why my Blog page isn't showing articles from the API

✔️ Awesome, I've got everything!

Great. Double check you have saved page.tsx and can see articles in your browser.

ⓧ I'd like to double check the full code

Scroll up and confirm your page.tsx contains both chunks in order:

  • The imports, metadata export, and Article interface (first chunk).
  • The BlogPage async function with the fetch call and the Card rendering (second chunk).

Make sure there is nothing else in the file. The two chunks together form the complete page.tsx.

Create a new article and confirm it appears

The real test of a live connection is creating new data and watching it show up without any code changes. Because you used cache: "no-store", Next.js fetches fresh data on every page load.

  • Open another terminal window and create a new article by running:
curl -X POST http://localhost:4000/api/articles \
  -H "Content-Type: application/json" \
  -d '{"title": "Finding Love in the Digital Age", "content": "Technology has changed how we connect with potential partners.", "summary": "How dating apps and AI are reshaping modern romance."}'

You should see the new article returned as JSON with an _id and timestamps.

  • Switch back to your browser at http://localhost:3000/blog and refresh the page.

The new article appears at the top of the list with the title "Finding Love in the Digital Age" and today's date. That is the full stack in action: curl to API to MongoDB and back to your Next.js page.

New article not showing up?

  • Make sure you refreshed the browser page. Server Components fetch on each new request, but you need to trigger a new page load.
  • Check the curl output. If you see an error instead of JSON, your API may have stopped. Return to the API terminal and restart it with node --watch server.js.

help me figure out why new articles don't appear on my Blog page after I create them with curl

Your frontend is now wired to real data. Next up, the Secret Mission challenges you to build a second API endpoint and connect another page.

Secret mission

Build the Informational Services Page

Love Agency's Services page is still a placeholder. Can you build a static page that explains what the agency does — travel arrangement, couple counseling, and marriage accompaniment — and shows potential clients why the agency is worth their trust? No database needed. Just a clean, informational page that sells the experience.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

This project runs entirely locally, so there are no ongoing costs.

Resources you used:

  • The love-agency-api project folder on your Desktop (Express API source code and dependencies).
  • The MongoDB service running via Homebrew (stores your article and service data).
  • The love-agency Next.js project (updated Blog and Services pages).

Keep everything running

No action needed. Choose this if you're still actively building on Love Agency.

  • Your MongoDB service persists across reboots when started with brew services.
  • Run node --watch server.js in the love-agency-api folder anytime to restart the API server.
  • Run npm run dev in the love-agency folder to restart the Next.js dev server.

Pause - I'll come back to this later

Shut down running processes to free up memory. Your files and data stay exactly where they are.

  • Stop both servers by pressing Ctrl+C in each terminal window.
  • MongoDB keeps running as a background service. Your data stays in the database until you return.
  • When you come back, run node --watch server.js in the API folder and npm run dev in the Next.js folder to pick up where you left off.

Delete - I don't want to use this again

Remove all project resources and start fresh. This deletes the API code, stops MongoDB, and uninstalls it from your machine.

  • Stop both servers by pressing Ctrl+C in each terminal window.
  • Stop the MongoDB service by running:
brew services stop mongodb-community@8.0
  • Delete the API folder by running:
rm -rf ~/Desktop/love-agency-api
  • To fully uninstall MongoDB from your machine, run these commands:
brew uninstall mongodb-community@8.0
brew untap mongodb/brew
  • Your love-agency Next.js project still exists on your Desktop. The updated Blog and Services pages will show fetch errors without the API running. You can leave them as-is or revert src/app/blog/page.tsx and src/app/services/page.tsx to their previous state.

Nice Work!

Nice Work!

Nice work! You just built a full-stack data pipeline for Love Agency.

You've learned how to:

  • Installed MongoDB locally and connected it to an Express API server.
  • Built a Mongoose Article schema and REST endpoints (GET and POST) for blog content.
  • Discovered how Express middleware works by hitting the JSON parsing wall and fixing it.
  • Wired your Next.js Blog page to fetch real data from the API using Server Components.
  • Secret Mission: Built a second API endpoint for Services and wired the Services page, proving the pattern is repeatable.

Ready to quiz yourself?