SvelteKit

``

Qué es SvelteKit

SvelteKit es el framework oficial basado en Svelte que permite construir aplicaciones completas (SSR, SPA, SSG, Edge Rendering). Combina un enrutado basado en el filesystem, loaders y actions, adaptadores desplegables y una arquitectura optimizada para rendimiento.

Características clave

  • SSR progresivo: Renderizado inicial en servidor con hidración parcial.
  • File-based routing: La estructura de /src/routes determina las rutas automáticamente.
  • Optimización automática: Code-splitting, prerendering selectivo, tree-shaking y cargas diferidas.
  • Adaptadores: Deploy a Node, Vercel, Cloudflare, Netlify, estático, etc.
  • Reactividad de Svelte: Actualización fina sin VDOM.
  • Stores compartidos: Estado global reactivo sin librerías externas.
  • Acciones y loaders: Lógica de servidor integrada sin necesidad de backend separado.

Estructura básica de un proyecto

  • /src/routes
    • Define páginas, layouts y endpoints.
  • /src/lib
    • Código reutilizable (componentes, utilidades, stores).
  • +page.svelte
    • Componente de página.
  • +page.server.js
    • Lógica que corre exclusivamente en el servidor.
  • +layout.svelte
    • Plantilla común para un conjunto de rutas.
  • +layout.server.js
    • Lógica para cargar datos comunes.

Fundamentos del enrutado

  • Rutas simples: src/routes/about/+page.svelte/about
  • Rutas dinámicas: src/routes/blog/[slug]/+page.svelte
  • Layouts anidados: Cada carpeta puede tener su propio layout que se compone con los superiores.
  • Rutas API: +server.js o +server.ts crean endpoints REST o acciones personalizadas.

Loaders (load)

Permiten cargar datos antes de renderizar la página. Pueden ejecutarse en servidor o cliente según el archivo.

+page.js y +layout.js

  • Se ejecutan en cliente tras la primera carga.
  • Útiles para datos no sensibles o dinámicos.

+page.server.js y +layout.server.js

  • Siempre se ejecutan en el servidor.
  • Ideales para datos sensibles, consultas protegidas o acceso a APIs privadas.

Actions (formularios progresivos)

Permiten manejar formularios y mutaciones sin necesidad de endpoints adicionales.

  • +page.server.js define acciones como actions = { default: async (event) => { ... } }
  • Funcionan con SSR, devolviendo fail() o redirect() según el flujo.
  • Compatibles con progressive enhancement.

Stores y estado global

  • Writable: estado reactivo mutable.
  • Readable: estado derivado o estático.
  • Derived: valores calculados automáticamente.
  • Permiten manejar estado global sin Redux ni context.

Rendering modes

  • SSR (por defecto): Ideal para SEO y contenido dinámico.
  • CSR: Cuando necesitas una SPA pura.
  • Prerendering: Generación estática de rutas (prerender = true).
  • Hybrid: Mezcla de estático + dinámico según ruta.

Despliegue y adaptadores

SvelteKit usa adaptadores para ajustar el build al entorno de ejecución.

  • @sveltejs/adapter-auto → elige el mejor para tu entorno.
  • @sveltejs/adapter-node → servidor Node.
  • @sveltejs/adapter-cloudflare → workers.
  • @sveltejs/adapter-vercel → Vercel Edge/Serverless.
  • @sveltejs/adapter-static → sitios 100% prerenderizados.

Buenas prácticas esenciales

  • Usar +page.server.js para datos sensibles.
  • Mantener lógica de negocio en /src/lib.
  • Aprovechar form actions para mutaciones.
  • Dividir layouts para mejorar composición y performance.
  • Usar export const prerender = true en rutas estáticas.

Ejemplos de código

Ejemplo: loader en +page.server.js

// +page.server.js
export async function load({ params }) {
	const post = await fetchPost(params.slug);
	return { post };
}

