WebDevStory
  • Tech
    • Software Testing
    • IT and Management
    • Software Engineering
    • Technology
  • Web
    • JavaScript
    • Web Development
    • Front-end Development
    • React
    • Database Technologies
  • AI
    • AI and Machine Learning
    • AI in Education
    • AI Learning
    • AI Prompts
  • Programming
    • Coding
    • Design Patterns
  • Misc
    • Digital Transformation
    • SEO
    • Technology and Business
    • Technology and Innovation
    • Developer Roadmaps
    • Digital Marketing
  • More
    • Newsletter
    • Support Us
    • Contact
    • Tech & Lifestyle
    • Digital Nomadism
  • Services
    • Tech Services
    • WordPress Maintenance Package
No Result
View All Result
WebDevStory
  • Tech
    • Software Testing
    • IT and Management
    • Software Engineering
    • Technology
  • Web
    • JavaScript
    • Web Development
    • Front-end Development
    • React
    • Database Technologies
  • AI
    • AI and Machine Learning
    • AI in Education
    • AI Learning
    • AI Prompts
  • Programming
    • Coding
    • Design Patterns
  • Misc
    • Digital Transformation
    • SEO
    • Technology and Business
    • Technology and Innovation
    • Developer Roadmaps
    • Digital Marketing
  • More
    • Newsletter
    • Support Us
    • Contact
    • Tech & Lifestyle
    • Digital Nomadism
  • Services
    • Tech Services
    • WordPress Maintenance Package
No Result
View All Result
WebDevStory
No Result
View All Result
Home Web Development

Building a Blogging Site with React and PHP: A Step-by-Step Guide

Learn How to Create Your Own Blogging Platform

Mainul Hasan by Mainul Hasan
February 10, 2024
in Web Development
Reading Time: 8 mins read
0 0
48
User interface of a blog application showing a list of posts with titles, authors, and publication dates
0
SHARES
1.8k
VIEWS

Welcome to our comprehensive tutorial on building a React PHP Blogging Site. This step-by-step guide takes you through the process of creating a fully functional blog using the powerful combination of React for the frontend and PHP for the backend.

  • CRUD Operations
  • Like/Dislike Feature

By the end of this tutorial, I hope you will have a clear understanding how to integrate a React frontend with a PHP backend, along with a functional blogging site you can continue to expand and customize. Let’s get started on this exciting project and bring our blogging site to life!

