Final Project Build a Small Web App with Next.js
Deslize para mostrar o menu
You have learned how to build pages, handle routing, work with server and client components, fetch data, and process user input.
Now it is time to combine everything into a real application.
In this final project, you will build a small multi-page web app using Next.js. The goal is to apply all the concepts from this block and create something that feels like a real product.
Project Overview
You will build a simple Products App with the following features:
- A homepage with a list of products;
- A dynamic product page;
- Loading and error states;
- A form to add a product;
- A route handler to process form data.
This project covers the full flow of a modern Next.js application.
What You Will Build
Your app will include:
/→ list of products;/products/[id]→ product details page;/add-product→ form to submit a new product.
Step 1: Display Products
Create a homepage that fetches and displays a list of products.
export default async function Page() {
const res = await fetch("https://api.example.com/products");
const products = await res.json();
return (
<ul>
{products.map((product) => (
<li key={product.id}>
{product.name}
</li>
))}
</ul>
);
}
Step 2: Create a Dynamic Product Page
Use a dynamic route to display product details.
export default async function ProductPage({ params }) {
const res = await fetch(
`https://api.example.com/products/${params.id}`
);
const product = await res.json();
return <h1>{product.name}</h1>;
}
Step 3: Add Loading and Error States
Create:
loading.tsx
error.tsx
Use them to handle loading and error scenarios for your pages.
Step 4: Build a Form
Create a form to submit new products.
"use client";
import { useState } from "react";
export default function AddProductForm() {
const [name, setName] = useState("");
async function handleSubmit(e) {
e.preventDefault();
await fetch("/api/products", {
method: "POST",
body: JSON.stringify({ name }),
headers: {
"Content-Type": "application/json",
},
});
}
return (
<form onSubmit={handleSubmit}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button type="submit">Add Product</button>
</form>
);
}
Step 5: Create a Route Handler
Handle the submitted data:
export async function POST(request: Request) {
const data = await request.json();
return Response.json({
message: "Product added",
data,
});
}
What You Practiced
In this project, you applied:
- File-based routing;
- Dynamic routes;
- Server components and data fetching;
- Client components and forms;
- Route handlers for backend logic;
- Loading and error handling.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo