# Les 15 — Externe APIs + Cursor agents + Vercel deploy ## Slide Overzicht (Klas A — 3 uur fysiek, demo-driven) **Lesvorm:** Tim demonstreert klassikaal. Studenten kijken. Zelf bouwen = huiswerk. **Demo-app:** Nieuwe kleine Pokédex (PokéAPI, geen key, visueel) **Vervolg op:** Les 14 — RAG + Embeddings **Aansluit op:** Les 16 — MCP servers --- ## Slide 1: Title ### Les 15 — Externe APIs + Cursor + Vercel **Visual:** - Background: CREAM - "Les 15" in BLUE - "Externe APIs + Cursor + Vercel" in BLACK - Subtitle: "Van localhost naar productie — met Cursor agents en preview deploys" --- ## Slide 2: Terugblik ### Waar staan we? **Vorige lessen:** - Les 11: AI SDK basics - Les 12: Tool Calling - Les 13: Agents **Tot nu toe:** alles draaide op `localhost:3000`. Geen wereld eromheen. **Vandaag:** - Externe APIs aanroepen (geen LLM nodig, gewoon data ophalen) - App naar productie met Vercel - Feature branches met Cursor agents (Composer + Background) - GitHub Actions CI (lint + build per PR) **Visual:** localhost icoon → cloud icoon met branches eruit. --- ## Slide 3: Planning ### Vandaag — 180 minuten | Onderwerp | Duur | |-----------|------| | Welkom + Terugblik | 10 min | | Theorie: Externe APIs in Next.js | 15 min | | Theorie: Cursor agents — Composer vs Background | 15 min | | Theorie: Vercel preview deploys + GH Actions | 15 min | | **Live Demo 1** — Pokédex bouwen met Composer | 30 min | | **Live Demo 2** — Deploy naar Vercel productie | 15 min | | **Pauze** | 15 min | | **Live Demo 3** — Feature branch met Background Agent | 25 min | | **Live Demo 4** — GitHub Actions CI | 15 min | | Composer vs Background — wanneer welke? | 10 min | | Lesopdracht + Huiswerk | 10 min | | Vragen + Afsluiting | 5 min | **Format:** Demo-driven, Cursor en browser side-by-side. --- ## Slide 4: Wat is een externe API? ### Data van buiten, in jouw app **Het idee:** - Andere mensen / bedrijven hebben data of functionaliteit - Ze stellen die beschikbaar via HTTP endpoints (REST) - Jij doet een `fetch()` en krijgt JSON terug **Voorbeelden:** - PokéAPI — Pokemon data (geen key) - Tavily — web search (key nodig) - Stripe — betalingen (key + secret) - GitHub API — repos, users, issues - Open-Meteo — weer (geen key) **In Next.js — twee plekken om te fetchen:** | Server-side (RSC / API route) | Client-side (`useEffect`) | |-------------------------------|---------------------------| | Snel, key veilig, gecached | Nodig voor user-interactie | | Voor initiële data | Voor live updates | **Visual:** Diagram: Next.js → fetch → externe API → JSON terug. --- ## Slide 5: Externe API in Next.js — code ### Server Component met fetch ```typescript // app/pokemon/[name]/page.tsx async function getPokemon(name: string) { const res = await fetch( `https://pokeapi.co/api/v2/pokemon/${name}`, { next: { revalidate: 3600 } } // cache 1 uur ); if (!res.ok) throw new Error("Pokemon niet gevonden"); return res.json(); } export default async function PokemonPage({ params }) { const pokemon = await getPokemon(params.name); return (

