Table of Contents
Next.js is a popular React framework that enables server-side rendering and static site generation. In this article, we’ll walk through creating a basic CRUD (Create, Read, Update, Delete) application using Next.js and an external API. For simplicity, we’ll use the JSONPlaceholder API as our external data source.
Steps for CRUD in Next.js with axios
Step 1: Setting Up the Project
First, let’s set up a new Next.js project.
Initialize a New Project
npx create-next-app@latest nextjs-crud cd nextjs-crud
Install Axios
We’ll use Axios for making HTTP requests.
npm install axios
Step 2: Creating API Service
Create a service to handle API requests. Create a file named api.js inside a new services directory.
// services/api.js import axios from 'axios'; const API_URL = 'https://jsonplaceholder.typicode.com/posts'; export const getPosts = async () => { const response = await axios.get(API_URL); return response.data; }; export const getPost = async (id) => { const response = await axios.get(`${API_URL}/${id}`); return response.data; }; export const createPost = async (post) => { const response = await axios.post(API_URL, post); return response.data; }; export const updatePost = async (id, post) => { const response = await axios.put(`${API_URL}/${id}`, post); return response.data; }; export const deletePost = async (id) => { await axios.delete(`${API_URL}/${id}`); };
Step 3: Creating Pages and Components
Displaying All Posts
Create a page to list all posts.
// pages/index.js import { useEffect, useState } from 'react'; import { getPosts } from '../services/api'; import Link from 'next/link'; const HomePage = () => { const [posts, setPosts] = useState([]); useEffect(() => { const fetchPosts = async () => { const data = await getPosts(); setPosts(data); }; fetchPosts(); }, []); return ( <div> <h1>Posts</h1> <Link href="/create"> <a>Create New Post</a> </Link> <ul> {posts.map((post) => ( <li key={post.id}> <Link href={`/post/${post.id}`}> <a>{post.title}</a> </Link> </li> ))} </ul> </div> ); }; export default HomePage;
Displaying a Single Post
Create a page to display a single post.
// pages/post/[id].js import { useRouter } from 'next/router'; import { getPost, deletePost } from '../../services/api'; import { useState, useEffect } from 'react'; import Link from 'next/link'; const PostPage = () => { const router = useRouter(); const { id } = router.query; const [post, setPost] = useState(null); useEffect(() => { if (id) { const fetchPost = async () => { const data = await getPost(id); setPost(data); }; fetchPost(); } }, [id]); const handleDelete = async () => { await deletePost(id); router.push('/'); }; if (!post) return <div>Loading...</div>; return ( <div> <h1>{post.title}</h1> <p>{post.body}</p> <Link href={`/edit/${id}`}> <a>Edit</a> </Link> <button onClick={handleDelete}>Delete</button> <Link href="/"> <a>Back to Posts</a> </Link> </div> ); }; export default PostPage;
Creating a New Post
Create a page for adding a new post.
// pages/create.js import { useState } from 'react'; import { createPost } from '../services/api'; import { useRouter } from 'next/router'; const CreatePostPage = () => { const [title, setTitle] = useState(''); const [body, setBody] = useState(''); const router = useRouter(); const handleSubmit = async (e) => { e.preventDefault(); await createPost({ title, body }); router.push('/'); }; return ( <div> <h1>Create New Post</h1> <form onSubmit={handleSubmit}> <div> <label>Title</label> <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} required /> </div> <div> <label>Body</label> <textarea value={body} onChange={(e) => setBody(e.target.value)} required ></textarea> </div> <button type="submit">Create</button> </form> </div> ); }; export default CreatePostPage;
Editing a Post
Create a page for editing an existing post.
// pages/edit/[id].js import { useRouter } from 'next/router'; import { useState, useEffect } from 'react'; import { getPost, updatePost } from '../../services/api'; const EditPostPage = () => { const router = useRouter(); const { id } = router.query; const [title, setTitle] = useState(''); const [body, setBody] = useState(''); useEffect(() => { if (id) { const fetchPost = async () => { const data = await getPost(id); setTitle(data.title); setBody(data.body); }; fetchPost(); } }, [id]); const handleSubmit = async (e) => { e.preventDefault(); await updatePost(id, { title, body }); router.push(`/post/${id}`); }; return ( <div> <h1>Edit Post</h1> <form onSubmit={handleSubmit}> <div> <label>Title</label> <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} required /> </div> <div> <label>Body</label> <textarea value={body} onChange={(e) => setBody(e.target.value)} required ></textarea> </div> <button type="submit">Update</button> </form> </div> ); }; export default EditPostPage;
Step 4: Running the Application
Start the Next.js development server.
npm run dev
Open your browser and navigate to http://localhost:3000 to see your CRUD application in action.
Conclusion
In this article, we’ve built a simple CRUD application using Next.js and an external API. This example can be expanded and customized to fit more complex requirements, but it serves as a solid foundation for understanding how to integrate Next.js with external APIs for full-stack development.
For more updates on programming trends and tutorials, visit blogsea.net regularly.
Building a CRUD Application with Next.js – FAQs
By running npx create-next-app@latest nextjs-crud in your terminal.
Next.js is a React framework for server-side rendering and static site generation.
The JSONPlaceholder API is used as an external data source.
Axios is used to make HTTP requests to the external API.
npm run dev