Sunday, December 28, 2025

thumbnail

MERN Blogging Platform from Scratch

 Building a MERN (MongoDB, Express, React, Node.js) blogging platform from scratch is a great way to learn how to build full-stack applications. I'll walk you through the basic steps and key concepts, and by the end, you'll have a functional blogging platform!

Here's a high-level roadmap to building the blog platform:

1. Set Up the Development Environment

Before starting, make sure you have the following installed:



Node.js and npm (Node package manager)



MongoDB (You can use MongoDB Atlas for a cloud database if you don’t want to install MongoDB locally)



VS Code or any code editor you're comfortable with



2. Backend: Node.js + Express + MongoDB

We'll start by setting up the backend with Node.js, Express, and MongoDB. The backend will handle all the CRUD operations (Create, Read, Update, Delete) for the blog posts.

a. Initialize Node.js Project

mkdir mern-blog

cd mern-blog

npm init -y


b. Install Dependencies

We’ll need some packages for the backend:

npm install express mongoose cors dotenv body-parser




express: For the server



mongoose: For interacting with MongoDB



cors: To handle cross-origin requests (so React can talk to the backend)



dotenv: For environment variables



body-parser: To handle incoming JSON data



c. Create the Server (index.js)

Create a new file called index.js in the root directory and set up a basic Express server:

const express = require('express');

const mongoose = require('mongoose');

const cors = require('cors');

require('dotenv').config();


const app = express();

app.use(cors());

app.use(express.json());


// Connect to MongoDB

mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })

  .then(() => console.log('MongoDB connected'))

  .catch((err) => console.log('Error connecting to MongoDB:', err));


// Define a basic route

app.get('/', (req, res) => {

  res.send('Welcome to the MERN Blog!');

});


// Start the server

const port = process.env.PORT || 5000;

app.listen(port, () => {

  console.log(`Server running on port ${port}`);

});


d. Create a .env File

Create a .env file to store sensitive information like your MongoDB URI:

MONGO_URI=your_mongodb_connection_string


e. Define Blog Post Model

Create a folder called models and add a BlogPost.js file to define the schema for the blog posts:

const mongoose = require('mongoose');


const blogPostSchema = new mongoose.Schema({

  title: {

    type: String,

    required: true

  },

  content: {

    type: String,

    required: true

  },

  author: {

    type: String,

    required: true

  },

  createdAt: {

    type: Date,

    default: Date.now

  }

});


const BlogPost = mongoose.model('BlogPost', blogPostSchema);


module.exports = BlogPost;


f. Create Routes for CRUD Operations

In your index.js file, add the routes to handle the creation, reading, updating, and deleting of blog posts.

const BlogPost = require('./models/BlogPost');


// Create a new blog post

app.post('/api/posts', async (req, res) => {

  try {

    const { title, content, author } = req.body;

    const newPost = new BlogPost({ title, content, author });

    await newPost.save();

    res.status(201).json(newPost);

  } catch (err) {

    res.status(400).json({ error: err.message });

  }

});


// Get all blog posts

app.get('/api/posts', async (req, res) => {

  try {

    const posts = await BlogPost.find();

    res.json(posts);

  } catch (err) {

    res.status(500).json({ error: err.message });

  }

});


// Get a single blog post by ID

app.get('/api/posts/:id', async (req, res) => {

  try {

    const post = await BlogPost.findById(req.params.id);

    if (!post) {

      return res.status(404).json({ error: 'Post not found' });

    }

    res.json(post);

  } catch (err) {

    res.status(500).json({ error: err.message });

  }

});


// Update a blog post

app.put('/api/posts/:id', async (req, res) => {

  try {

    const { title, content, author } = req.body;

    const updatedPost = await BlogPost.findByIdAndUpdate(req.params.id, { title, content, author }, { new: true });

    res.json(updatedPost);

  } catch (err) {

    res.status(400).json({ error: err.message });

  }

});


// Delete a blog post

app.delete('/api/posts/:id', async (req, res) => {

  try {

    await BlogPost.findByIdAndDelete(req.params.id);

    res.status(204).json({ message: 'Post deleted' });

  } catch (err) {

    res.status(500).json({ error: err.message });

  }

});


3. Frontend: React

Now, let's build the front-end using React.

a. Create the React App

Inside the mern-blog folder, create the React application:

npx create-react-app client

cd client

npm start


b. Install Axios

We’ll use Axios to make HTTP requests to the backend API.

npm install axios


c. Create Blog Components

Create a components folder inside the src folder and add components for listing posts, creating new posts, and viewing individual posts.



App.js: The main component that will route to different parts of the application.



import React from 'react';

import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';

import PostList from './components/PostList';

import CreatePost from './components/CreatePost';

import ViewPost from './components/ViewPost';


function App() {

  return (

    <Router>

      <div className="App">

        <Routes>

          <Route path="/" element={<PostList />} />

          <Route path="/create" element={<CreatePost />} />

          <Route path="/post/:id" element={<ViewPost />} />

        </Routes>

      </div>

    </Router>

  );

}


export default App;




PostList.js: Display a list of all blog posts.



import React, { useEffect, useState } from 'react';

import axios from 'axios';

import { Link } from 'react-router-dom';


function PostList() {

  const [posts, setPosts] = useState([]);


  useEffect(() => {

    axios.get('http://localhost:5000/api/posts')

      .then(response => setPosts(response.data))

      .catch(error => console.log(error));

  }, []);


  return (

    <div>

      <h1>Blog Posts</h1>

      <Link to="/create">Create a New Post</Link>

      <ul>

        {posts.map(post => (

          <li key={post._id}>

            <Link to={`/post/${post._id}`}>{post.title}</Link>

          </li>

        ))}

      </ul>

    </div>

  );

}


export default PostList;




CreatePost.js: Form to create a new blog post.



import React, { useState } from 'react';

import axios from 'axios';

import { useNavigate } from 'react-router-dom';


function CreatePost() {

  const [title, setTitle] = useState('');

  const [content, setContent] = useState('');

  const [author, setAuthor] = useState('');

  const navigate = useNavigate();


  const handleSubmit = async (e) => {

    e.preventDefault();

    const newPost = { title, content, author };


    try {

      await axios.post('http://localhost:5000/api/posts', newPost);

      navigate('/');

    } catch (error) {

      console.log(error);

    }

  };


  return (

    <div>

      <h1>Create a New Post</h1>

      <form onSubmit={handleSubmit}>

        <input

          type="text"

          placeholder="Title"

          value={title}

          onChange={(e) => setTitle(e.target.value)}

        />

        <textarea

          placeholder="Content"

          value={content}

          onChange={(e) => setContent(e.target.value)}

        />

        <input

          type="text"

          placeholder="Author"

          value={author}

          onChange={(e) => setAuthor(e.target.value)}

        />

        <button type="submit">Create Post</button>

      </form>

    </div>

  );

}


export default CreatePost;




ViewPost.js: View the details of a single post.



import React, { useEffect, useState } from 'react';

import axios from 'axios';

import { useParams } from 'react-router-dom';


function ViewPost() {

  const [post, setPost] = useState(null);

  const { id } = use


Learn MERN Stack Training in Hyderabad

Read More

Building a Forum or Commenting System

Building a Fitness Tracker in MERN

MERN Stack Job Board Project

Developing an E-commerce Site in MERN Stack

Visit Our Quality Thought Training Institute in Hyderabad

Get Directions

Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

About

Search This Blog

Powered by Blogger.

Blog Archive