Enrutamiento
- Enrutador basado en el sistema de archivos
- Las rutas URL están definidas por las carpetas y archivos
- Cada directorio de ruta contiene uno o más archivos de ruta , que pueden identificarse por su prefijo +
- Todos los archivos pueden ejecutarse en el servidor
- Todos los archivos se ejecutan en el cliente excepto los archivos
+server - Los archivos
+layouty+errorse aplican tanto a los subdirectorios como al directorio en el que se encuentran - SvelteKit utiliza elementos <a> para navegar entre rutas, en lugar de un componente específico del marco como <Link>.
+page
+page.svelte
- Un componente
+page.sveltedefine una página en la aplicación - De forma predeterminada, las páginas se muestran tanto en el servidor ( SSR ) para la solicitud inicial como en el navegador ( CSR ) para la navegación posterior.
src/routes/+page.svelte
<h1>Hello Word!</h1>
<a href="/about">About my site</a>
src/routes/about/+page.svelte
<h1>About this site</h1>
<a href="/">Home</a>
src/routes/blog/[slug]/+page
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
</script>
<h1>{data.title}</h1>
<div>{@html data.content}</div>
+page.ts
- A menudo, una página necesita cargar algunos datos antes de poder renderizarse.
- Para ello, agregamos un módulo
+page.tsque exporta una funciónload - No incluir información sensible como conexión a base de datos o variables de entorno ya que también se ejecuta del lado del cliente
- Ej. si es SSG, se realizarían las consultas con fetch o axios a la api y se haría el return de los datos obtenidos.
La función load (en +page.ts) se ejecuta junto con +page.svelte, lo que significa que se ejecuta en el servidor durante la representación del lado del servidor y en el navegador durante la navegación del lado del cliente.
src/routes/blog/[slug]/+page
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
// The parameters of the current page
// - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object
export const load: PageLoad = ({ params }) => {
if (params.slug === 'hello-world') {
return {
title: 'Hello world!',
content: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
};
}
error(404, 'Not found');
};
Además load, +page.js puede exportar valores que configuran el comportamiento de la página:
- export const prerender = true o false o 'auto'
- export const ssr = true o false
- export const csr = true o false
+page.server.ts
- Alternativa a
+page.tspara obtener datos solo en el servidor de forma segura
Si la función load solo puede ejecutarse en el servidor (por ejemplo, para obtener datos de una base de datos o acceder a variables de entorno privadas como claves API), se pueden hacer unos cambios
- Cambiar el nombre
+page.jsa+page.server.js - El tipo
PageLoadaPageServerLoad
Durante la navegación del lado del cliente, SvelteKit cargará estos datos desde el servidor, lo que significa que el valor devuelto debe ser serializable mediante devalue.
src/routes/blog/[slug]/+page.server
import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params }) => {
const post = await getPostFromDatabase(params.slug);
if (post) {
return post;
}
error(404, 'Not found');
};
Al igual que +page.js, +page.server.js puede exportar opciones de página como prerender, ssr, y csr.
Un archivo +page.server.js también puede exportar acciones .
Si load permite leer datos del servidor, actions permite escribir datos en el servidor mediante el elemento <form>.
+error
Si se produce un error durante la ejecución load, SvelteKit mostrará una página de error predeterminada.
Se puede personalizar esta página de error para cada ruta agregando un archivo +error.svelte:
<script>
import { page } from '$app/stores';
</script>
<h1>{$page.status}: {$page.error.message}</h1>
src/error.htmlpara errores en la raíz del proyecto (aunque ya muestra uno por defecto)
+layout
- Al navegar, el componente
+page.svelteexistente se destruirá y uno nuevo ocupará su lugar - Pero hay elementos que deberían estar visibles en todas las páginas, como la navegación de nivel superior o un pie de página.
- En lugar de repetirlos en todas +page.svelte, se pueden colocar en los layouts.
+layout.svelte
- Para crear un diseño que se aplique a todas las páginas, crear un archivo llamado
src/routes/+layout.svelte. - El único requisito es que el componente incluya un
<slot>para el contenido de la página. - El diseño predeterminado (el que usa SvelteKit si no traes el tuyo) se ve así...
<slot></slot>
Layout personalizado
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/settings">Settings</a>
</nav>
<slot></slot>
Para las rutas
<h1>Home</h1>
<h1>About</h1>
<h1>Settings</h1>
+layout.js
Al igual que +page.svelte carga datos desde +page.js, el componente +layout.svelte puede obtener datos de una función load en +layout.js.
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = () => {
return {
sections: [
{ slug: 'profile', title: 'Profile' },
{ slug: 'notifications', title: 'Notifications' }
]
};
};
- Si una página
+layout.jstiene opcionesprerender, ssr y csr, se usarán como predeterminadas para las páginas secundarias - Los datos devueltos desde la función
loadde un diseño también están disponibles para todas sus páginas secundarias:
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
console.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]
</script>
+layout.server.js
- Para ejecutar la función
loaddel layout en el servidor; - debe moverse de
+layout.tsa+layout.server.ts - y del tipo
LayoutLoadaLayoutServerLoad. - Al igual que
+layout.js,+layout.server.jspuede exportar opciones de página; prerender, ssry csr.
+server
- Además de las páginas, se puede definir rutas con un archivo
+server.js(a veces denominado "ruta API" o "punto final") - El archivo
+server.jsexporta funciones correspondientes a verbos HTTP comoGET,POST,PATCH,PUT,DELETE,OPTIONS, yHEADque toman un argumentoRequestEventy devuelven un objetoResponse
Ejemplo, una ruta /api/random-number con un controlador GET:
- Se puede utilizar los métodos error, redirect y json pero no es necesario
- Si hay error, devolverá un JSON
import { error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const GET: RequestHandler = ({ url }) => {
const min = Number(url.searchParams.get('min') ?? '0');
const max = Number(url.searchParams.get('max') ?? '1');
const d = max - min;
if (isNaN(d) || d < 0) {
error(400, 'min and max must be numbers, and min must be less than max');
}
const random = min + Math.random() * d;
return new Response(String(random));
};
Enviando datos a una ruta API
- Al exportar (usar) los controladores
POST/PUT/PATCH/DELETE/OPTIONS/HEAD, los archivos+server.jsse pueden usar para crear una API completa - En general, las acciones de formulario son una mejor manera de enviar datos desde el navegador al servidor.
Vista
- src/routes/add/+page.svelte
<script>
let a = 0;
let b = 0;
let total = 0;
async function add() {
const response = await fetch('/api/add', {
method: 'POST',
body: JSON.stringify({ a, b }),
headers: {
'content-type': 'application/json'
}
});
total = await response.json();
}
</script>
<input type="number" bind:value={a}> +
<input type="number" bind:value={b}> =
{total}
<button on:click={add}>Calculate</button>
API
- src/routes/api/add/+server.ts
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const POST: RequestHandler = async ({ request }) => {
const { a, b } = await request.json();
return json(a + b);
};
Error a método no implementado
La exportación del controlador fallback coincidirá con cualquier método de solicitud no manejado
import { json, text } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export async function POST({ request }) {
const { a, b } = await request.json();
return json(a + b);
}
// Este handler responderá a PUT, PATCH, DELETE, etc.
export const fallback: RequestHandler = async ({ request }) => {
return text(`I caught your ${request.method} request!`);
};
Sin carpeta específica para API
Los archivos +server.js se pueden colocar en el mismo directorio que los archivos +page , lo que permite que la misma ruta sea una página o un punto final de API.
Para determinar cuál, SvelteKit aplica las siguientes reglas:
- Las solicitudes
PUT/PATCH/DELETE/OPTIONSsiempre son manejadas por +server.js ya que no se aplican a páginas. - Las solicitudes
GET/POST/HEADse tratan como solicitudes de página si el encabezadoacceptprioriza text/html (en otras palabras, es una solicitud de página del navegador); de lo contrario, son manejadas por +server.js. - Las respuestas a GET incluirán un encabezado
Vary: Accepten, de modo que los servidores proxy y los navegadores almacenen en caché las respuestas HTML y JSON por separado.
$types
Se trata de un archivo que SvelteKit crea en un directorio oculto (con TS) para brindar seguridad de tipos al trabajar con los archivos raíz.
Por ejemplo, export let datacon PageData (o LayoutData, para un archivo +layout.svelte) le dice a TypeScript que el tipo de data es lo que se devolvió desde load
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
</script>
Otros archivos
- SvelteKit ignora cualquier otro archivo dentro de un directorio de ruta.
- Esto significa que se puede colocar componentes y módulos de utilidad con las rutas que los necesitan
- Si varias rutas necesitan componentes y módulos, es una buena idea colocarlos en $lib.