# Consumiendo la API de Rick & Morty con SvelteKit , App sencilla
He creado mi primera aplicación en SvelteKit que consume una API externa. Concretamente, he trabajado con la Rick and Morty API para crear una galería de personajes con páginas de detalle.
He descubierto que SvelteKit tiene un sistema de archivos que automáticamente crea las rutas de mi aplicación. Esto significa que:
src/routes/+page.svelte → Se convierte en la página principal /src/routes/character/[id]/+page.svelte → Se convierte en /character/123 (rutas dinámicas)Como se hace en NextJS
+page.ts + +page.svelteUna de las cosas más importantes que he aprendido es cómo SvelteKit separa la lógica de carga de datos de la presentación:
+page.ts:export const load: PageLoad = async ({ fetch }) => {
const response = await fetch('https://rickandmortyapi.com/api/character');
const data = await response.json();
return {
characters: data.results
};
}
Aquí es donde pido los datos a la API. Esta función se ejecuta antes de que se renderice la página.
+page.svelte:<script>
let { data } = $props();
</script>
{#each data.characters as char}
<Card characters={char} />
{/each}
Aquí recibo los datos que preparó el archivo .ts y los muestro. Es como si el .ts fuera el chef que cocina y el .svelte fuera el camarero que sirve el plato.
interface Personaje {
name: string;
image: string;
id: string;
}
export const load: PageLoad = async ({ fetch, params }) => {
// TypeScript sabe qué contiene 'params' y 'fetch'
}
El tipo PageLoad es proporcionado por SvelteKit y me dice exactamente qué puedo hacer dentro de esta función.
Card.svelteHe creado mi primer componente reutilizable. Esto me permite:
Recibir datos desde el componente padre:
let { characters }: Props = $props();
Mostrar la información de manera consistente:
<a href="/character/{characters.id}" class="card">
<img src={characters.image} alt={characters.name} />
<h3>{characters.name}</h3>
</a>
Reutilizarlo tantas veces como necesite sin duplicar código.
[id]He aprendido que cuando creo una carpeta con corchetes [id], SvelteKit entiende que es una ruta dinámica, se me ha hecho facil el concepto dado que tambien se hace igual en NEXTJS:
routes/
character/
[id]/
+page.svelte
+page.ts
Esto me permite:
/character/1, /character/2, etc.params.id en mi función load:export const load: PageLoad = async ({ fetch, params }) => {
const id = params.id; // ¡El ID viene de la URL!
const response = await fetch(`https://rickandmortyapi.com/api/character/${id}`);
// ...
}
He aprendido a manejar errores con svelte
if (!response.ok) {
if (response.status === 404) {
error(404, {
message: '¡Vaya! Este personaje no existe en este universo. 🌌'
});
}
}
Y he creado un archivo +error.svelte que muestra mensajes bonitos cuando algo falla, en lugar de dejar que la aplicación explote.
El fetch que recibo en SvelteKit no es el fetch normal del navegador. Es una versión mejorada que:
He dominado la sintaxis {#each} de Svelte:
{#each data.characters as char}
<Card characters={char} />
{/each}
{# = Apertura de bloque/} = Cierre de bloqueEs mucho más limpio que escribir bucles en JavaScript tradicional.
try {
const response = await fetch(url);
// ...
} catch (err: unknown) {
error(503, {
message: 'No se pudo conectar con el servidor.'
});
}
Api-rickandmorty/
├── src/
│ ├── routes/
│ │ ├── +page.svelte # Página principal con galería
│ │ ├── +page.ts # Carga datos de todos los personajes
│ │ ├── +error.svelte # Página de error personalizada
│ │ └── character/
│ │ └── [id]/
│ │ ├── +page.svelte # Detalle de un personaje
│ │ └── +page.ts # Carga datos de un personaje específico
│ └── lib/
│ └── Card.svelte # Componente de tarjeta reutilizable
# Instalar dependencias
bun install
# Modo desarrollo
bun run dev
# Build para producción
bun run build
Nota: Este proyecto forma parte de mi proceso de aprendizaje en desarrollo web con Svelte.