¿Qué es SvelteKit?
SvelteKit es el framework oficial de aplicaciones para Svelte. Mientras que Svelte te proporciona los componentes y la reactividad, SvelteKit añade el enrutamiento, la carga de datos en el servidor, el manejo de formularios, endpoints de API y adaptadores de despliegue. Es la forma recomendada de construir cualquier proyecto más complejo que un simple widget, y se integra de forma natural con Svelte 5.
Si has utilizado Next.js o Nuxt, la estructura te resultará familiar. La diferencia es una fuerte inclinación hacia los estándares web: los formularios, las peticiones y las respuestas son primitivas de la plataforma, y SvelteKit las potencia en lugar de reemplazarlas.
Enrutamiento basado en archivos
Todo reside en src/routes. Las carpetas se convierten en segmentos de la URL y los archivos con nombres específicos definen el comportamiento.
src/routes/
├── +layout.svelte # shared shell for all routes
├── +page.svelte # /
├── about/+page.svelte # /about
├── blog/
│ ├── +page.svelte # /blog
│ └── [slug]/
│ ├── +page.svelte # /blog/:slug
│ └── +page.server.js # data for that page
└── api/
└── posts/+server.js # GET/POST /api/posts
El prefijo + marca los archivos especiales de SvelteKit. +page.svelte renderiza una página, +layout.svelte envuelve las rutas hijas, +page.server.js proporciona datos exclusivos del servidor y +server.js define un endpoint de API.
Funciones de carga (Load functions)
Las load functions obtienen datos antes de que una página se renderice. Pueden ejecutarse en el servidor, en el navegador o en ambos.
// src/routes/posts/+page.server.js
export async function load({ fetch }) {
const res = await fetch("/api/posts");
if (!res.ok) throw error(500, "Failed to load posts");
return { posts: await res.json() };
}
<!-- src/routes/posts/+page.svelte -->
<script>
let { data } = $props();
</script>
<ul>
{#each data.posts as post (post.id)}
<li>{post.title}</li>
{/each}
</ul>
Debido a que los datos se resuelven antes del renderizado, el primer paint ya contiene contenido. Usa +page.server.js cuando el código necesite secretos o una base de datos, y +page.js cuando pueda ejecutarse en ambos entornos. Los layouts también pueden tener load functions, y las cargas de los hijos reciben los datos del padre.
Form actions
Los formularios son ciudadanos de primera clase. Una form action se ejecuta en el servidor y gestiona el envío, sin necesidad de realizar un fetch en el lado del cliente.
// src/routes/posts/new/+page.server.js
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const title = String(data.get("title") ?? "").trim();
if (!title) {
return { success: false, error: "Title is required" };
}
await db.post.create({ data: { title } });
return { success: true };
},
};
<!-- src/routes/posts/new/+page.svelte -->
<script>
let { form } = $props();
</script>
<form method="POST">
<input name="title" />
{#if form?.error}<p class="error">{form.error}</p>{/if}
<button>Create</button>
</form>
El formulario funciona incluso antes de que JavaScript se cargue, y SvelteKit lo mejora una vez que el cliente está listo. El valor devuelto está disponible en la prop form de la página, por lo que la retroalimentación de la validación es sencilla.
Endpoints de la API
Para las API JSON, un archivo +server.js exporta los handlers de HTTP.
// src/routes/api/posts/+server.js
import { json } from "@sveltejs/kit";
export async function GET() {
const posts = await db.post.findMany();
return json(posts);
}
export async function POST({ request }) {
const body = await request.json();
const post = await db.post.create({ data: body });
return json(post, { status: 201 });
}
Estos son objetos Request y Response web ordinarios, por lo que los mismos conocimientos se transfieren a otros runtimes y frameworks.
Hooks
Un archivo hooks.server.js se ejecuta en cada solicitud. Es el lugar ideal para gestionar la autenticación, el registro de logs y poblar event.locals.
// src/hooks.server.js
export async function handle({ event, resolve }) {
const session = await getSession(event.cookies);
event.locals.user = session?.user ?? null;
return resolve(event);
}
Cualquier valor que definas en locals estará disponible para las funciones de carga y las acciones, lo que permite mantener las preocupaciones transversales en un solo lugar en vez de dispersas por todas las rutas.
Renderizado y adaptadores
SvelteKit soporta diversas estrategias de renderizado y te permite elegir una por ruta:
- SSR renderiza en el servidor e hidrata en el navegador.
- Prerendering genera HTML estático en tiempo de compilación.
- CSR renderiza únicamente en el navegador para las rutas que opten por este método.
- Híbrido combina las tres opciones, permitiendo que una página de marketing sea estática mientras que una ruta de la aplicación se renderice en el servidor.
El despliegue se gestiona mediante adapters. Instala el adapter para tu destino — Node, static, Vercel, Netlify, Cloudflare y más —, configúralo y el mismo código fuente se compilará para esa plataforma. Cambiar de host suele requerir modificar una sola línea de código.
Mejores prácticas
- Utiliza funciones load de
+page.server.jspara los datos que deben permanecer en el servidor. - Prioriza las form actions sobre las peticiones POST del lado del cliente para las mutaciones.
- Mantén la autenticación y el registro de logs en
hooks.server.js. - Elige el modo de renderizado más restrictivo que se ajuste a cada ruta.
- Utiliza
+layout.sveltepara la UI compartida, de modo que el estado persista durante la navegación. - Define los tipos de los valores de retorno de tus funciones load cuando uses TypeScript.
- Instala desde el principio un adaptador que coincida con tu entorno de despliegue.
Errores comunes
- Hacer fetch en
onMounty perder el renderizado del servidor. - Colocar secretos en un load universal de
+page.jsen lugar de+page.server.js. - Reconstruir formularios con fetch en el cliente cuando las actions ya funcionan.
- Olvidar asignar claves a los bloques
{#each}y romper las actualizaciones de las listas. - Hacer prerendering de una ruta que depende de datos específicos del usuario.
- Ignorar los hooks y duplicar las comprobaciones de autenticación en cada función load.
Próximos pasos
SvelteKit es la forma completa de construir aplicaciones con Svelte. Profundiza tus conocimientos de Svelte, añade TypeScript y compara su arquitectura con Next.js, Nuxt y Astro. Después, construye una aplicación pequeña con una load function, una form action y un API endpoint para ver todo el modelo en acción.