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.
Prerequisites:
Approach to Create Blogging Platform:
- Setup the Project by Creating a new NextJS project Install the necessary libraries.
- Design the layout of blogging platform, including components like Navbar, BlogList, Blogdetail, SearchBar, etc.
- We will use local storage to store the blog details.
- We will utilize useState and useEffect hooks to manage state and fetch blog data. we will use useRouter hook to access route parameters such as blog id.
- Implement a search feature for filtering blog posts based on the search query.
- We will implement Next.js routing to navigate between different pages (e.g., list of blogs, individual blog posts, create new blogs).
- We will style the application using bootstrap.
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:
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.
- **Navbar.js: This component defines a navigation bar for blogging platform. It uses the Link component from Next.js to create links to different pages of the website.
- **Createblog.js: This component allows users to add new blog posts by entering blog details.
- **BlogList.js: This component is responsible to retrieve and display a list of published blog posts.
- **[id].js: This componentdisplays the details of a specific blog post using dynamic routing. JavaScript `
// 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: