Blogging Platform using Next JS (original) (raw)

Last Updated : 13 Mar, 2024

In this project, we will explore the process of building The Blogging Platform with Next.js. Blogging Platform is a web application that allows users to create and publish blog posts. The platform provides a user-friendly interface for managing blog content and includes functionalities to create new blogs, search for blogs, and read the detailed content of specific blogs.

**Output Preview: Let us have a look at how the final output will look like.

gfg-blog

Prerequisites:

Approach to Create Blogging Platform:

Steps to Create the Blogging Platform:

**Step 1: Create a application of NextJS using the following command.

npx create-next-app blog-app

**Step 2: Navigate to project directory

cd blog-app

**Step 3: Install the necessary package in your project using the following command.

npm install bootstrap

Step 4: Create the folder structure as shown below and create the files in respective folders.

Project Structure:

Screenshot-(18)

The updated dependencies in **package.json file will look like:

"dependencies": {
"bootstrap": "^5.3.3",
"next": "14.1.3",
"react": "^18",
"react-dom": "^18"
}

**Example: Below are the components which describes the implementation of the Blogging platform.

// page.js

import React from 'react' import BlogList from '@/Components/BlogList';

const page = () => { return ( <> </> ) }

export default page

JavaScript

// Navbar.js

import React from 'react'; import Link from 'next/link';

const Navbar = () => { return (

); };

export default Navbar;

` JavaScript ``

// BlogList.js

'use client' import React, { useState, useEffect } from 'react'; import 'bootstrap/dist/css/bootstrap.min.css'; import Navbar from '@/Components/Navbar'; import Link from 'next/link';

function BlogList() { const [data, setData] = useState([]); const [expandedId, setExpandedId] = useState(null); const [searchQuery, setSearchQuery] = useState('');

useEffect(() => {
    const blogs =
        JSON.parse(localStorage.getItem('myData') || '[]');
    setData(blogs);
}, []);


const toggleExpanded = (id) => {
    setExpandedId(expandedId === id ? null : id);
};

let filteredData = data;
if (searchQuery.trim() !== '') {
    filteredData = data.filter(item =>
        item.title.toLowerCase()
            .includes(searchQuery.toLowerCase())
    );
}

return (
    <div>
        <Navbar />
        <div className="container bg-light"
            style={{ marginTop: '5rem' }}>
            <input
                type="text"
                className="form-control mb-2"
                placeholder="Search..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
            />
            <div className="row">
                {
                    filteredData.map((item) => (
                        <div key={item.id} className="col-md-4">
                            <div className="card mb-3">
                                <img src={item.imageUrl} 
                                    className="card-img-top" 
                                    alt="Blog" />
                                <div className="card-body">
                                    <h5 className="card-title">
                                        {item.title}
                                    </h5>
                                    <p className="card-text">
                                        {
                                            expandedId ===
                                                item.id ?
                                                item.description :
                                                `${item.description.substring(0, 50)}...`
                                        }
                                    </p>
                                    <div className="d-flex justify-content-between 
                                        align-items-center row">
                                        <div>
                                            <p className="m-0 small col">
                                                {"posted by "}
                                                {item.author}
                                            </p>
                                            <small className="text-muted">
                                                {item.date}
                                            </small>
                                        </div>
                                    </div>
                                    <Link href={`/blog/${item.id}`}>
                                        <button className='btn btn-primary'>
                                            Read more
                                        </button>
                                    </Link>
                                </div>
                            </div>
                        </div>
                    ))}
            </div>
        </div>
    </div>
);

}

export default BlogList;

`` JavaScript `

// Createblog.js

'use client' import React, { useState, useEffect } from 'react'; import 'bootstrap/dist/css/bootstrap.min.css'; import Navbar from '@/Components/Navbar';

const Createblog = () => { const [author, setAuthor] = useState(''); const [title, setTitle] = useState(''); const [description, setDescription] = useState(''); const [imageUrl, setImageUrl] = useState(''); const initialBlogs = typeof window !== 'undefined' ? JSON.parse(localStorage.getItem('myData')) || [] : []; const [data, setData] = useState(initialBlogs);

useEffect(() => {
    // Save habits to localStorage whenever they change
    localStorage.setItem('myData', JSON.stringify(data));
}, [data]);

const addData = () => {
    const currentDate = new Date().toLocaleDateString();
    const newData =
    {
        id: data.length + 1,
        author: author,
        date: currentDate,
        title: title,
        description: description,
        imageUrl: imageUrl
    };
    const updatedData = [...data, newData];
    setData(updatedData);
    setAuthor('');
    setTitle('');
    setDescription('');
    setImageUrl('');
};

return (
    <div>
        <Navbar />
        <div className="container bg-light" 
             style={{ marginTop: '5rem' }}>
            <div className="row">
                <div className="col">
                    <input
                        type="text"
                        className="form-control mb-2"
                        placeholder="Author"
                        value={author}
                        onChange={(e) => setAuthor(e.target.value)}
                    />
                    <input
                        type="text"
                        className="form-control mb-2"
                        placeholder="Title"
                        value={title}
                        onChange={(e) => setTitle(e.target.value)}
                    />
                    <textarea
                        className="form-control mb-2"
                        placeholder="Description"
                        value={description}
                        onChange={(e) => setDescription(e.target
                                                         .value)}
                    />
                    <input
                        type="text"
                        className="form-control mb-2"
                        placeholder="Image URL"
                        value={imageUrl}
                        onChange={(e) =>setImageUrl(e.target.value)}
                    />
                    <button onClick={addData} 
                            className="btn btn-primary mb-2">
                        Add Data
                    </button>
                </div>
            </div>
        </div>
    </div>
);

};

export default Createblog;

JavaScript

// pages/[id].js

import React, { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; import Navbar from '@/Components/Navbar'; import 'bootstrap/dist/css/bootstrap.min.css';

const BlogDetails = () => {

const [blogDetail, setBlogDetail] = useState([]);
const router = useRouter();
const { id } = router.query;
useEffect(() => {
    const blogs = JSON.parse(localStorage.getItem('myData'));
    const selectedBlog=blogs.find(blog => blog.id === parseInt(id));
    setBlogDetail(selectedBlog);
}, [id]);


if (!blogDetail) {
    return <div>Loading...</div>;
}

return (
    <div className="container bg-light" 
         style={{ marginTop: '5rem' }}>
        <Navbar />
        <div className="card mt-5">
            <img src={blogDetail.imageUrl}
                style={
                    {
                        maxWidth: '100%',
                        maxHeight: '300px'
                    }}
                className="card-img-top" alt="Blog" />
            <div className="card-body">
                <h1 className="card-title">{blogDetail.title}</h1>
                <p className="card-text">
                    {blogDetail.description}
                </p>
                <p className="card-text">
                    Author: {blogDetail.author}
                </p>
                <p className="card-text">Date: {blogDetail.date}</p>
            </div>
        </div>
    </div>
);

};

export default BlogDetails;

`

**Start your application using the following command:

npm run dev

**Output: Naviage to the URL **http://localhost:3000:

gfg-blog-live