{pokemon.name}

); } ``` **Drie dingen om te weten:** 1. **`async`** Server Component — fetch direct in component 2. **`next: { revalidate }`** — Next.js cache opties 3. **Error handling** — `!res.ok` netjes afvangen --- ## Slide 6: Cursor — twee soorten agents ### Composer vs Background | | Composer | Background Agent | |---|----------|------------------| | Waar draait | Lokaal in je editor | Cursor cloud | | Mode | Synchroon — jij wacht | Async — runt zonder jou | | Output | Diffs in editor | Branch + PR op GitHub | | Goed voor | Pair programming, snelle changes | Welomschreven feature, tijdens andere taak | | Aanroep | `Cmd+I` (Mac) / `Ctrl+I` | `Cmd+Shift+P` → Background Agent | | Repo nodig | Lokaal | Verbonden met Cursor cloud | **Beide kanten:** - Composer: jij stuurt, snel feedback, niet schaalbaar voor lange taken - Background: schaalbaar (5 agents tegelijk), maar minder controle in flight **Visual:** Twee tracks naast elkaar — synchroon (jij + composer) vs asynchroon (background agent + jij elders). --- ## Slide 7: Vercel preview deploys ### Een URL per branch — automatisch **Hoe het werkt:** 1. Connect je GitHub repo aan Vercel (eenmalig) 2. Push naar `main` → **productie** deploy op `je-app.vercel.app` 3. Push naar elke andere branch → **preview** deploy op `je-app-git-{branch}-{user}.vercel.app` 4. PR krijgt automatisch een comment met preview URL **Wat krijg je:** - Stakeholders zien een nieuwe feature voor de merge - Cursor Background Agent maakt een PR → preview URL → klikbaar - Reviewer test live in browser, niet alleen code-diff **Environment scopes:** | Scope | Wanneer | Voorbeeld var | |-------|---------|---------------| | **Production** | Deploys vanaf `main` | Echte API key | | **Preview** | Alle andere branches | Test API key | | **Development** | Lokaal (`.env.local`) | Dev API key | --- ## Slide 8: GitHub Actions CI ### Lint + build per PR **Waarom:** - Voor merge weet je: code lint clean én build slaagt - Voorkomt "werkte op mijn laptop" - Background Agent doet PR → CI draait automatisch → groene check of feedback **Minimaal `.github/workflows/ci.yml`:** ```yaml name: CI on: pull_request: branches: [main] push: branches: [main] jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v3 with: { version: 9 } - uses: actions/setup-node@v4 with: { node-version: 20, cache: pnpm } - run: pnpm install - run: pnpm lint - run: pnpm build ``` **Tijd per CI-run:** ~1-2 min op een kleine Next.js app. --- ## Slide 9: Wat we vandaag bouwen ### Pokédex — Next.js + PokéAPI **Doel:** Een mini-Pokédex om de hele pipeline te oefenen. **Stack:** - Next.js 16 + TypeScript + Tailwind + Shadcn - PokéAPI (geen key, gratis, geen rate-limit bij normaal gebruik) - Cursor (Composer + Background Agent) - GitHub (repo + Actions) - Vercel (productie + preview deploys) **Features die we bouwen vandaag:** | Feature | Met | Branch | |---------|-----|--------| | Pokédex list (eerste 151) | Composer | main | | Detail page per Pokemon | Composer | main | | Search met filter | Background Agent | feature/search | | Type-filter chips | Background Agent | feature/type-filter | **Visual:** Folder-tree + GitHub branch-diagram + Vercel URLs. --- ## Slide 10: LIVE DEMO 1 — Pokédex met Composer ### ~30 min **Wat ik laat zien:** 1. `pnpm create next-app pokedex --typescript --tailwind --app` 2. Open in Cursor 3. **Composer (`Cmd+I`)**: "Bouw een lijst-pagina met de eerste 151 Pokémon van PokéAPI, gebruik Tailwind cards" 4. Composer maakt: `app/page.tsx` met fetch + map + cards 5. `pnpm dev` — werkt 6. **Composer**: "Voeg detail-pagina toe op /pokemon/[name] met sprite + types + stats" 7. Composer maakt: `app/pokemon/[name]/page.tsx` 8. Cards op homepage linken naar detail-pages 9. Klein bugje fix-en in chat: "de cards zijn te smal" **Belangrijk om uit te leggen:** - Composer is een TAB in Cursor — niet hetzelfde als Chat - Multi-file edits zichtbaar als diffs — je accepteert per file - Terminal commands vragen toestemming **Visual:** Cursor screenshot met Composer panel. --- ## Slide 11: LIVE DEMO 2 — Deploy naar Vercel productie ### ~15 min **Wat ik laat zien:** 1. **GitHub:** new repo `pokedex` — public 2. **Lokaal:** ```bash git init git add . && git commit -m "Initial Pokédex" git branch -M main git remote add origin https://github.com/USER/pokedex.git git push -u origin main ``` 3. **Vercel:** Add New → Import Git Repository → kies `pokedex` → Deploy 4. Wachten 60-90s op build 5. Open productie URL — werkt! 6. **Wijziging:** title aanpassen, push naar main → 2e deploy, ~30s **Wat studenten moeten zien:** - One-time setup (Vercel verbinden) - Daarna: push to main = deploy - Build logs in Vercel dashboard - Custom domain mogelijk (skipping vandaag) --- ## Slide 12: Pauze ### 15 minuten --- ## Slide 13: LIVE DEMO 3 — Feature branch + Background Agent ### ~25 min **Wat ik laat zien:** 1. **Cursor:** `Cmd+Shift+P` → "Open Background Agent" 2. **Verbind** repo aan Cursor cloud (eenmalig — accepteren in browser) 3. **Prompt aan Background Agent:** > "Maak een nieuwe branch `feature/search`. Voeg een zoekbalk toe bovenaan de homepage. Wanneer iemand typt, filter de Pokémon-lijst op naam. Gebruik client-side state. Push de branch + open een PR met titel 'Add search bar'." 4. **Background Agent gaat aan de slag** — Tim laat zien hoe je 'm volgt in het Cursor panel 5. **~3-5 minuten later:** PR verschijnt op GitHub 6. **Vercel** comment in PR: preview URL → klik → live preview! 7. **Demo:** zoeken werkt op preview URL 8. **Code review** in GitHub UI: wat heeft de agent gedaan? 9. **Merge** → main → productie deploy **Tweede prompt — parallel:** > "Maak branch `feature/type-filter`. Voeg chips toe bij elk type (fire, water, ...) om te filteren." Beide branches kunnen tegelijk draaien. **Visual:** Cursor Background Agent panel + GitHub PR + Vercel preview URL. --- ## Slide 14: LIVE DEMO 4 — GitHub Actions CI ### ~15 min **Wat ik laat zien:** 1. **Vraag aan Composer:** > "Voeg een GitHub Actions workflow toe: lint + build moeten slagen op PR's naar main." 2. Composer maakt `.github/workflows/ci.yml` 3. Push naar nieuwe branch `chore/add-ci` 4. Open PR → GitHub Actions tab → workflow draait 5. **Demo failing CI:** introduceer typo (``), push, zie rode X 6. Fix met Composer ("repareer de TypeScript build error in de PR"), push, zie groene check 7. **Branch protection:** main beschermen — PR's mogen pas mergen als CI groen is **Waarom belangrijk:** - Background Agents kunnen lint-errors maken — CI vangt dit op - Voor je merge: weet je dat het op een schone runner ook werkt - Geen "werkt op mijn laptop"-discussies --- ## Slide 15: Composer vs Background Agent ### Wanneer welke? | Scenario | Tool | |----------|------| | Snelle wijziging tijdens coden | Composer | | Complex refactor over meerdere files | Composer (kun je begeleiden) | | Onbekend gebied — wil zien wat agent doet | Composer | | Welomschreven feature, kan op de achtergrond | Background Agent | | Parallel werken aan 3 features | 3x Background Agent | | Tijdens vergadering een PR voorbereiden | Background Agent | | Repo nog niet in Cursor cloud | Composer | **Mentale model:** - **Composer = pair programming** — jij + AI samen aan dezelfde plek - **Background Agent = delegeren** — je geeft taak, gaat iets anders doen, komt terug **Risico bij Background Agent:** - Agent kan vastlopen op rare config — debugging is moeilijker - Verbruikt credits (Cursor Pro of Business) - Te vage prompts → matige PR's. Specifiek zijn helpt. --- ## Slide 16: Lesopdracht + Huiswerk ### Pokédex zelf bouwen + deploy **Lesopdracht (in-class, 30 min):** - Eigen Pokédex repo opzetten (zelfde setup als demo) - 1 feature met Composer toevoegen - Push naar GitHub + connect Vercel - Productie URL openen — werkt **Huiswerk (voor Les 16):** - **A:** Feature branch met Background Agent (1 feature, jouw keuze) → preview URL delen - **B:** GitHub Actions CI (lint + build) in werking - **C:** Branch protection — main mag pas merge na groene CI - **D:** `DEPLOY.md` met: - Productie URL + 1 preview URL - Reflectie: Composer vs Background — wanneer welke werkte beter? - 1 voorbeeld waar Background Agent verbluffend goed of slecht was **Bonus:** - Eigen externe API integreren (Open-Meteo, GitHub, jouw keuze) - Vercel environment vars demo (verschillende waarde in preview vs prod) --- ## Slide 17: Volgende les + Afsluiting ### Vragen? **Vandaag gezien:** - Externe API integratie in Server Components - Cursor Composer voor synchrone changes - Cursor Background Agent voor async features - Vercel productie + preview per branch - GitHub Actions CI (lint + build) - Wanneer welke Cursor-modus **Volgende les (Les 16): MCP — Model Context Protocol** - Wat is MCP (Model Context Protocol) - Bestaande MCP servers gebruiken in Cursor/Claude Desktop - Eigen MCP server bouwen + laden - Demo: eigen tools beschikbaar in alle MCP-clients **Daarna in deze leerlijn:** - Les 17: Externe APIs in diepte (OAuth, webhooks, paid APIs) - Les 18: Supabase Auth + RLS — multi-user apps **Vragen? Feedback?** --- ## Slide Summary | # | Title | Type | |---|-------|------| | 1 | Title | Opening | | 2 | Terugblik | Recap | | 3 | Planning | 180-min | | 4 | Externe APIs | Theorie | | 5 | Externe API code | Theorie | | 6 | Cursor — Composer vs Background | Theorie | | 7 | Vercel preview deploys | Theorie | | 8 | GitHub Actions CI | Theorie | | 9 | Wat we bouwen | Intro demo | | 10 | **LIVE DEMO 1** — Pokédex + Composer | Demo | | 11 | **LIVE DEMO 2** — Vercel deploy | Demo | | 12 | Pauze | Break | | 13 | **LIVE DEMO 3** — Background Agent + preview | Demo | | 14 | **LIVE DEMO 4** — GitHub Actions CI | Demo | | 15 | Wanneer welke Cursor-mode | Reflectie | | 16 | Lesopdracht + Huiswerk | Praktijk | | 17 | Afsluiting + Les 15 preview | Closing | --- ## Bronnen - **PokéAPI:** https://pokeapi.co/ - **Next.js fetching:** https://nextjs.org/docs/app/building-your-application/data-fetching - **Cursor agents:** https://cursor.com/product - **Vercel preview deployments:** https://vercel.com/docs/deployments/preview-deployments - **Vercel environment variables:** https://vercel.com/docs/environment-variables - **GitHub Actions for Next.js:** https://nextjs.org/docs/app/building-your-application/deploying - **GitHub branch protection:** https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches