Meistern Sie Next.js 15 mit App Router, Server Components und Server Actions. Lernen Sie Best Practices für moderne Webentwicklung mit React und TypeScript auf Deutsch.
# Next.js 15 Vollständige Entwicklungsanleitung
Erstellen Sie moderne, leistungsstarke Webanwendungen mit Next.js 15 und nutzen Sie die neuesten Funktionen wie App Router und Server Components.
## Projekteinrichtung
### Neues Projekt erstellen
```bash
npx create-next-app@latest mein-projekt --typescript --tailwind --app
cd mein-projekt
npm run dev
```
### Empfohlene Verzeichnisstruktur
```
mein-projekt/
├── src/
│ ├── app/ # App Router (Routen und Seiten)
│ │ ├── layout.tsx # Hauptlayout
│ │ ├── page.tsx # Startseite
│ │ ├── loading.tsx # Ladezustand
│ │ └── error.tsx # Fehlerbehandlung
│ ├── components/ # Wiederverwendbare Komponenten
│ │ ├── ui/ # UI-Komponenten
│ │ └── forms/ # Formularkomponenten
│ ├── lib/ # Hilfsfunktionen
│ └── types/ # TypeScript-Definitionen
└── next.config.ts # Next.js-Konfiguration
```
## Server Components (Server-Komponenten)
Server Components werden vollständig auf dem Server gerendert und reduzieren das an den Client gesendete JavaScript.
### Beispiel einer Server Component
```typescript
// app/produkte/page.tsx
import { holeProdukte } from "@/lib/api";
// Diese Komponente wird vollständig auf dem Server gerendert
export default async function ProduktSeite() {
// Daten direkt ohne useEffect abrufen
const produkte = await holeProdukte();
return (
<main className="container mx-auto py-8">
<h1 className="text-3xl font-bold mb-6">Unsere Produkte</h1>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{produkte.map((produkt) => (
<article key={produkt.id} className="border rounded-lg p-4">
<h2 className="text-xl font-semibold">{produkt.name}</h2>
<p className="text-gray-600">{produkt.beschreibung}</p>
<span className="text-lg font-bold text-blue-600">
€{produkt.preis}
</span>
</article>
))}
</div>
</main>
);
}
```
## Server Actions (Server-Aktionen)
```typescript
// app/actions/kontakt.ts
"use server";
import { z } from "zod";
import { revalidatePath } from "next/cache";
const kontaktSchema = z.object({
name: z.string().min(2, "Name muss mindestens 2 Zeichen haben"),
email: z.string().email("Ungültige E-Mail-Adresse"),
nachricht: z.string().min(10, "Nachricht muss mindestens 10 Zeichen haben"),
});
export async function sendeKontakt(formData: FormData) {
const daten = {
name: formData.get("name") as string,
email: formData.get("email") as string,
nachricht: formData.get("nachricht") as string,
};
const ergebnis = kontaktSchema.safeParse(daten);
if (!ergebnis.success) {
return {
erfolg: false,
fehler: ergebnis.error.flatten().fieldErrors,
};
}
await speichereNachricht(ergebnis.data);
revalidatePath("/kontakt");
return { erfolg: true, nachricht: "Nachricht erfolgreich gesendet" };
}
```
### Formular mit Server Action
```typescript
// components/KontaktFormular.tsx
"use client";
import { useFormState, useFormStatus } from "react-dom";
import { sendeKontakt } from "@/app/actions/kontakt";
function AbsendenButton() {
const { pending } = useFormStatus();
return (
<button
type="submit"
disabled={pending}
className="bg-blue-600 text-white px-6 py-2 rounded-lg disabled:opacity-50"
>
{pending ? "Wird gesendet..." : "Nachricht senden"}
</button>
);
}
export function KontaktFormular() {
const [zustand, aktion] = useFormState(sendeKontakt, null);
return (
<form action={aktion} className="space-y-4 max-w-md">
<div>
<label htmlFor="name" className="block text-sm font-medium">
Name
</label>
<input
type="text"
id="name"
name="name"
required
className="mt-1 block w-full rounded-md border px-3 py-2"
/>
{zustand?.fehler?.name && (
<p className="text-red-500 text-sm">{zustand.fehler.name}</p>
)}
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium">
E-Mail-Adresse
</label>
<input
type="email"
id="email"
name="email"
required
className="mt-1 block w-full rounded-md border px-3 py-2"
/>
</div>
<div>
<label htmlFor="nachricht" className="block text-sm font-medium">
Ihre Nachricht
</label>
<textarea
id="nachricht"
name="nachricht"
rows={4}
required
className="mt-1 block w-full rounded-md border px-3 py-2"
/>
</div>
<AbsendenButton />
{zustand?.erfolg && (
<p className="text-green-600">{zustand.nachricht}</p>
)}
</form>
);
}
```
## Datenabruf und Caching
```typescript
// lib/api.ts
export async function holeProdukte() {
const res = await fetch("https://api.example.com/produkte", {
next: { revalidate: 3600 }, // Cache für 1 Stunde
});
if (!res.ok) {
throw new Error("Produkte konnten nicht geladen werden");
}
return res.json();
}
// Statische Generierung mit dynamischen Parametern
export async function generateStaticParams() {
const produkte = await holeProdukte();
return produkte.map((produkt) => ({
slug: produkt.slug,
}));
}
```
Diese vollständige Anleitung hilft deutschsprachigen Entwicklern, Next.js 15 zu meistern.This nextjs prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their nextjs implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For nextjs projects, consider mentioning your framework version, coding style, and any specific libraries you're using.