`

Ejemplo: acción de formulario

// +page.server.js
import { fail, redirect } from '@sveltejs/kit';

export const actions = {
	default: async ({ request }) => {
		const data = Object.fromEntries(await request.formData());
		const ok = await saveUser(data);

		if (!ok) return fail(400, { message: 'Datos inválidos' });
		throw redirect(303, '/dashboard');
	}
};

Ejemplo: store global

// src/lib/stores/user.js
import { writable } from 'svelte/store';

export const user = writable(null);

Ejemplo: página con datos cargados

<!-- +page.svelte -->
<script>
	export let data;
</script>

<h1>{data.post.title}</h1>
<p>{data.post.content}</p>

SvelteKit — Conceptos Avanzados

Hooks y ciclo de vida del servidor

SvelteKit permite interceptar y modificar peticiones y respuestas usando hooks. Se definen en src/hooks.server.js.

  • handle: Permite envolver todas las requests y responses.
// src/hooks.server.js
export async function handle({ event, resolve }) {
	// Modificar request o autenticar usuario
	const response = await resolve(event);
	return response;
}
  • handleFetch: Intercepta fetch internos para añadir headers, tokens, etc.
  • handleError: Maneja errores globales de SSR.
  • getSession (deprecated, se reemplaza con event.locals): permite exponer datos de usuario a la app.

event.locals y manejo de estado temporal

event.locals es el lugar recomendado para almacenar datos por request, como usuario autenticado.

// src/hooks.server.js
export async function handle({ event, resolve }) {
	event.locals.user = await getUserFromCookie(event.request.headers.get('cookie'));
	return resolve(event);
}

Rutas protegidas y autenticación

Para proteger rutas se puede usar un loader en +page.server.js verificando event.locals:

// +page.server.js
import { redirect } from '@sveltejs/kit';

export async function load({ locals }) {
	if (!locals.user) throw redirect(303, '/login');
	return { user: locals.user };
}

Manejo avanzado de errores

  • +error.svelte captura errores por ruta.
  • handleError permite logging global:
// src/hooks.server.js
export function handleError({ error, event }) {
	console.error('Error en request:', event.url, error);
	return { message: 'Ocurrió un error interno' };
}

Optimización y rendimiento

  • Prerendering selectivo: export const prerender = true/false
  • Streaming SSR: permite enviar contenido progresivamente al cliente.
  • Cache control: configurar headers para mejorar el rendimiento y edge caching.
  • Edge rendering: desplegar con adaptadores para ejecución en CDN/Edge.

Formularios avanzados y validación

  • Uso de librerías como zod o superValidate para validación avanzada.
  • Compatible con progressive enhancement.
import { z } from 'zod';
const schema = z.object({ email: z.string().email() });

Environment Variables

  • $env/static/private → variables privadas disponibles solo en build/server.
  • $env/static/public → expuestas al cliente.
  • $env/dynamic/private → accesibles dinámicamente en SSR.

Internacionalización (i18n)

  • Se puede integrar usando stores y loaders para traducir contenido dinámico.
  • Ejemplo simple con store:
// src/lib/stores/i18n.js
import { writable } from 'svelte/store';
export const locale = writable('es');
  • <slot> permite componer layouts.
  • Layouts paralelos: diferentes layouts para rutas específicas.
  • Layout resets: reiniciar layout en subruta usando +layout.reset.svelte.

Acceso avanzado a cookies y request

  • event.cookies permite leer y escribir cookies con seguridad.
// +page.server.js
export function load({ cookies }) {
	const token = cookies.get('session');
	return { token };
}

Integración con bases de datos y ORMs

  • Conexión directa en loaders o actions (+page.server.js) usando Prisma, Drizzle o cualquier ORM.
  • Evitar exponer credenciales al cliente.

Testing en SvelteKit

  • Vitest → testing unitario de componentes y stores.
  • Playwright → pruebas end-to-end para navegación, SSR y formularios.

Configuración avanzada

  • svelte.config.js permite configurar adaptadores, preprocessors, alias y más.
  • Ejemplo:
import adapter from '@sveltejs/adapter-vercel';
export default {
	kit: {
		adapter: adapter(),
		alias: { $lib: 'src/lib' }
	}
};

Datos incrementales y partial loading

  • Cargar solo lo necesario para renderizar primero.
  • Ideal para dashboards y listados grandes.
  • Se combina con streaming SSR para mejorar experiencia de usuario.

Summary

SvelteKit avanzado combina: - SSR optimizado y edge-ready
- Form actions progresivos y seguros
- Manejo de errores y estado por request (event.locals)
- Internacionalización y layouts complejos
- Integración con bases de datos y testing completo
- Optimización mediante prerendering, streaming y cache control

Estos conceptos permiten construir aplicaciones completas, escalables y seguras sin depender de librerías externas para estado, routing o validación.