Workshops/2025
Astro-Workshop
This page was used for misc. links during the live workshop I did in June of 2025 on Astro!
The complete StackBlitz example (with some stuff I didn’t end up getting to in the workshop portion) is available here.
They’ll probably lack context without my words next to them, but here are the slides from the introduction:
Links from the live talk:
3: https://github.com/ascorbic/astro-loaders/tree/main/packages/feed
4: https://jackharrhy.dev/linkblog/rss.xml
5: https://pokeapi.co/api/v2/pokemon/ditto
import { useState, useEffect, useRef } from 'react';
export default function PokemonSearch() {
const [term, setTerm] = useState('');
const [pokemon, setPokemon] = useState(null);
const debounce = useRef();
useEffect(() => {
if (!term) {
setPokemon(null);
return;
}
clearTimeout(debounce.current);
debounce.current = setTimeout(async () => {
try {
const res = await fetch(
`https://pokeapi.co/api/v2/pokemon/${term.toLowerCase()}`
);
if (!res.ok) throw new Error();
const data = await res.json();
setPokemon({
name: data.name,
type: data.types.map((t) => t.type.name).join(', '),
img: data.sprites.front_default,
});
} catch {
setPokemon(null);
}
}, 300);
return () => clearTimeout(debounce.current);
}, [term]);
return (
<div className="pokemon-search">
<input
value={term}
onChange={(e) => setTerm(e.target.value)}
placeholder="Search Pokémon"
/>
{pokemon && (
<div className="result">
<h2 className="capitalize">{pokemon.name}</h2>
<p>Type: {pokemon.type}</p>
{pokemon.img && (
<img src={pokemon.img} alt={pokemon.name} width={96} height={96} />
)}
</div>
)}
</div>
);
}