Table of Contents

    Essential Tools for Our React PHP Blogging Site Tutorial

    • React
    • PHP
    • MySQL
    • Axios
    • Bootstrap

    Environment Variables

    To handle our API endpoint configurations, we use an .env file in our React PHP Blogging Platform.

    
    	        REACT_APP_API_BASE_URL=http://localhost/Projects/blogging-stie/server/api
    	    

    Database Schema

    Our blogging site has primarily two tables to store data: blog_posts for the blog entries and post_votes for counting likes and dislikes.

    
    	        CREATE TABLE `blog_posts`
    	        (
    	            `id` INT(11) NOT NULL AUTO_INCREMENT,
    	            `title` VARCHAR(255) NOT NULL,
    	            `author` VARCHAR(255) NOT NULL,
    	            `content` TEXT NOT NULL,
    	            `publish_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    	            PRIMARY KEY (`id`)
    	        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    	        CREATE TABLE `post_votes`
    	        (
    	            `id` INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    	            `post_id` INT(11) NOT NULL,
    	            `user_ip` VARCHAR(50) NOT NULL,
    	            `vote_type` ENUM('like', 'dislike') NOT NULL,
    	            `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    	            `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    	            FOREIGN KEY (`post_id`) REFERENCES `blog_posts` (`id`)
    	            ON DELETE CASCADE
    	            ON UPDATE CASCADE
    	        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    	    

    Configuring CORS

    In today’s web application, security is crucial. To enable safe cross-origin requests, we implement CORS policies in our config.php file.

    Key Components of Our CORS Configuration

    • Allowed Origins
    • Allowed Headers
    • Handling Preflight Requests
    
    	        // Define configuration options
    	        $allowedOrigins = ['http://localhost:3000'];
    	        $allowedHeaders = ['Content-Type'];
    
    	        // Set headers for CORS
    	        $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
    	        if (in_array($origin, $allowedOrigins)) {
    	            header('Access-Control-Allow-Origin: ' . $origin);
    	        }
    
    	        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
    	            header('Access-Control-Allow-Methods: ' . implode(', ', $allowedMethods));
    	        }
    
    	        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
    	            $requestHeaders = explode(',', $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
    	            $requestHeaders = array_map('trim', $requestHeaders); // Trim whitespace from headers
    	            if (count(array_intersect($requestHeaders, $allowedHeaders)) == count($requestHeaders)) {
    	                header('Access-Control-Allow-Headers: ' . implode(', ', $allowedHeaders));
    	            }
    	        }
    	    

    Database Configuration and Connection

    To store and manage the data for our blogging platform, we use a MySQL database.

    
    	        // Database configuration
    	        $dbHost = "";
    	        $dbUsername = "";
    	        $dbPassword = "";
    	        $dbName = "";
    
    	        // Create database connection
    	        $conn = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);
    
    	        // Check connection
    	        if ($conn->connect_error) {
    	            die("Connection failed: " . $conn->connect_error);
    	        }
    	    

    Create Single Post

    Core Features of the CreatePost Component

    • State Management with Hooks
    • Form Validation
    • Asynchronous Data Handling
    • Navigation and Feedback
    
    	        import { useState } from 'react';
    	        import { useNavigate } from 'react-router-dom';
    	        import axios from 'axios';
    
    	        function CreatePost() {
    	            const [title, setTitle] = useState('');
    	            const [content, setContent] = useState('');
    	            const [author, setAuthor] = useState('');
    	            const [isLoading, setIsLoading] = useState(false);
    	            const [error, setError] = useState('');
    
    	            const navigate = useNavigate();
    
    	            // Example validation function (extend as needed)
    	            const validateForm = () => {
    	                if (!title.trim() || !content.trim() || !author.trim()) {
    	                    setError("Please fill in all fields.");
    	                    return false;
    	                }
    	                return true;
    	            };
    
    	            const handleSubmit = async (event) => {
    	                event.preventDefault();
    	                setError('');
    	                if (!validateForm()) return;
    
    	                setIsLoading(true);
    
    	                try {
    	                    const response = await axios.post(`${process.env.REACT_APP_API_BASE_URL}/create-post.php`, {
    	                        title,
    	                        content,
    	                        author
    	                    });
    	                    console.log(response.data);
    	                    navigate('/');
    	                } catch (error) {
    	                    console.error(error);
    	                    setError('Failed to create post. Please try again later.');
    	                    setIsLoading(false);
    	                }
    	            };
    
    	            return (
    	                <div className="container mt-4">
    	                    <h2>Create a New Post</h2>
    	                    {error && <div className="alert alert-danger" role="alert">error</div>}
    	                    <form onSubmit={handleSubmit}>
    	                        <div className="mb-3">
    	                            <label htmlFor="title" className="form-label">Title</label>
    	                            <input
    	                                type="text"
    	                                className="form-control"
    	                                id="title"
    	                                value={title}
    	                                onChange={(e) => setTitle(e.target.value)}
    	                                required
    	                            />
    	                        </div>
    	                        <div className="mb-3">
    	                            <label htmlFor="content" className="form-label">Content</label>
    	                            <textarea
    	                                className="form-control"
    	                                id="content"
    	                                rows="5"
    	                                value={content}
    	                                onChange={(e) => setContent(e.target.value)}
    	                                required
    	                            ></textarea>
    	                        </div>
    	                        <div className="mb-3">
    	                            <label htmlFor="author" className="form-label">Author</label>
    	                            <input
    	                                type="text"
    	                                className="form-control"
    	                                id="author"
    	                                value={author}
    	                                onChange={(e) => setAuthor(e.target.value)}
    	                                required
    	                            />
    	                        </div>
    	                        <button 
    	                            type="submit" 
    	                            className="btn btn-primary" 
    	                            disabled={isLoading}>
    	                            {
    	                                isLoading ? 
    	                                <span><span 
    	                                    className="spinner-border spinner-border-sm" 
    	                                    role="status" 
    	                                    aria-hidden="true"></span> 
    	                                Creating post...</span> : 
    	                                'Create Post'
    	                            }
    	                        </button>
    	                    </form>
    	                </div>
    	            );
    	        }
    
    	        export default CreatePost;
    	    
    
    	        header('Access-Control-Allow-Headers: Content-Type'); // Allow Content-Type header
    
    	        require_once('../config/config.php');
    	        require_once('../config/database.php');
    
    	        // Retrieve the request body as a string
    	        $request_body = file_get_contents('php://input');
    
    	        // Decode the JSON data into a PHP array
    	        $data = json_decode($request_body, true);
    
    	        // Validate input fields with basic validation
    	        if (empty($data['title']) || empty($data['content']) || empty($data['author'])) {
    	            http_response_code(400);
    	            echo json_encode(['message' => 'Error: Missing or empty required parameter']);
    	            exit();
    	        }
    
    	        // Validate input fields
    	        if (!isset($data['title']) || !isset($data['content']) || !isset($data['author'])) {
    	            http_response_code(400);
    	            die(json_encode(['message' => 'Error: Missing required parameter']));
    	        }
    
    	        // Sanitize input
    	        $title = filter_var($data['title'], FILTER_SANITIZE_STRING);
    	        $author = filter_var($data['author'], FILTER_SANITIZE_STRING);
    	        $content = filter_var($data['content'], FILTER_SANITIZE_STRING);
    
    	        // Prepare statement
    	        $stmt = $conn->prepare('INSERT INTO blog_posts (title, content, author) VALUES (?, ?, ?)');
    	        $stmt->bind_param('sss', $title, $content, $author);
    
    	        // Execute statement
    	        if ($stmt->execute()) {
    	            // Get the ID of the newly created post
    	            $id = $stmt->insert_id;
    
    	            // Return success response
    	            http_response_code(201);
    	            echo json_encode(['message' => 'Post created successfully', 'id' => $id]);
    	        } else {
    	            // Return error response with more detail if possible
    	            http_response_code(500);
    	            echo json_encode(['message' => 'Error creating post: ' . $stmt->error]);
    	        }
    
    	        // Close statement and connection
    	        $stmt->close();
    	        $conn->close();
    	    

    Display All Posts

    
    	        import { useState, useEffect } from 'react';
    	        import { Link } from 'react-router-dom';
    	        import axios from 'axios';
    
    	        function PostList() {
    	            const [posts, setPosts] = useState([]);
    	            const [isLoading, setIsLoading] = useState(true);
    	            const [error, setError] = useState('');
    	            const [currentPage, setCurrentPage] = useState(1);
    	            const [totalPosts, setTotalPosts] = useState(0);
    	            const postsPerPage = 10;
    
    	            useEffect(() => {
    	                const fetchPosts = async () => {
    	                    setIsLoading(true);
    	                    try {
    	                        const response = await axios.get(`${process.env.REACT_APP_API_BASE_URL}/posts.php?page=${currentPage}`);
    	                        setPosts(response.data.posts);
    	                        setTotalPosts(response.data.totalPosts);
    	                        setIsLoading(false);
    	                    } catch (error) {
    	                        console.error(error);
    	                        setError('Failed to load posts.');
    	                        setIsLoading(false);
    	                    }
    	                };
    
    	                fetchPosts();
    	            }, [currentPage]);
    
    	            const totalPages = Math.ceil(totalPosts / postsPerPage);
    	            const goToPreviousPage = () => setCurrentPage(currentPage - 1);
    	            const goToNextPage = () => setCurrentPage(currentPage + 1);
    
    	            return (
    	                <div className="container mt-5">
    	                    <h2 className="mb-4">All Posts</h2>
    	                    {error && <div className="alert alert-danger">{error}</div>}
    	                    <div className="row">
    	                        {isLoading ? (
    	                        <p>Loading posts...</p>
    	                        ) : posts.length ? (
    	                        posts.map(post => (
    	                        <div className="col-md-6" key=post.id>
    	                            <div className="card mb-4">
    	                                <div className="card-body">
    	                                    <h5 className="card-title">{post.title}</h5>
    	                                    <p className="card-text">By {post.author} on {new Date(post.publish_date).toLocaleDateString()}</p>
    	                                    <Link to=`/post/${post.id}` className="btn btn-primary">Read More</Link>
    	                                </div>
    	                            </div>
    	                        </div>
    	                        ))
    	                        ) : (
    	                        <p>No posts available.</p>
    	                        )}
    	                    </div>
    	                    <nav aria-label="Page navigation">
    	                        <ul className="pagination">
    	                            <li className=`page-item ${currentPage === 1 ? 'disabled' : ''}`>
    	                                <button className="page-link" onClick=goToPreviousPage>Previous</button>
    	                            </li>
    	                            {Array.from({ length: totalPages }, (_, index) => (
    	                            <li key=index className=`page-item ${index + 1 === currentPage ? 'active' : ''}`>
    	                                <button className="page-link" onClick=() => setCurrentPage(index + 1)>{index + 1}</button>
    	                            </li>
    	                            ))}
    	                            <li className=`page-item ${currentPage === totalPages ? 'disabled' : ''}`>
    	                                <button className="page-link" onClick=goToNextPage>Next</button>
    	                            </li>
    	                        </ul>
    	                    </nav>
    	                </div>
    	            );
    	        }
    
    	        export default PostList;
    	    
    
    	        // Load configuration files
    	        require_once('../config/config.php');
    	        require_once('../config/database.php');
    
    	        header('Content-Type: application/json');
    
    	        // Define configuration options
    	        $allowedMethods = ['GET'];
    	        $maxPostsPerPage = 10;
    
    	        // Implement basic pagination
    	        $page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
    	        $offset = ($page - 1) * $maxPostsPerPage;
    
    	        // Query to count total posts
    	        $countQuery = "SELECT COUNT(*) AS totalPosts FROM blog_posts";
    	        $countResult = mysqli_query($conn, $countQuery);
    	        $countRow = mysqli_fetch_assoc($countResult);
    	        $totalPosts = $countRow['totalPosts'];
    
    	        // Check if total posts query is successful
    	        if (!$countResult) {
    	            http_response_code(500); // Internal Server Error
    	            echo json_encode([
    	                'message' => 'Error querying database for total posts count: ' . mysqli_error($conn)
    	            ]);
    	            mysqli_close($conn);
    	            exit();
    	        }
    
    	        // Query to get all blog posts with pagination and ordering
    	        $query = "SELECT * FROM blog_posts ORDER BY publish_date DESC LIMIT $offset, $maxPostsPerPage";
    	        $result = mysqli_query($conn, $query);
    
    	        // Check if paginated posts query is successful
    	        if (!$result) {
    	            http_response_code(500); // Internal Server Error
    	            echo json_encode([
    	                'message' => 'Error querying database for paginated posts: ' . mysqli_error($conn)
    	            ]);
    	            mysqli_close($conn);
    	            exit();
    	        }
    
    	        // Convert query result into an associative array
    	        $posts = mysqli_fetch_all($result, MYSQLI_ASSOC);
    
    	        // Check if there are posts
    	        if (empty($posts)) {
    	            // No posts found, you might want to handle this case differently
    	            http_response_code(404); // Not Found
    	            echo json_encode([
    	                'message' => 'No posts found',
    	                'totalPosts' => $totalPosts
    	            ]);
    	        } else {
    	            // Return JSON response including totalPosts
    	            echo json_encode([
    	                'posts' => $posts,
    	                'totalPosts' => $totalPosts
    	            ]);
    	        }
    
    	        // Close database connection
    	        mysqli_close($conn);
    	    

    Single Post Display & Like/Dislike Feature

    
    		        import React, { useState, useEffect } from "react";
    		        import { useParams } from "react-router-dom";
    		        import axios from "axios";
    
    		        const Post = () => {
    		            const { id } = useParams();
    		            const [post, setPost] = useState(null);
    		            const [likeCount, setLikeCount] = useState(0);
    		            const [dislikeCount, setDislikeCount] = useState(0);
    		            const [ipAddress, setIpAddress] = useState("");
    
    		            const fetchPost = async () => {
    		                try {
    		                    const response = await axios.get(`${process.env.REACT_APP_API_BASE_URL}/post.php/${id}`);
    		                    const post = response.data.data;
    		                    setPost(post);
    		                    setLikeCount(post.likes);
    		                    setDislikeCount(post.dislikes);
    		                } catch (error) {
    		                    console.log(error);
    		                }
    		            };
    
    		            const fetchIpAddress = async () => {
    		                try {
    		                    const response = await axios.get("https://api.ipify.org/?format=json");
    		                    setIpAddress(response.data.ip);
    		                } catch (error) {
    		                    console.log(error);
    		                }
    		            };
    
    		            const handleLike = async () => {
    		                try {
    		                    const response = await axios.post(`${process.env.REACT_APP_API_BASE_URL}/post.php/${id}/like/${ipAddress}`);
    		                    setLikeCount(response.data.data);
    		                } catch (error) {
    		                    console.log(error);
    		                }
    		            };
    
    		            const handleDislike = async () => {
    		                try {
    		                    const response = await axios.post(`${process.env.REACT_APP_API_BASE_URL}/post.php/${id}/dislike/${ipAddress}`);
    		                    setDislikeCount(response.data.data);
    		                } catch (error) {
    		                    console.log(error);
    		                }
    		            };
    
    		            useEffect(() => {
    		                fetchPost();
    		                fetchIpAddress();
    		            }, []);
    
    		            if (!post) return <div>Loading...</div>;
    
    		            return (
    		                <div className="container my-4">
    		                    <h1 className="mb-4">{post.title}</h1>
    		                    <p>{post.content}</p>
    		                    <hr />
    		                    <div className="d-flex justify-content-between">
    		                        <div>
    		                            <button className="btn btn-outline-primary me-2" onClick={handleLike}>
    		                                Like <span className="badge bg-primary">{likeCount}</span>
    		                            </button>
    		                            <button className="btn btn-outline-danger" onClick={handleDislike}>
    		                                Dislike <span className="badge bg-danger">{dislikeCount}</span>
    		                            </button>
    		                        </div>
    		                        <div>
    		                            <small className="text-muted">
    		                                Posted by {post.author} on {post.date}
    		                            </small>
    		                        </div>
    		                    </div>
    		                </div>
    		            );
    		        };
    
    		        export default Post;
    		    
    
    		        // Load configuration files
    		        require_once('../config/config.php');
    		        require_once('../config/database.php');
    
    		        if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    		            $requestUri = $_SERVER['REQUEST_URI'];
    		            $parts = explode('/', $requestUri);
    		            $id = end($parts);
    
    		            $query = "SELECT bp.*, 
    		            (SELECT COUNT(*) FROM post_votes WHERE post_id = bp.id AND vote_type = 'like') AS numLikes,
    		            (SELECT COUNT(*) FROM post_votes WHERE post_id = bp.id AND vote_type = 'dislike') AS numDislikes
    		            FROM blog_posts AS bp WHERE bp.id = ?";
    
    		            $stmt = $conn->prepare($query);
    		            $stmt->bind_param('i', $id);
    		            $stmt->execute();
    		            $result = $stmt->get_result();
    
    		            if ($result->num_rows === 1) {
    		                $post = $result->fetch_assoc();
    
    		                $response = [
    		                    'status' => 'success',
    		                    'data' => [
    		                        'id' => $post['id'],
    		                        'title' => $post['title'],
    		                        'content' => $post['content'],
    		                        'author' => $post['author'],
    		                        'date' => date("l jS \\of F Y", strtotime($post['publish_date'])),
    		                        'likes' => $post['numLikes'],
    		                        'dislikes' => $post['numDislikes']
    		                    ]
    		                ];
    
    		                header('Content-Type: application/json');
    		                echo json_encode($response);
    		            } else {
    		                $response = [
    		                    'status' => 'error',
    		                    'message' => 'Post not found'
    		                ];
    
    		                header('Content-Type: application/json');
    		                echo json_encode($response);
    		            }
    
    		            $stmt->close();
    		            $conn->close();
    		        }
    
    		        // Additional helper functions for voting logic
    		        function checkVote($conn, $postId, $ipAddress, $voteType) {
    		            $query = "SELECT * FROM post_votes WHERE post_id=? AND user_ip=? AND vote_type=?";
    		            $stmt = $conn->prepare($query);
    		            $stmt->bind_param("iss", $postId, $ipAddress, $voteType);
    		            $stmt->execute();
    		            $result = $stmt->get_result();
    		            return $result->num_rows() > 0;
    		        }
    
    		        // Functions for inserting and removing votes
    		        function insertVote($conn, $postId, $ipAddress, $voteType) {
    		            if (!checkVote($conn, $postId, $ipAddress, $voteType)) {
    		                $query = "INSERT INTO post_votes (post_id, user_ip, vote_type) VALUES (?, ?, ?)";
    		                $stmt = $conn->prepare($query);
    		                $stmt->bind_param("iss", $postId, $ipAddress, $voteType);
    		                $stmt->execute();
    		                return $stmt->affected_rows() > 0;
    		            }
    		            return false;
    		        }
    		    

    Navbar

    
    	        import React from 'react';
    	        import { Link } from 'react-router-dom';
    
    	        const Navbar = () => {
    	            return (
    	                <nav className="navbar navbar-expand-lg navbar-light bg-light">
    	                    <div className="container-fluid">
    	                        <Link className="navbar-brand" to="/">
    	                            Blog Application
    	                        </Link>
    	                        <button
    	                            className="navbar-toggler"
    	                            type="button"
    	                            data-bs-toggle="collapse"
    	                            data-bs-target="#navbarNav"
    	                            aria-controls="navbarNav"
    	                            aria-expanded="false"
    	                            aria-label="Toggle navigation"
    	                        >
    	                            <span className="navbar-toggler-icon"></span>
    	                        </button>
    	                        <div className="collapse navbar-collapse" id="navbarNav">
    	                            <ul className="navbar-nav">
    	                                <li className="nav-item">
    	                                    <Link className="nav-link" to="/">
    	                                        Home
    	                                    </Link>
    	                                </li>
    	                                <li className="nav-item">
    	                                    <Link className="nav-link" to="/create-post">
    	                                        Create Post
    	                                    </Link>
    	                                </li>
    	                            </ul>
    	                        </div>
    	                    </div>
    	                </nav>
    	            );
    	        };
    
    	        export default Navbar;
    	    

    App.js and Route

    
    	        import React from 'react';
    	        import { BrowserRouter, Routes, Route } from 'react-router-dom';
    	        import './App.css';
    	        import Navbar from './components/Navbar';
    	        import CreatePost from './components/CreatePost';
    	        import Post from './components/Post';
    	        import PostList from './components/PostList';
    
    	        function App() {
    	            return (
    	                <div className="App">
    	                    <BrowserRouter>
    	                        <Navbar />
    	                        <Routes>
    	                            <Route path="/" element={<PostList />} />
    	                            <Route path="/create-post" element={<CreatePost />} />
    	                            <Route path="/post/:id" element={<Post />} />
    	                        </Routes>
    	                    </BrowserRouter>
    	                </div>
    	            );
    	        }
    
    	        export default App;
    	    

    Conclusion: Mastering the Art of Blog Development with React and PHP

    Congratulations on completing this comprehensive guide to building a blogging site with React and PHP! Now you’ve a good idea to integrate a React frontend with a PHP backend, implementing essential features like CRUD operations and a like/dislike system.

    This project not only enhances your development skills, but also serves as a solid foundation for future web applications.

    Thank you for choosing this tutorial to advance your web development journey on how to create a blogging site using React and PHP.

    Get the full React and PHP tutorial for a blogging platform on Code on GitHub.

    🚀 Before You Go:

    • 👏 Found this guide helpful? Give it a like!
    • 💬 Got thoughts? Share your insights!
    • 📤 Know someone who needs this? Share the post!
    • 🌟 Your support keeps us going!

    💻 Level up with the latest tech trends, tutorials, and tips - Straight to your inbox – no fluff, just value!

    Join the Community →
    Tags: Blogging SitePHPReactweb development
    ADVERTISEMENT
    Previous Post

    Security Debt in Software Engineering Comprehensive Overview

    Next Post

    20 Things You Should Consider When You Grow as a Developer

    Related Posts

    Open notebook with questions for JavaScript interview preparation
    Front-end Development

    150 JavaScript Interview Questions & Answers – Nail Your Tech Interview

    December 29, 2024
    Stylized JavaScript JS logo alongside Advanced text, representing in-depth JavaScript programming concepts
    JavaScript

    25 Advanced JavaScript Features You Should Know

    December 28, 2024
    Collaborative web design and hosting integration with creative and technical teamwork
    Web Development

    Best Practices for Web Design and UX Hosting Integration

    December 21, 2024
    Cloud technology representing OneDrive integration with React and Microsoft Graph API
    Web Development

    OneDrive Integration with React: Step-by-Step Guide

    September 21, 2024
    Hands typing on a laptop with API development icons, showcasing technology and integration
    Web Development

    Integrate Dropbox API with React: A Comprehensive Guide

    September 6, 2024
    Best React Frameworks concept with geometric shapes representing modular design
    Web Development

    Best React Frameworks: Which One Should You Choose and When?

    September 5, 2024
    Next Post
    Open notebook with inspirational quote: Big Journeys Begin With Small Steps, symbolizing the start of a developer's journey.

    20 Things You Should Consider When You Grow as a Developer

    Comments 48

    1. kajol singh says:
      1 year ago

      where is the demo link could you plz provide a valid demo link

      Reply
      • Mainul Hasan says:
        1 year ago

        Thanks for reading the post. Demo link is https://github.com/mainulspace/Projects/tree/master/blogging-stie

        Reply
    2. Bokep Bispak says:
      7 months ago

      Hey very nice blog!

      Reply
    3. Sharyn says:
      7 months ago

      Howdy just wanted to give you a quick heads up. The text in your content seem to be running off the screen in Opera.

      I’m not sure if this is a format issue or something to do with internet browser compatibility but I figured I’d post to let you know.

      The style and design look great though! Hope you get the problem fixed soon. Kudos

      Reply
      • Mainul Hasan says:
        6 months ago

        Hi there! Thank you so much for taking the time to point this out—I appreciate it. I’ll look into the issue with the text running off the screen in Opera and see if it’s a formatting or browser compatibility issue.

        Kudos to you for being so helpful as well!

        Reply
    4. Tamara Kavanagh says:
      7 months ago

      Hi there, You’ve done a fantastic job. I’ll definitely digg it and personally suggest to my friends. I’m confident they will be benefited from this website.

      Reply
    5. Dessie Rickard says:
      7 months ago

      It’s an remarkable post in favor of all the web users; they will take benefit from it I am sure.

      Reply
    6. Ivory Jain says:
      7 months ago

      Fine way of describing, and good piece of writing to obtain data concerning my presentation focus, which i am going to present in academy.

      Reply
    7. Regan Vigil says:
      7 months ago

      Hi! I just wanted to ask if you ever have any issues with hackers? My last blog (wordpress) was hacked and I ended up losing a few months of hard work due to no back up. Do you have any methods to protect against hackers?

      Reply
    8. Gertie Akers says:
      7 months ago

      Hello everyone, it’s my first go to see at this web page, and article is in fact fruitful in support of me, keep up posting these types of posts.

      Reply
    9. Claudio Robles says:
      7 months ago

      Heya i am for the first time here. I found this board and I find It truly useful & it helped me out much. I hope to give something back and aid others like you aided me.

      Reply
    10. Akhuwat says:
      7 months ago

      It’s very effortless to find out any matter on web as compared to books, as I found this post at this site.

      Reply
    11. Refugia Hagai says:
      7 months ago

      Spot on with this write-up, I really believe this website needs far more attention. I’ll probably be back again to read through more, thanks for the information!

      Reply
    12. Jeffry says:
      7 months ago

      This post is truly a fastidious one it helps new the web visitors, who are wishing in favor of blogging.

      Reply
    13. Anal says:
      7 months ago

      Thanks for a marvelous posting! I really enjoyed reading it, you might be a great author. I will remember to bookmark your blog and will come back down the road.

      I want to encourage yourself to continue your great writing, have a nice evening!

      Reply
    14. Janette Donnelly says:
      7 months ago

      Interesting blog! Is your theme custom made or did you download it from somewhere?

      A design like yours with a few simple adjustements would really make my blog jump out. Please let me know where you got your design. Kudos

      Reply
      • Mainul Hasan says:
        6 months ago

        Thank you so much for your kind words! I’m using jNews, a versatile and feature-rich theme that I’ve customized to suit my blog’s needs. It’s a premium theme with many options for layout, styling, and functionality, making it easy to tailor to your preferences.

        If you’re interested, you can check out the jNews theme—it might also be an excellent fit for your blog. Best of luck with your blog!

        Reply
    15. Butland says:
      7 months ago

      I have been reading out some of your posts and it’s nice stuff. I will make sure to bookmark your blog.

      Reply
    16. Bokep Bispak says:
      7 months ago

      It’s great that you are getting thoughts from this piece of writing as well as from our discussion made at this place.

      Reply
    17. Renaldo Bevan says:
      7 months ago

      This is my first time visit at here and i am in fact pleassant to read all at one place.

      Reply
    18. Erlinda says:
      7 months ago

      It’s an awesome post in support of all the web visitors; they will get benefit from it I am sure.

      Reply
    19. Jacob says:
      7 months ago

      Good post. I learn something totally new and challenging on sites I stumbleupon on a daily basis.

      It will always be useful to read through articles from other authors and use a little something from other sites.

      Reply
    20. Gudrun says:
      7 months ago

      We are a group of volunteers and starting a new scheme in our community. Your site offered us with valuable information to work on. You’ve done an impressive job and our whole community will be thankful to you.

      Reply
    21. Teena says:
      7 months ago

      Aw, this was an incredibly nice post. Finding the time and actual effort to generate a superb article… but what can I say… I procrastinate a lot and never manage to get anything done.

      Reply
    22. Rose Mary says:
      7 months ago

      Greetings! Quick question that’s totally off topic. Do you know how to make your site mobile friendly?

      My web site looks weird when browsing from my apple iphone. I’m trying to find a theme or plugin that might be able to fix this problem. If you have any recommendations, please share. Thank you!

      Reply
      • Mainul Hasan says:
        6 months ago

        Hi there! Thanks for your comment! Making a website mobile-friendly is essential these days, and there are a few steps you can take to fix this issue. If you’re using WordPress, look for a responsive theme that works well on mobile devices.

        Reply
    23. Carlo says:
      7 months ago

      Greetings from Colorado! I’m bored to death at work so I decided to browse your website on my iphone during lunch break. I really like the info you provide here and can’t wait to take a look when I get home.

      I’m amazed at how fast your blog loaded on my cell phone .. I’m not even using WIFI, just 3G .. Anyways, awesome blog!

      Reply
    24. Humber Toarndell says:
      7 months ago

      Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this.

      Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

      Reply
      • Mainul Hasan says:
        6 months ago

        Hi there! As for widgets that automatically tweet your latest updates, check out tools like Jetpack for WordPress, which offers a “Publicize” feature to auto-share posts to Twitter and other social platforms.

        If you’re looking for a way to display your Twitter feed on your blog, plugins like Twitter Feed or Smash Balloon Social Post Feed are great options—they’re customizable and easy to integrate.

        Reply
    25. Dakota says:
      7 months ago

      Wow! In the end I got a weblog from where I know how to in fact obtain valuable data concerning my study and knowledge.

      Reply
    26. Zita Winkel says:
      7 months ago

      Do you mind if I quote a couple of your articles as long as I provide credit and sources back to your webpage? My blog site is in the exact same niche as yours and my users would really benefit from some of the information you present here.

      Please let me know if this ok with you. Cheers!

      Reply
      • Mainul Hasan says:
        6 months ago

        Hi there! Thank you for reaching out and for considering my content for your blog. I’d be happy for you to quote my articles, but please give me proper credit and link back to the source. Cheers!

        Reply
    27. Bette Patch says:
      7 months ago

      Nice post. I was checking continuously this blog and I am impressed! Extremely useful information particularly the last part 🙂 I care for such info much. I was seeking this particular info for a long time. Thank you and best of luck.

      Reply
    28. Julian Netanner says:
      7 months ago

      I was excited to uncover this website. I wanted to thank you for ones time for this particularly fantastic read!! I definitely savored every part of it and i also have you bookmarked to check out new stuff in your website.

      Reply
      • Mainul Hasan says:
        6 months ago

        Thank you so much for your kind words! I’m thrilled you enjoyed the article and found it valuable.

        Reply
    29. Pamela Danielson says:
      6 months ago

      Hi! I know this is kinda off topic but I was wondering if you knew where I could locate a captcha plugin for my comment form? I’m using the same blog platform as yours and I’m having trouble finding one? Thanks a lot!

      Reply
      • Mainul Hasan says:
        6 months ago

        Hi there! Thanks for your comment! To add a captcha to your comment form, I recommend using Google reCAPTCHA v3, which integrates seamlessly with most platforms, including WordPress.

        Plugins like Advanced noCaptcha & Invisible Captcha or Simple Google reCAPTCHA are great options for WordPress users.

        Let me know if you’d like more details or help to set it up. Good luck, and thanks for stopping by!

        Reply
    30. Arnold Fedler says:
      6 months ago

      I constantly spent my half an hour to read this blog’s content all the time along with a mug of coffee.

      Reply
      • Mainul Hasan says:
        6 months ago

        Thank you so much for your lovely comment! It’s wonderful to hear that reading the blog has become a part of your routine—nothing pairs better with good content than a mug of coffee! 😊

        Reply
    31. Ambrose Minahan says:
      6 months ago

      It is truly a great and useful piece of information. I am happy that you simply shared this helpful info with us. Please keep us up to date like this. Thanks for sharing.

      Reply
      • Mainul Hasan says:
        6 months ago

        Thank you so much for your kind feedback! I’m thrilled to hear that you found the information helpful.

        Reply
    32. Alonzo Freud says:
      6 months ago

      Excellent article. I will be facing many of these issues as well..

      Reply
      • Mainul Hasan says:
        6 months ago

        Thank you so much for your kind words! I’m glad you found the article helpful. These challenges can feel overwhelming, but tackling them step by step always helps.

        If you have questions or guidance on any issues, ask—I’d be happy to assist. Wishing you the best on your blogging journey!

        Reply
    33. Slot says:
      6 months ago

      It’s perfect time to make a few plans for the long run and it is time to be happy. I’ve read this publish and if I may just I desire to suggest you some interesting issues or suggestions. Maybe you could write subsequent articles regarding this article. I want to read even more things about it!

      Reply
      • Mainul Hasan says:
        6 months ago

        Thank you so much for your thoughtful comment! I’m glad you enjoyed the article. I’d love to hear your suggestions — share the topics or issues you’d like me to cover. Your feedback helps shape future content, so it’s always welcome!

        I’m brainstorming follow-up articles to dive deeper into related aspects, like advanced integration techniques or performance optimization tips. Stay tuned, and I hope to bring you even more valuable insights soon. Thanks again for reading and sharing your thoughts!

        Reply
    34. Slot Gacor says:
      6 months ago

      Hey there! Do you know if they make any plugins to help with SEO? I’m trying to get my blog to rank for some targeted keywords but I’m not seeing very good gains. If you know of any please share. Many thanks!

      Reply
      • Mainul Hasan says:
        6 months ago

        Hi there! Thanks for your comment. Yes, there are quite a few great plugins available that can help with SEO for your blog. If you’re using WordPress, popular plugins like Yoast SEO or Rank Math can assist you in optimizing your content for targeted keywords. They offer features like keyword analysis, XML sitemaps, meta descriptions, and readability improvements.

        For other platforms or custom-built sites, you might explore tools like Ahrefs Webmaster Tools or Google Search Console to identify keyword opportunities and track your progress.

        Additionally, consider creating high-quality, engaging content and building backlinks from reputable sites to improve your ranking further. I can also share some tips or tools specific to your setup if you’d like. Let me know, and happy blogging!

        Reply
    35. Doug Jasper says:
      5 months ago

      Hi,
      This an excellent example!
      I do have a couple of issues happening though.
      1. The pagination buttons appear correctly but when I click on one to navigate to a new page it generates a Browser error.
      2. Like and Dislike buttons appear but when clicked on do not make an entry in the database and the number does not update.
      Has anyone else had this problem and is there updated code to resolve this? I have copied and pasted your code from GitHub and I still have the same issues.
      Thanks,
      Doug Jasper
      PS. I am using XAMPP on Mac for the backend.

      Reply

    Leave a Reply Cancel reply

    Your email address will not be published. Required fields are marked *

    Save 20% with Code mainul76 on Pictory AI - Limited-Time Discount Save 20% with Code mainul76 on Pictory AI - Limited-Time Discount Save 20% with Code mainul76 on Pictory AI - Limited-Time Discount

    You might also like

    User interface of a blog application showing a list of posts with titles, authors, and publication dates

    Building a Blogging Site with React and PHP: A Step-by-Step Guide

    February 10, 2024
    JavaScript ES6 features for React development

    Essential ES6 Features for Mastering React

    July 26, 2023
    Word cloud featuring modern software development key terms.

    Modern Software Development Practices, Terms and Trends

    January 23, 2024
    Globe with HTTP Protocol - Understanding JavaScript HTTP Request Libraries

    HTTP Requests in JavaScript: Popular Libraries for Web Developers

    March 5, 2024
    Stylized JavaScript JS logo alongside Advanced text, representing in-depth JavaScript programming concepts

    25 Advanced JavaScript Features You Should Know

    December 28, 2024
    Hands typing on a laptop with API development icons, showcasing technology and integration

    Integrate Dropbox API with React: A Comprehensive Guide

    September 6, 2024
    Fiverr affiliates promotional banner - Get paid to share Fiverr with your network. Start Today. Fiverr affiliates promotional banner - Get paid to share Fiverr with your network. Start Today. Fiverr affiliates promotional banner - Get paid to share Fiverr with your network. Start Today.
    Coursera Plus promotional banner - Save 40% on one year of Coursera Plus. Subscribe now. Coursera Plus promotional banner - Save 40% on one year of Coursera Plus. Subscribe now. Coursera Plus promotional banner - Save 40% on one year of Coursera Plus. Subscribe now.
    Namecheap .COM domain promotional banner - Get a .COM for just $5.98. Secure a mighty domain for a mini price. Claim now. Namecheap .COM domain promotional banner - Get a .COM for just $5.98. Secure a mighty domain for a mini price. Claim now. Namecheap .COM domain promotional banner - Get a .COM for just $5.98. Secure a mighty domain for a mini price. Claim now.
    WebDevStory logo

    Empowering your business with tailored web solutions, expert SEO, and cloud integration to fuel growth and innovation.

    Contact Us

    Hans Ross Gate 3, 0172, Oslo, Norway

    +47-9666-1070

    info@webdevstory.com

    Stay Connected

    • Contact
    • Privacy Policy

    © webdevstory.com

    Welcome Back!

    Login to your account below

    Forgotten Password?

    Retrieve your password

    Please enter your username or email address to reset your password.

    Log In
    No Result
    View All Result
    • Tech
      • Software Testing
      • IT and Management
      • Software Engineering
      • Technology
    • Web
      • JavaScript
      • Web Development
      • Front-end Development
      • React
      • Database Technologies
    • AI
      • AI and Machine Learning
      • AI in Education
      • AI Learning
      • AI Prompts
    • Programming
      • Coding
      • Design Patterns
    • Misc
      • Digital Transformation
      • SEO
      • Technology and Business
      • Technology and Innovation
      • Developer Roadmaps
      • Digital Marketing
    • More
      • Newsletter
      • Support Us
      • Contact
      • Tech & Lifestyle
      • Digital Nomadism
    • Services
      • Tech Services
      • WordPress Maintenance Package

    © webdevstory.com