Tutorial Nextjs 15: Guía Completa Paso a Paso
Next.js 15 transforma cómo construimos apps web full-stack. Imagina renderizar en servidor por defecto y streaming nativo que hace tus sitios ultrarrápidos. En este Tutorial Nextjs 15: Guía Completa Paso a Paso, te llevo de cero a experto construyendo un dashboard real.
¿Listo para dominar el framework React más potente? Sigue conmigo.
Instalación y Primer Proyecto
Empecemos con lo básico. Abre tu terminal y crea un nuevo proyecto Next.js 15.
💡 Si estás explorando carreras en tecnología o ciencias aplicadas, no te pierdas esta guía completa sobre las diversas ramas de la ingeniería, perfecta para decidir cuál encaja con tus pasiones y habilidades.
Ejecuta este comando:
npx create-next-app@latest mi-proyecto --typescript --tailwind --eslint --app
Elige App Router cuando pregunte. ¿Por qué? Es el futuro de Next.js 15, con Server Components incluidos.
Entra al directorio:
cd mi-proyecto
npm run dev
💡 Si estás explorando el mundo de la estadística y quieres entender a fondo las distribuciones probabilísticas, échale un ojo a esta guía exhaustiva sobre tipos de distribuciones estadísticas para aplicarlas con confianza en tus análisis.
Abre http://localhost:3000. ¡Ya tienes una página lista!
¿Qué pasa si eres nuevo en React? No hay problema. Next.js 15 asume bases sólidas, pero refresca con su curso oficial si hace falta.
Estructura del Proyecto en App Router
Explora la carpeta app. Aquí está el corazón de Next.js 15.
💡 Si estás lidiando con identificadores únicos en programación o bases de datos, echa un vistazo a esta guía esencial sobre UUID para entender su rol y aplicarlos sin complicaciones en tus desarrollos.
layout.tsx: Envuelve todas las páginas.page.tsx: Tu homepage.globals.css: Estilos globales.
Crea una carpeta (dashboard) para rutas agrupadas. No genera URL extra, solo organiza.
app/
├── (dashboard)/
│ └── page.tsx
├── layout.tsx
└── page.tsx
Layouts anidados comparten UI. ¿Te preguntas cómo evitar repeticiones? Usa children prop.
Edita app/page.tsx:
💡 Si buscas potenciar tus proyectos de IA con un lenguaje versátil y potente, echa un vistazo a los beneficios clave de Python en inteligencia artificial para acelerar tu desarrollo y resultados.
export default function Home() {
return (
<main>
<h1>Bienvenido a **Next.js 15**</h1>
</main>
);
}
Guarda y ve el cambio en vivo. Hot reload funciona de maravilla.
Estilos con Tailwind y CSS Modules
Next.js 15 soporta Tailwind out-of-the-box. Instálalo si no lo hiciste.
En tailwind.config.js, configura temas personalizados.
💡 Si estás evaluando algoritmos simples para tu código, no te pierdas los pros y contras de la búsqueda secuencial para decidir cuándo aplicarla sin complicaciones innecesarias.
Prueba clases en un componente:
<div className="bg-blue-500 text-white p-4 rounded-lg">
¡Hola, **Tailwind**!
</div>
Para CSS modules, crea Home.module.css y usa styles.className.
¿Prefieres algo más? Shadcn/ui es genial para UI components reutilizables.
npx shadcn-ui@latest init
npx s
<ImageCustom url="/img/tutorial-nextjs-15-2.webp" alt="Tutorial Nextjs 15 - Detalle Adicional" width="100%" />
hadcn-ui@latest add button
Integra rápido. Tu app luce pro en minutos.
Optimización de Fuentes e Imágenes
Imágenes lentas matan conversiones. Next.js 15 tiene <Image> optimizado.
Instala:
npm install next@latest
Usa:
import Image from 'next/image';
<Image
src="/mi-imagen.jpg"
alt="Descripción"
width={500}
height={300}
priority
/>
Lazy loading automático. Para fuentes, usa next/font:
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="es">
<body className={inter.className}>{children}</body>
</html>
);
}
Sin flashes de texto no renderizado. ¿Ves la diferencia en performance?
Navegación y Rutas Dinámicas
Link de Next.js prefiere <Link> para navegación suave.
import Link from 'next/link';
<Link href="/dashboard">Ir al Dashboard</Link>
Rutas dinámicas: Crea [id]/page.tsx.
export default function Page({ params }: { params: { id: string } }) {
return <h1>ID: {params.id}</h1>;
}
Accede /mi-ruta/123. Catch-all con [...slug].
Layouts por grupo: (marketing)/layout.tsx solo para esas páginas.
¿Problemas con rutas protegidas? Espera a la sección de auth.
Fetching de Datos con Server Components
Server Components son el killer feature de Next.js 15. Fetch en servidor, sin cliente extra.
En page.tsx:
async function getData() {
const res = await fetch('https://api.example.com/data', {
cache: 'no-store' // O 'force-cache'
});
return res.json();
}
export default async function Dashboard() {
const data = await getData();
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
Static rendering por defecto. Usa dynamic para dinámico.
Para bases de datos, integra Prisma:
npm install prisma @prisma/client
npx prisma init
Configura schema.prisma con Postgres o SQLite.
Seed data:
npx prisma db seed
Fetch en Server Component:
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export default async function Page() {
const users = await prisma.user.findMany();
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
Datos frescos sin API routes. ¿Rápido, verdad?
Streaming y Estados de Carga
Apps lentas frustran. Streaming en Next.js 15 carga shells primero.
Usa loading.tsx junto a page.tsx:
// app/dashboard/loading.tsx
export default function Loading() {
return <div>Cargando dashboard...</div>;
}
En page.tsx, envuelve secciones:
import { Suspense } from 'react';
<Suspense fallback={<div>Cargando...</div>}>
<ExpensiveComponent />
</Suspense>
UX impecable. Users ven progreso real.
Paginación y Búsqueda
Escala tu lista. Para paginación:
Usa URL params: /dashboard?page=2&search=query.
En Server Component:
export default async function Page({
searchParams
}: {
searchParams: { page?: string; search?: string };
}) {
const page = Number(searchParams.page) || 1;
const search = searchParams.search || '';
// Fetch con offsets
const items = await prisma.item.findMany({
where: { name: { contains: search } },
skip: (page - 1) * 10,
take: 10
});
return (
<>
<input placeholder="Buscar..." defaultValue={search} />
<ul>{items.map(item => <li key={item.id}>{item.name}</li>)}</ul>
{/* Links de paginación */}
</>
);
}
Revalida con revalidatePath o revalidateTag.
¿Mil items? No sudes, Next.js 15 lo maneja.
Server Actions y Mutaciones
Olvídate de APIs. Server Actions mutan datos directo.
Define en actions.ts:
'use server';
import { revalidatePath } from 'next/cache';
import { prisma } from '@/lib/prisma';
export async function createItem(formData: FormData) {
const name = formData.get('name') as string;
await prisma.item.create({ data: { name } });
revalidatePath('/dashboard');
}
En form:
'use client';
import { createItem } from '@/data/actions';
export default function Form() {
return (
<form action={createItem}>
<input name="name" />
<button type="submit">Crear</button>
</form>
);
}
Seguro y simple. Zod para validación:
import { z } from 'zod';
const schema = z.object({ name: z.string().min(1) });
export async function createItem(prevState: any, formData: FormData) {
const validated = schema.safeParse({
name: formData.get('name'),
});
if (!validated.success) {
return { errors: validated.error };
}
// Create...
}
Maneja errores con useFormState.
Manejo de Errores y Not-Found
Apps perfectas no existen. Next.js 15 las hace resilient.
Crea error.tsx:
'use client';
export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
return (
<>
<h2>Algo salió mal</h2>
<button onClick={reset}>Reintentar</button>
</>
);
}
not-found.tsx para 404:
export default function NotFound() {
return <h2>Página no encontrada</h2>;
}
Global en global-error.tsx. Cubierto.
Autenticación con NextAuth
Protege rutas. Usa Auth.js (ex NextAuth).
npm install next-auth @auth/prisma-adapter
Configura auth.ts en app/api/auth/[...nextauth]/route.ts.
Provedores:
import NextAuth from 'next-auth';
import Google from 'next-auth/providers/google';
const handler = NextAuth({
providers: [Google()],
adapter: PrismaAdapter(prisma),
});
export { handler as GET, handler as POST };
Middleware para rutas protegidas:
// middleware.ts
import { auth } from 'next-auth/middleware';
export default auth((req) => {
// Redirigir si no auth
});
export const config = { matcher: ['/dashboard/:path*'] };
Sesión en Server Component:
import { getServerSession } from 'next-auth';
const session = await getServerSession();
if (!session) redirect('/login');
Fácil y seguro. ¿Olvidaste password? NextAuth lo cubre.
Metadata y SEO
Next.js 15 genera metadata dinámica.
En layout.tsx:
export const metadata = {
title: 'Mi App',
description: 'Descripción',
};
export default function Layout({ children }: { children: React.ReactNode }) {
// ...
}
Dinámica:
export async function generateMetadata({ params }: { params: { id: string } }) {
const item = await getItem(params.id);
return { title: item.title };
}
OpenGraph listo. Google te ama.
Accesibilidad y Validación
Formularios accesibles venden. Usa ARIA y labels.
Server-side validation con Zod + Server Actions.
Mejora con error.tsx en forms.
Prueba con Lighthouse. Next.js 15 puntúa alto por defecto.
Despliegue en Vercel
Lista para prod. Push a GitHub.
Conecta Vercel, deploy automático.
npm i -g vercel
vercel
Edge runtime para funciones globales. Zero-config previews.
¿Qué si usas Netlify? Funciona, pero Vercel es nativo.
Próximos Pasos y Tips Avanzados
Has construido un dashboard full-stack. ¿Quieres más?
Explora Partial Prerendering en Next.js 15. Mezcla static y dynamic.
Integra AI con Vercel AI SDK para resúmenes de video, como en tutorials pro.
Monitorea con Vercel Analytics. Optimiza bottlenecks.
¿Atascado? Revisa docs.nextjs.org/learn. Comunidad en Discord.
Este Tutorial Nextjs 15: Guía Completa Paso a Paso te da bases sólidas. Prueba variaciones, como multi-tenant apps.
¡Comparte tu proyecto en comentarios! Sigue coding.