You now have auth (Lesson 10), a database (Lesson 11), relationships (Lesson 12), and file storage (Lesson 13). Time for the fourth pillar of Cloud: AI. In this lesson you bolt a Summarize this note button onto the notes app from Lesson 11 — one click, three tidy bullets, no API keys to babysit.
Part 1 · Why an AI Gateway
Wiring AI the traditional way means picking a provider (OpenAI, Anthropic, Google), creating an account, generating a key, storing it as a secret, learning that provider's SDK, and rewriting the whole thing when you want to try a different model. The Lovable AI Gateway collapses all of that into one endpoint you can call from a server function. One key (already provisioned for you), one shape, many models behind it.
LOVABLE_API_KEY. One helper. Change the model string to switch families. Usage rolls up into your Cloud account.Part 2 · The mental model
Every AI feature in your app has the same five-step shape. Memorise this and you'll never have to guess where to put the code again.
- 1Click
User clicks a button (or submits a form) in the browser.
- 2Server fn
Client calls a createServerFn that fetches whatever it needs from the DB.
- 3Gateway
Server fn sends prompt + model choice to the AI Gateway.
- 4Model
The model returns text (or structured JSON, or a stream).
- 5Save + render
Server fn writes the result back to the DB and returns it. UI updates.
Ask for a server function namedsummarizeNotethat takes anoteId, loads the note, sends its body to the AI Gateway, saves the summary onto the note row, and returns it.
Part 3 · Picking a model
The Gateway exposes several model families. You don't need to know them all — you need to know the axis they trade on: speed & cost on one end, reasoning power on the other. For 90% of app features (summaries, tags, classify, short rewrites), the small/fast model is the right default.
gemini-flash-class.gpt- or claude-class.- Default to small. Ship the feature on the fast model, only upgrade when you can point at an output that's genuinely worse.
- Match model to task. "Summarize a 200-word note" is not the same job as "refactor this file" — don't pay Opus prices for Flash-tier work.
- Model choice is a one-line change. With the Gateway you swap a string. Try two side by side before committing.
Part 4 · Mini-project — Summarize this note
We're adding a single button to each note card. Click it → the server function runs → a summary appears under the note body. Nothing else in the notes app changes.
- Reflected on launch page priorities.
- Questioned current onboarding email cadence.
- Wants to revisit both this week.
Under the hood: add a summary text column to notes, write a server function that loads the note (RLS ensures the caller owns it), calls the Gateway, and updates the row. The UI reads note.summary and renders it when present.
Add asummarycolumn to the notes table. Create asummarizeNote({ noteId })server function using the Lovable AI Gateway. Wire a Summarize button on each note card with loading and error states.
Part 5 · Prompting for reliable output
The model does what you ask. If you ask vaguely, you get vaguely. A prompt for an app feature has two parts: a system prompt (the role and rules, written once) and a user prompt (the actual content, different every call).
"summarize this: {note}"3 bullets, ≤20 words each, no preamble. User: the note.- Name the role. "You summarise notes" beats "please help." The model leans into the role.
- Pin the shape. Bullets? Word count? JSON? Say it in the system prompt, not the user prompt.
- Ban preambles. "No preamble. No 'Sure!'." Saves tokens and looks better in the UI.
- Give one example if the shape is unusual. One example is worth a paragraph of instructions.
Part 6 · Traps & debugging
- Rate limit (429) — you hit the model's per-minute cap. Back off and retry; for spikey UIs, debounce the button.
- Out of credits (402) — top up in Workspace → Usage. Surface a clear message to the user, don't fail silently.
- Empty response — usually a prompt so strict the model gave up. Loosen one constraint at a time until output returns.
- Length cutoff — long notes can blow past the output token budget. Cap the input, or ask for a shorter summary.
- Hallucinations on tiny inputs — a two-word note gives the model nothing to summarise. Guard: skip the call under N characters.
- Streaming vs single — for a button-and-wait feature, a single response is simpler. Stream when the user is watching the text appear.
- Cost creep — every click costs a fraction of a cent. Cache the summary on the row (that's why we saved it) so a second view is free.
AI cheat sheet
Quick prompts
- "Add a
summarycolumn to notes" → migration, one column. - "Create a
summarizeNoteserver function using the AI Gateway" → server fn wired toLOVABLE_API_KEY. - "3 bullets, ≤20 words each, no preamble" → system prompt that produces clean UI output.
- "Skip the call if the note body is under 40 characters" → cheap guard against hallucinations.
Model decision rules
- Default: small/fast model (Flash-class). Ship on this.
- Upgrade only when you can point at a real output that's worse than you need.
- Compare by A/B on the same input — swap the model string, keep everything else identical.
Debug checklist
- Button click does nothing → check the server fn was actually called (network tab, server logs).
- 4xx from Gateway → wrong model id, missing key, or you're calling from the client instead of a server fn.
- Summary is empty string → prompt too restrictive, or the model refused; log the raw response.
- Summary saved but UI stale → invalidate the notes query after the mutation resolves.
Sign up with my invite link and Lovable will drop 10 bonus credits into your account — enough to try everything in this course.
Claim 10 credits