fix: vercel
This commit is contained in:
455
Les14-Cursor-Vercel-Deploy/Les14-Docenttekst.md
Normal file
455
Les14-Cursor-Vercel-Deploy/Les14-Docenttekst.md
Normal file
@@ -0,0 +1,455 @@
|
||||
# Les 13 — Docenttekst (Autocue)
|
||||
|
||||
**Online les — letterlijk voorleesbaar. Slide-nummers staan tussen `[SLIDE N]` zodat je weet wanneer door te klikken.**
|
||||
|
||||
**Lesvorm:** online, demo-driven. Cursor + browser side-by-side delen.
|
||||
**Duur:** 180 minuten met 1 pauze van 15 minuten.
|
||||
|
||||
> **Voor de les klaarzetten:**
|
||||
> - Cursor open in lege werkmap
|
||||
> - Browser tabs open: github.com, vercel.com, pokeapi.co
|
||||
> - Terminal klaar
|
||||
> - Cursor Pro/Business actief (voor Background Agent)
|
||||
> - GitHub + Vercel ingelogd
|
||||
> - Webcam check + scherm delen ingericht
|
||||
|
||||
---
|
||||
|
||||
## BLOK 1 — Welkom + Terugblik (10 min)
|
||||
|
||||
`[SLIDE 1]`
|
||||
|
||||
Welkom bij Les 13. Vandaag is een belangrijke les, want we verlaten voor het eerst je laptop.
|
||||
|
||||
Tot nu toe draaiden al jullie projecten op `localhost:3000`. Dat is prima om te leren, maar in de praktijk wil je dat anderen je werk kunnen zien. Klanten. Collega's. Werkgevers. Vandaag zetten we die stap.
|
||||
|
||||
We gaan drie dingen leren die je voor elk professioneel project nodig hebt. Eén: data ophalen van externe websites en APIs. Twee: je code automatisch online zetten via Vercel. Drie: efficiënt werken met Cursor agents.
|
||||
|
||||
Aan het einde van deze les heb je een live URL die je aan iedereen kunt delen.
|
||||
|
||||
`[SLIDE 2]`
|
||||
|
||||
Even kort terug. In de afgelopen lessen hebben we gewerkt aan AI-features. Les 11 was de Vercel AI SDK, Les 12 was Tool Calling. Allemaal mooi, maar steeds lokaal.
|
||||
|
||||
Vandaag stappen we even uit dat AI-pad. Geen LLM's. Geen API keys voor AI. We gaan terug naar de basis: hoe ziet een professionele Next.js-workflow eruit van localhost tot productie?
|
||||
|
||||
We gebruiken een eenvoudige Pokédex als demo-app. Waarom Pokémon? Omdat de PokéAPI gratis is, geen API key vraagt, en je krijgt direct visuele resultaten. Perfect om je te focussen op de workflow, niet op de data.
|
||||
|
||||
`[SLIDE 3]`
|
||||
|
||||
Dit is de planning voor vandaag. Honderdtachtig minuten.
|
||||
|
||||
We beginnen met theorie. Drie blokken van een kwartier: externe APIs in Next.js, Vercel met preview-omgevingen, en Cursor agents.
|
||||
|
||||
Dan vier live demo's. In demo één bouwen we de Pokédex met Composer. In demo twee deployen we naar Vercel en zetten we environment variables in. Na de pauze: demo drie met de Background Agent om een feature parallel te bouwen. Demo vier: GitHub Actions om CI in te richten.
|
||||
|
||||
Na elke demo bouw je het zelf na in je eigen repo. Vragen tussendoor altijd welkom — typ ze in de chat.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 2 — Theorie: Externe APIs (15 min)
|
||||
|
||||
`[SLIDE 4]`
|
||||
|
||||
Wat is een externe API. In simpele woorden: andere mensen of bedrijven hebben data of functionaliteit, en die stellen ze beschikbaar via HTTP. Jij doet een fetch-request, krijgt JSON terug, en kunt daar dingen mee doen.
|
||||
|
||||
Een paar voorbeelden van APIs die je in projecten zult tegenkomen.
|
||||
|
||||
PokéAPI — onze demo van vandaag. Pokemon-data, geen key nodig.
|
||||
|
||||
Open-Meteo — gratis weerservice, ook geen key.
|
||||
|
||||
GitHub API — informatie over repositories, gebruikers, issues.
|
||||
|
||||
Tavily — web search. Die heeft wél een API key nodig.
|
||||
|
||||
Stripe — betalingen. Twee keys: een publishable en een secret.
|
||||
|
||||
Voor APIs met een key onthoud je één regel: nooit, ooit, in je code committen. Altijd in environment variables. Hier komen we straks bij Vercel uitgebreid op terug.
|
||||
|
||||
`[SLIDE 5]`
|
||||
|
||||
Dit is misschien wel de belangrijkste slide van vandaag. Drie manieren om een API te fetchen in Next.js. Static, server, of client. Welke je kiest hangt af van je use case.
|
||||
|
||||
Eerste optie: **static**. De fetch gebeurt tijdens `next build`. Eén keer, en daarna is het HTML. Snel, want geen server-werk per request. Goed voor data die zelden verandert: een blog-post, een marketing-pagina, een lijst van producten.
|
||||
|
||||
Tweede optie: **server, oftewel dynamic**. De fetch gebeurt bij elke request opnieuw. Altijd vers, maar trager. Goed voor data die per gebruiker anders is, of die altijd up-to-date moet zijn.
|
||||
|
||||
Derde optie: **ISR**, Incremental Static Regeneration. Een mix van de twee. Wordt gecached zoals static, maar elke X seconden mag Next.js de cache vervangen. Het beste van beide werelden. Voor onze Pokédex de juiste keuze voor de detail-pagina's: snel, maar elk uur kijkt Next.js of de PokéAPI iets nieuws heeft.
|
||||
|
||||
Vierde optie: **client-side fetching**, met useEffect. Dit doe je alleen als de data live moet, of als je user-interactie nodig hebt. Belangrijk: bij client-side staat je API key in de browser. Dus alleen voor publieke APIs of voor data die geen geheim is.
|
||||
|
||||
Kijk naar het code-blokje onderaan. Het verschil tussen die drie server-modes is letterlijk één optie in je fetch-call. Verder verandert je code helemaal niet. Dat is de kracht van Next.js: je kiest het render-gedrag per fetch.
|
||||
|
||||
Vandaag gebruiken we static voor de Pokédex-lijst en ISR voor de detail-pages.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 3 — Theorie: Vercel + Cursor + GitHub (15 min)
|
||||
|
||||
`[SLIDE 6]`
|
||||
|
||||
Korte sidetrack — straks komen we terug op Vercel. Even Cursor: twee soorten agents.
|
||||
|
||||
Composer is de agent die je al kent. Cmd+I openen, prompt typen, hij maakt aanpassingen in je editor. Synchroon. Jij wacht, hij werkt, jij kijkt, je accepteert de diff. Pair programming.
|
||||
|
||||
Background Agent is anders. Die draait in Cursor's cloud. Je geeft een opdracht, hij gaat aan de slag, hij maakt een branch, hij pusht naar GitHub, hij opent een Pull Request. Allemaal terwijl jij iets anders doet. Asynchroon dus.
|
||||
|
||||
Het verschil komt straks duidelijk in de demo. Voor nu: onthoud dat je twee modes hebt. Eén voor naast je, één voor namens je.
|
||||
|
||||
`[SLIDE 7]`
|
||||
|
||||
Nu Vercel. Dit is het hart van de les. Drie omgevingen, drie scopes — en het is cruciaal dat je dit begrijpt.
|
||||
|
||||
Productie is de live versie. Wordt gedeployed elke keer dat je naar de `main` branch pusht. URL is `je-app.vercel.app`. Dit ziet iedereen.
|
||||
|
||||
Preview is wat je krijgt voor élke andere branch. Push naar `feature/search` en je krijgt automatisch een URL terug. Iets als `je-app-git-feature-search-jouwnaam.vercel.app`. Ook publiek bereikbaar, maar alleen mensen met de link.
|
||||
|
||||
Development is je lokale `pnpm dev` op localhost. Alleen jij ziet dat.
|
||||
|
||||
Nu de belangrijke vraag: hoe ga je daar mee om als je verschillende databases, of verschillende API keys hebt per omgeving? Want dat wil je. Je wilt absoluut niet dat een experimentele preview-branch in je productie-database gaat schrijven.
|
||||
|
||||
Bekijk de tabel met environment variables. In Vercel ga je naar Project, Settings, Environment Variables. En daar zet je per variabele drie keer een waarde. Voor productie. Voor preview. En voor development.
|
||||
|
||||
Een paar voorbeelden. Je `DATABASE_URL` is voor productie je echte database. Voor preview een staging-database. Voor development je lokale Postgres. Drie totaal verschillende waarden, één variabele-naam.
|
||||
|
||||
Je `OPENAI_API_KEY` is in productie de echte key met hoge limit. In preview een test-key zodat experimenten je niet failliet maken. In development je persoonlijke key.
|
||||
|
||||
Voor Stripe heel concreet: productie is `sk_live_...`, preview en development zijn allebei `sk_test_...`. Een experiment dat per ongeluk een betaling doet komt nooit op een echte creditcard.
|
||||
|
||||
Onderaan staat één killer-combo: Cursor Background Agent maakt een Pull Request, Vercel ziet die PR en bouwt automatisch een preview URL, die URL komt automatisch in een comment op de PR. Reviewer klikt, opent in de browser, test live. Geen lokale setup nodig. Dit is voor mij persoonlijk een van de redenen dat ik altijd met Vercel werk.
|
||||
|
||||
`[SLIDE 8]`
|
||||
|
||||
GitHub Actions, snel. Waarom: voordat je iets merget, weet je zeker dat de code lint en bouwt op een schone machine. Niet "het werkt op mijn laptop", maar "het werkt op een verse ubuntu". Belangrijk omdat Background Agents soms lint-errors maken — CI vangt dat op.
|
||||
|
||||
Kijk naar het code-blok. Een minimale workflow. Bij elke pull request en bij elke push naar main: checkout, pnpm install, pnpm lint, pnpm build. Duurt ongeveer twee minuten op een kleine app.
|
||||
|
||||
In demo vier gaan we dit bouwen.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 4 — Wat we vandaag bouwen (5 min)
|
||||
|
||||
`[SLIDE 9]`
|
||||
|
||||
Dit is wat we vandaag bouwen. Een Pokédex.
|
||||
|
||||
De stack: Next.js 16 met TypeScript en Tailwind. Geen Shadcn vandaag, we houden het simpel. PokéAPI als data-bron, geen API key. Cursor voor de code. GitHub voor de versie-controle. Vercel voor de deploys.
|
||||
|
||||
Vier features die we bouwen. Een lijst met de eerste 151 Pokémon. Detail-pages per Pokémon. Een zoek-functie. Type-filter chips.
|
||||
|
||||
De eerste twee bouwen we met Composer, op de `main` branch. De andere twee met de Background Agent op feature-branches.
|
||||
|
||||
Aan het einde heb je: een productie-URL, twee preview-URL's, drie Pull Requests, een werkende CI-pipeline, en een geverifieerd begrip van static versus ISR.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 5 — LIVE DEMO 1: Pokédex met Composer (30 min)
|
||||
|
||||
`[SLIDE 10]`
|
||||
|
||||
Tijd voor de eerste demo. Open Cursor, lege werkmap, terminal openen.
|
||||
|
||||
Eerste commando, typ mee:
|
||||
|
||||
```bash
|
||||
pnpm create next-app pokedex --typescript --tailwind --app
|
||||
```
|
||||
|
||||
Beantwoord de vragen: geen src directory, gebruik Turbopack, default alias is prima.
|
||||
|
||||
Stap in de map: `cd pokedex` en open in Cursor met `cursor .` of File → Open Folder.
|
||||
|
||||
Nu het magische moment. Druk op Cmd+I — of Ctrl+I op Windows — voor Composer. Type deze prompt letterlijk over:
|
||||
|
||||
> Bouw een lijst-pagina met de eerste 151 Pokémon van PokéAPI. URL is `https://pokeapi.co/api/v2/pokemon?limit=151`. Gebruik Tailwind cards in een grid met de naam en sprite van elke Pokémon. De sprite staat op `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{id}.png` waar {id} het index-nummer is. Gebruik een static fetch — dus géén revalidate optie meegeven.
|
||||
|
||||
Composer gaat aan de slag. Je ziet diffs verschijnen in `app/page.tsx`. Lees ze met me mee. Accepteer alle wijzigingen.
|
||||
|
||||
Start lokaal:
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open `localhost:3000`. Daar zou nu een grid van 151 Pokémon moeten staan. Werkt het? Mooi.
|
||||
|
||||
Tweede prompt in Composer:
|
||||
|
||||
> Voeg een detail-pagina toe op `/pokemon/[id]`. Fetch van `https://pokeapi.co/api/v2/pokemon/{id}`. Toon de official artwork — die staat in `sprites.other["official-artwork"].front_default`. Toon ook de types als chips. Gebruik ISR met `revalidate: 3600`. Zorg dat de cards op de homepage linken naar `/pokemon/[id]`.
|
||||
|
||||
Wacht op de diffs. Accepteer ze. Open een random Pokémon. Werkt? Goed.
|
||||
|
||||
Belangrijke uitleg terwijl studenten kijken:
|
||||
|
||||
Kijk naar het verschil tussen `app/page.tsx` en `app/pokemon/[id]/page.tsx`. De homepage gebruikt gewoon `fetch(URL)`. De detail-pagina gebruikt `fetch(URL, { next: { revalidate: 3600 } })`. Dat is het hele verschil tussen static en ISR. Eén optie.
|
||||
|
||||
Open de browser Network tab — F12. Klik door wat detail-pages. Je ziet dat er geen calls vanuit de browser naar PokéAPI gaan. Alles is server-side. Dat betekent: als PokéAPI morgen omvalt, blijft jouw site werken tot de revalidate triggert.
|
||||
|
||||
Optioneel — en als de tijd het toelaat — voeg een derde route toe met `cache: "no-store"`. Bijvoorbeeld een "random pokemon" pagina. Zo zien studenten alle drie de modes naast elkaar.
|
||||
|
||||
Commit alles in de terminal:
|
||||
|
||||
```bash
|
||||
git add . && git commit -m "Initial Pokédex met Composer"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## BLOK 6 — LIVE DEMO 2: Vercel deploy + env vars (20 min)
|
||||
|
||||
`[SLIDE 11]`
|
||||
|
||||
Tijd om dit live te zetten.
|
||||
|
||||
Open github.com in een nieuwe tab. Klik "New repository". Naam `pokedex`. Public. Geen README, geen gitignore, geen license — die hebben we al lokaal.
|
||||
|
||||
Klik Create. GitHub laat een URL zien. Kopieer die.
|
||||
|
||||
Terug in de terminal:
|
||||
|
||||
```bash
|
||||
git branch -M main
|
||||
git remote add origin https://github.com/JOUWNAAM/pokedex.git
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
Refresh github.com. Daar staat je code.
|
||||
|
||||
Open vercel.com. Log in met GitHub. Klik "Add New" en kies "Project". Vercel toont een lijst met je repositories — kies `pokedex`. Klik "Deploy".
|
||||
|
||||
Wacht zestig tot negentig seconden. Je ziet de build logs voorbij komen. Aan het einde: live URL. Klik. Daar staat je Pokédex op het internet. Live.
|
||||
|
||||
Nu het belangrijkste stuk: environment variables.
|
||||
|
||||
Open `app/page.tsx` lokaal in Cursor. Voeg ergens bovenaan in de return een regel toe:
|
||||
|
||||
```tsx
|
||||
<p className="mb-4 text-sm text-zinc-500">
|
||||
Omgeving: {process.env.NEXT_PUBLIC_APP_ENV ?? "onbekend"}
|
||||
</p>
|
||||
```
|
||||
|
||||
Push naar main:
|
||||
|
||||
```bash
|
||||
git add . && git commit -m "Toon huidige omgeving"
|
||||
git push
|
||||
```
|
||||
|
||||
Vercel deployt automatisch opnieuw. Maar de regel toont "onbekend" — omdat we de variabele nog niet hebben ingesteld.
|
||||
|
||||
Ga in Vercel naar je project → Settings → Environment Variables. Klik "Add new".
|
||||
|
||||
Variable name: `NEXT_PUBLIC_APP_ENV`. Value: `production`. **Belangrijk:** vink ALLEEN Production aan. Klik Save.
|
||||
|
||||
Tweede keer toevoegen. Zelfde naam, value `preview`, en vink ALLEEN Preview aan. Save.
|
||||
|
||||
Ga naar de Deployments tab en redeploy de laatste deploy. Of push een kleine wijziging om automatisch te triggeren. Wacht. Open productie-URL — staat nu "production".
|
||||
|
||||
Nu een feature-branch. Terug in Cursor terminal:
|
||||
|
||||
```bash
|
||||
git checkout -b chore/banner
|
||||
# kleine wijziging — bv een spatie ergens
|
||||
git add . && git commit -m "Banner aanpassing"
|
||||
git push -u origin chore/banner
|
||||
```
|
||||
|
||||
Open de Vercel deployments tab. Daar verschijnt een nieuwe deployment voor `chore/banner`. Klik de preview URL. Daar zie je "preview" staan, niet "production". Twee URL's, twee waarden, één variabele.
|
||||
|
||||
Voor `.env.local` zou je `NEXT_PUBLIC_APP_ENV=development` zetten — dat doen ze in het huiswerk.
|
||||
|
||||
Belangrijke regel: voor secrets — echte API keys, database passwords — vink je in Vercel **alleen** Production aan. In Preview gebruik je een aparte test-key. Dit voorkomt dat experimenten je productie-data raken.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 7 — Pauze (15 min)
|
||||
|
||||
`[SLIDE 12]`
|
||||
|
||||
Vijftien minuten pauze. Ik mute mijn microfoon en zet de camera uit. Tot zo.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 8 — LIVE DEMO 3: Background Agent + preview (25 min)
|
||||
|
||||
`[SLIDE 13]`
|
||||
|
||||
Welkom terug. Nu het stuk wat veel mensen voor het eerst zien: de Cursor Background Agent.
|
||||
|
||||
Open Cursor. Druk Cmd+Shift+P voor het command palette. Type "Background Agent". Eerste keer: Cursor vraagt of je je repository wilt verbinden aan de cloud. Accepteer in de browser, autoriseer GitHub.
|
||||
|
||||
Nu kun je een Background Agent starten. Type deze prompt — letterlijk over:
|
||||
|
||||
> Maak een nieuwe branch genaamd `feature/search`. Voeg bovenaan de homepage een zoekbalk toe. Wanneer iemand typt, filter dan de Pokémon-lijst op naam. Gebruik client-side state met useState. Push de branch naar GitHub en open een Pull Request met titel "Add search bar" en een korte beschrijving in de body.
|
||||
|
||||
Klik start. De agent gaat aan de slag.
|
||||
|
||||
Wat je nu kunt doen — en dit is het hele punt: iets anders doen. Een tweede Background Agent starten met een andere taak.
|
||||
|
||||
Nieuwe Background Agent, prompt:
|
||||
|
||||
> Maak branch `feature/type-filter`. Op de homepage, naast de zoekbalk: chips om te filteren op type. Type-data moet je per Pokémon fetchen via de detail-endpoint. Push de branch en open een PR.
|
||||
|
||||
Beide agents lopen nu parallel. Klik op de eerste in het Background panel — je ziet wat hij doet. Bij vragen kan hij je stoppen voor input.
|
||||
|
||||
Wacht drie tot vijf minuten. Pull-Requests verschijnen op GitHub.
|
||||
|
||||
Open de eerste PR — "Add search bar". Onderaan zie je een comment van Vercel met de preview URL. Klik. Test de zoekbalk live in de browser. Werkt? Goed.
|
||||
|
||||
Open de code-diff in de GitHub UI. Lees mee. De agent heeft toegevoegd: een useState voor de query, een input bovenaan, een filter op de lijst. Logisch.
|
||||
|
||||
Als de code goed is, klik "Merge pull request". Push gaat naar `main`. Vercel deployt naar productie. Binnen een minuut staat de zoekbalk live.
|
||||
|
||||
Hetzelfde voor de tweede PR. Review, test op preview-URL, merge.
|
||||
|
||||
Wat hier net gebeurde: in vijf minuten zijn er twee features autonoom gebouwd door agents, getest op aparte preview-URLs, en gemerged naar productie. Zonder dat ik één regel code zelf heb geschreven.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 9 — LIVE DEMO 4: GitHub Actions CI (15 min)
|
||||
|
||||
`[SLIDE 14]`
|
||||
|
||||
Laatste demo. We voegen CI toe. Lint en build moeten slagen voor elke PR.
|
||||
|
||||
Open Composer in Cursor, Cmd+I, prompt:
|
||||
|
||||
> Voeg een GitHub Actions workflow toe op `.github/workflows/ci.yml`. Bij pull request én bij push naar main: checkout, setup pnpm met `pnpm/action-setup@v4`, setup node 22 met `actions/setup-node@v4` en `cache: pnpm`, install, run lint, run build.
|
||||
|
||||
Composer maakt het bestand. Accepteer.
|
||||
|
||||
Push de wijziging:
|
||||
|
||||
```bash
|
||||
git checkout -b chore/add-ci
|
||||
git add . && git commit -m "Add GitHub Actions CI"
|
||||
git push -u origin chore/add-ci
|
||||
```
|
||||
|
||||
Open de PR op GitHub. Onder de PR zie je de "Checks" tab — de workflow draait. Wacht ongeveer twee minuten. Groene vinkjes — goed.
|
||||
|
||||
Nu de demo van een falende CI. Introduceer een typo in de code. Open `app/page.tsx` lokaal, verander een opening tag in iets fouts — bijvoorbeeld `<dvi>` in plaats van `<div>`. Commit en push naar dezelfde branch.
|
||||
|
||||
CI draait opnieuw, faalt. Rode X. Open de logs in GitHub — zie de TypeScript error.
|
||||
|
||||
Fix met Composer:
|
||||
|
||||
> Repareer de TypeScript build error in `app/page.tsx`.
|
||||
|
||||
Composer fixt. Commit, push. CI draait. Groen.
|
||||
|
||||
Laatste stap: branch protection. Ga naar GitHub repo → Settings → Branches → Add rule. Branch name pattern: `main`. Vink aan: "Require status checks to pass before merging". Selecteer de CI-workflow. Save.
|
||||
|
||||
Vanaf nu mag niemand — ook jij niet — naar main mergen zonder groene CI.
|
||||
|
||||
Merge de PR. Klaar.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 10 — Composer vs Background (10 min)
|
||||
|
||||
`[SLIDE 15]`
|
||||
|
||||
Vandaag hebben we beide gebruikt. Wanneer kies je welke?
|
||||
|
||||
Composer is je pair-programmer. Je zit erbij, hij maakt aanpassingen, je accepteert per file. Goed voor: snelle wijzigingen tijdens je werk, complex refactor waar je wilt meekijken, onbekend gebied waar je niet wilt dat een agent vastloopt.
|
||||
|
||||
Background Agent is je delegate. Je geeft een welomschreven taak, gaat iets anders doen, krijgt later een PR met preview URL. Goed voor: features met heldere specs, parallel werken aan meerdere features, tijdens een meeting iets voorbereiden.
|
||||
|
||||
Mentaal model: Composer is "samen werken". Background Agent is "uitbesteden".
|
||||
|
||||
Twee waarschuwingen voor Background Agent. Een: hij kan vastlopen op rare config — debuggen is moeilijker omdat je er niet bij was. Twee: hij verbruikt credits, dus Cursor Pro of Business is wel nodig.
|
||||
|
||||
Praktische tip: te vage prompts geven matige PR's. Wees specifiek. Noem de bestanden, beschrijf de UX, geef voorbeelden van wat je wilt. Hoe meer context, hoe beter de output.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 11 — Lesopdracht + Huiswerk (10 min)
|
||||
|
||||
`[SLIDE 16]`
|
||||
|
||||
Tijd voor jullie eigen werk. Twee delen.
|
||||
|
||||
**Lesopdracht — doe je nu, dertig minuten:**
|
||||
|
||||
Een. Eigen Pokédex-repo opzetten met dezelfde stappen als de demo: `pnpm create next-app`, Composer prompt voor de lijst, Composer prompt voor de detail-page.
|
||||
|
||||
Twee. Push naar GitHub.
|
||||
|
||||
Drie. Verbind met Vercel, deploy. Open de productie-URL en stuur de URL in de chat — ik wil zien dat het werkt.
|
||||
|
||||
Vier. Voeg de `NEXT_PUBLIC_APP_ENV` environment variable toe met een aparte waarde voor production en preview. Verifieer dat het werkt op beide URLs.
|
||||
|
||||
**Huiswerk — voor volgende les:**
|
||||
|
||||
A. Eén feature toevoegen met de Background Agent. Mijn voorstel: zoekbalk, type-filter, favorieten-systeem, of vergelijk-twee-pokemon. Open de PR, krijg de preview URL.
|
||||
|
||||
B. GitHub Actions CI toevoegen met lint en build.
|
||||
|
||||
C. Branch protection op `main` instellen.
|
||||
|
||||
D. Schrijf een `DEPLOY.md` in de root van je repo met: productie-URL, één preview-URL, en een reflectie van ongeveer driehonderd woorden over Composer versus Background Agent. Wanneer werkte welke beter? Geef één voorbeeld waar Background verbluffend goed of juist slecht was.
|
||||
|
||||
Bonus voor wie wil: vervang de Pokédex door een andere externe API. Open-Meteo voor weer, GitHub API voor jouw eigen repositories, of een free API naar keuze.
|
||||
|
||||
Inleveren via Teams, voor volgende les.
|
||||
|
||||
---
|
||||
|
||||
## BLOK 12 — Afsluiting (5 min)
|
||||
|
||||
`[SLIDE 17]`
|
||||
|
||||
Vandaag hebben we veel gedaan.
|
||||
|
||||
We hebben externe APIs leren fetchen vanuit Server Components. We hebben drie rendering modes gezien: static voor de lijst, ISR voor detail-pages, en kort genoemd hoe je dynamic of client-side zou doen. Dat is een knop die je per fetch omdraait.
|
||||
|
||||
We hebben Cursor Composer gebruikt voor synchrone wijzigingen, en Background Agent voor twee parallel-features. Verschillende tools voor verschillende momenten.
|
||||
|
||||
We hebben naar Vercel gedeployed. Productie op main, preview per branch. En het belangrijkste: environment variables per omgeving. Een variabele kan drie totaal verschillende waarden hebben, één per scope.
|
||||
|
||||
En tenslotte GitHub Actions CI. Zekerheid dat je code lint en bouwt voor de merge.
|
||||
|
||||
Volgende les is les 14: Agents. Nog een stap verder dan tool calling. LLM in een loop met tools, autonoom twintig tot vijftig stappen. We bouwen een research-agent from scratch met `ToolLoopAgent`, `stopWhen` en `prepareStep`. En we bespreken wanneer agents wel of niet de juiste keuze zijn.
|
||||
|
||||
Dat was 'm. Bedankt voor jullie aandacht. Vragen?
|
||||
|
||||
---
|
||||
|
||||
## VEELVOORKOMENDE FOUTEN — voor mezelf
|
||||
|
||||
| Probleem | Oplossing |
|
||||
|----------|-----------|
|
||||
| Vercel deploy faalt op build | Check Build Logs — meestal type-error of missende env var |
|
||||
| Background Agent doet niks | Repo niet gekoppeld aan Cursor cloud — Cmd+Shift+P → Repository Settings |
|
||||
| Preview URL toont oude versie | Hard refresh (Cmd+Shift+R), of Vercel cache invalidate |
|
||||
| Env var komt niet door | Redeploy na toevoegen var — bestaande build pakt 'm niet automatisch |
|
||||
| `process.env.NEXT_PUBLIC_*` undefined | Moet beginnen met `NEXT_PUBLIC_` om in browser te werken |
|
||||
| GitHub Actions faalt op pnpm | `actions/setup-node` MET `cache: pnpm` — anders geen lockfile-aware install |
|
||||
| Branch protection blokkeert PR | Eerst CI groen zien voor je merge |
|
||||
| Composer 'kan repo niet vinden' | Cursor verbinden met die specifieke repo via Cmd+Shift+P |
|
||||
|
||||
---
|
||||
|
||||
## TIMING-CHECK
|
||||
|
||||
| Blok | Cumulatief | Duur |
|
||||
|------|-----------|------|
|
||||
| 1. Welkom + Terugblik | 0–10 | 10 min |
|
||||
| 2. Theorie Externe APIs | 10–25 | 15 min |
|
||||
| 3. Theorie Vercel + GH | 25–40 | 15 min |
|
||||
| 4. Wat we bouwen | 40–45 | 5 min |
|
||||
| 5. Demo 1 — Composer | 45–75 | 30 min |
|
||||
| 6. Demo 2 — Vercel + env | 75–95 | 20 min |
|
||||
| 7. Pauze | 95–110 | 15 min |
|
||||
| 8. Demo 3 — Background Agent | 110–135 | 25 min |
|
||||
| 9. Demo 4 — GitHub Actions | 135–150 | 15 min |
|
||||
| 10. Composer vs Background | 150–160 | 10 min |
|
||||
| 11. Lesopdracht + Huiswerk | 160–170 | 10 min |
|
||||
| 12. Afsluiting | 170–175 | 5 min |
|
||||
| Buffer voor vragen | 175–180 | 5 min |
|
||||
|
||||
Totaal: 180 minuten.
|
||||
Reference in New Issue
Block a user