Final Project Build a Small Web App with Next.js
Sveip for å vise menyen
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.
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår