BoilerPrompt

Lovable prompts

Full-stack web apps from a chat prompt, with Supabase wired in.

Try Lovable

34 prompts, every one free to copy. Jump to: App, Backend, Design, Features, Frontend, Refactor, Testing

What Lovable is good at

Lovable is a browser-based builder that turns a written spec into a working full-stack web application. You describe the product in chat, and it generates a React frontend styled with Tailwind; when the app needs persistence, auth, or server logic, it reaches for Supabase: Postgres tables, Row Level Security policies, edge functions, and storage. Every message becomes an edit to a live preview you can click through, and the project can sync to GitHub, so you can eject to your own editor when the chat loop stops being the fastest path.

Among its neighbors, v0 concentrates on React UI components rather than whole products, Bolt gives you an in-browser IDE where you edit the generated files directly, and Replit Agent builds and hosts on Replit's infrastructure. Lovable is strongest when you want a complete product, database included, without touching a terminal. It fits founders validating an idea and developers who want a credible starting point to extend.

How to prompt Lovable

Lovable rewards specs and punishes one-liners. A strong first prompt reads like a short PRD with labeled sections: what the product is, the pages, the data model, key behaviors, and the states you care about. Two hundred to three hundred words is a reasonable target; below that, the tool fills gaps with defaults you will spend messages undoing.

Always specify:

- Tables and access. Name the tables, list important columns, and say who can read and write which rows. Lovable creates Supabase migrations and Row Level Security policies from this text, and vague data descriptions produce vague schemas. - Auth boundaries. Say whether login exists and which routes sit behind it. - Empty, loading, and error states. Unprompted, you get the happy path only. - What not to touch when editing an existing app.

Iterate one feature per message and click through the preview before sending the next; stacking three requests in one message makes failures hard to attribute. When something breaks, paste the exact error text and name the screen where it happened. Put standing decisions like stack choices and styling rules into the project's Knowledge so you stop repeating them, and connect GitHub early so every change lands in version control you can diff or revert outside the chat.

All 34 Lovable prompts

App 5 prompts

Build a multi-tenant SaaS starter where teams collaborate on {{resource}}.

Auth and accounts:
- Email and password signup and login with Supabase Auth, plus password reset. After first login, an onboarding step creates a workspace and makes that user its owner.

Workspaces:
- Tables: workspaces, workspace_members (role is owner, admin, or member), invitations.
- Owners and admins invite by email; the invite link joins the workspace after signup or login. Inviting an existing member returns a clear message instead of a duplicate row.
- A workspace switcher in the top bar for users who belong to several.
- Row Level Security policies so members only read rows in their own workspaces. Write actual policies; client-side filtering does not count.

App shell:
- Public marketing page with Free and Pro tiers as static content.
- Authenticated area: a dashboard placeholder, workspace settings (rename, member list with role management, remove member, delete workspace behind a type-to-confirm dialog), and account settings for email and password.
- Billing page showing the current plan with a disabled Upgrade button; structure it so a payment provider can slot in later, without adding keys or fake checkout now.
- Leave one clearly marked extension point where {{addon}} can be wired in after launch.

Edge cases: the last owner cannot leave or be demoted, and deleting a workspace cascades its memberships and invitations.

States: loading skeletons in the shell, a friendly empty dashboard for a new workspace, error toasts on failed mutations.

To verify, I will sign up two users, invite one into the other's workspace, confirm a plain member cannot open workspace settings, and confirm nothing from workspace A renders while workspace B is active.
Build a to-do app with Supabase auth so each user only sees their own tasks.

Screens: a login and signup screen, a main list view, and a settings page for display preferences.

Data model: a tasks table with title, notes, due_date, priority, completed_at, sort_order, and user_id, with row level security so users only read and write their own rows. Add a lists table so tasks can be grouped, with a default Inbox list created on signup.

Behaviors: inline task creation from a single input at the top of the list, optimistic checkbox toggling that writes completed_at, drag to reorder within a list persisted to sort_order, and a filter bar for Today, Upcoming, and Completed. Overdue tasks show the due date in red.

Empty and error states: a first-run state offering three sample tasks, a friendly message when a filter returns nothing, and a retry banner if a write fails so the checkbox rolls back visibly.

Styling: clean single-column layout with a max width around 640px, shadcn components, a subtle strike-through animation on completion, and a dark mode toggle stored per user.

Acceptance: signing up creates the Inbox list automatically, a task checked off leaves the Today filter after refresh, reordering survives a reload, and a second account cannot see the first account's tasks from the UI or the browser console.
Build a blog with an admin CMS in one app.

Public side: a home page listing published posts newest first with cover image, title, excerpt, and tag chips, a post page at /blog/[slug] rendering markdown with code highlighting, and a tag page filtering the list. Each post page sets its document title and description from the post record.

Admin side: routes under /admin gated by Supabase auth plus an is_editor flag on a profiles table, a posts list showing draft or published status, and an editor screen with title, a slug auto-generated from the title but editable, a markdown body with live preview, a tag picker, and a cover image uploaded to a covers storage bucket.

Data model: posts with a unique slug, status, published_at, author_id, and a tags array, with row level security allowing public reads of published rows only and writes for editors only.

Behaviors: save keeps drafts private, publish stamps published_at, unpublish returns a post to draft without deleting anything, and slug collisions get a numeric suffix.

States: an empty state on the public home when nothing is published yet, a 404 page for unknown slugs, and an editor warning before navigating away with unsaved changes.

Styling: a readable measure around 68 characters for post bodies, serif headings, and quiet admin chrome so the editor feels like a document, not a dashboard.

Acceptance: a draft is invisible when signed out, publishing makes it appear without any redeploy, an unknown slug 404s cleanly, and a non-editor account cannot open /admin or write to posts.
Build a small e-commerce store with a public catalog, a cart, and Stripe checkout.

Catalog: a products table with name, slug, price_cents, inventory_count, and images in a product-images storage bucket, a grid at /shop with category filter chips, and a product page with an image gallery and a quantity picker capped at available inventory.

Cart: stored in localStorage for guests and merged into a carts table on login, a slide-over cart panel with quantity steppers per line, and a subtotal that updates on every change. Out-of-stock items in a saved cart show a notice instead of failing silently at checkout.

Checkout: an edge function named create-checkout builds a Stripe Checkout session from server-side prices, never trusting amounts sent by the client, and a webhook function records the order and decrements inventory_count only after payment succeeds. Orders land in an orders table with line items and a status field.

Account: an order history page listing past orders with status and totals.

States: an empty cart panel with a link back to the shop, a payment-cancelled return page that keeps the cart intact, and a sold-out badge on depleted products.

Styling: product imagery dominant, a whitespace-heavy grid, and price typography consistent across card, product page, and cart.

Acceptance: adding beyond inventory is blocked at the picker, a completed test payment produces one order row and reduces inventory exactly once even if the webhook retries, guest carts survive a refresh, and a cancelled checkout creates no order.
Build a booking app where providers publish availability and clients reserve slots.

Roles: a role field on profiles distinguishing provider from client, with separate home screens after login.

Provider side: a weekly availability editor with day rows and add-window buttons creating availability_windows rows holding weekday, start_time, end_time, and slot length, plus a blocked_dates table for one-off days off. A bookings list shows upcoming appointments with a cancel action.

Client side: a provider page with a week view generated from the windows minus existing bookings and blocked dates, rendering every open slot as a button in the client's local timezone with the provider's zone noted. Choosing a slot opens a confirmation showing date, time, and duration before the insert.

Double-booking: the bookings table carries a unique constraint on provider_id plus starts_at, the insert catches the conflict error, and the client sees a slot-just-taken message with the calendar refreshed.

Cancellation: clients may cancel until a cutoff-hours value the provider sets, after which the button is disabled with the reason shown. Cancelled slots reopen immediately.

Timezones: store starts_at as timestamptz, never as separate date and time strings, and render in the viewer's zone everywhere.

States: providers with no windows see setup guidance, clients see a no-availability message with next-week navigation, and past weeks are read-only.

Acceptance: two browsers booking the same slot at once produce one booking and one polite conflict, a client in one timezone viewing a provider in another sees converted times, and cancelling reopens the slot on both calendars.

Backend 5 prompts

Build a REST API for managing {{resource}}, implemented as Supabase Edge Functions with a minimal admin page for exercising it.

Endpoints:
- POST /{{resource}}: create a record, validate required fields, return 201 with the created row.
- GET /{{resource}}: list with pagination (limit and offset params, default 20, max 100) and a sort param.
- GET /{{resource}}/:id: return the record or a 404 JSON body.
- PATCH /{{resource}}/:id: partial update, reject unknown fields with 400.
- DELETE /{{resource}}/:id: soft delete via a deleted_at column; exclude soft-deleted rows from every read.

Data model: a {{resource}} table in Postgres with id (uuid), created_at, updated_at, deleted_at, plus whatever fields fit {{resource}}. Propose the columns and wait for my confirmation before running the migration.

Behavior:
- Require a Supabase auth JWT on every endpoint; respond 401 without one.
- Scope rows to the authenticated user with Row Level Security policies, not only WHERE clauses.
- Errors are JSON: { "error": { "code", "message" } } with correct status codes (400 validation, 401 auth, 404 missing, 500 unexpected).
- Handle malformed JSON bodies and invalid uuids without the function crashing.

These endpoints must be callable with curl from outside the app; do not implement them as supabase-js calls inside React components.

Admin page: list records, a create form, and a panel showing the raw status code and JSON of the last request.

When done, print each endpoint with an example curl command against the deployed function URLs so I can verify all five paths.
Stand up a GraphQL API in this project as a single Supabase edge function named graphql, with GraphQL Yoga bundled into the function.

Schema: a {{resource}} type with id, name, status, and created_at, a paginated list query accepting limit, cursor, and a status filter, a single-record query by id, and mutations for create, update, and delete.

Resolvers: read and write through a Supabase client created from the caller's Authorization header so row level security still decides what each user can touch. Never use the service role key inside resolvers.

Errors: throw typed GraphQL errors with codes UNAUTHENTICATED, NOT_FOUND, and BAD_INPUT instead of generic 500s, and surface field-level validation messages for missing required inputs.

Frontend: add a small /playground page with a query editor textarea, a run button, and a formatted JSON result pane so I can exercise the endpoint without leaving the preview.

Hardening: handle CORS for the app origin only, and reject any query nested deeper than four levels to stop abusive queries.

Acceptance: the list query returns a cursor that fetches the next page, a mutation without a signed-in session comes back UNAUTHENTICATED, deleting a record owned by another user returns NOT_FOUND rather than confirming it exists, and the playground shows errors inline instead of crashing.
Add JWT-based authentication to this app using Supabase Auth, covering the client, the database, and the edge functions.

Flows: email and password signup with a confirmation step, sign in, a magic link option, password reset, and sign out. On signup, insert a row into a profiles table keyed to the new user id.

Route protection: redirect signed-out visitors from any authenticated route to /login with a return-to parameter, and send signed-in users away from /login. Keep the session in the Supabase client so a refresh does not log anyone out, and refresh tokens silently instead of bouncing to login when the access token expires.

Database: enable row level security on every user-owned table and write policies against auth.uid(), leaving no table with policies disabled.

Edge functions: each function reads the Authorization header, verifies the JWT through the Supabase client, and returns 401 with a JSON error body when it is missing or invalid. No function may fall back to the service role for user-scoped reads.

UI states: a loading gate while the session restores so protected pages never flash before redirect, inline errors for wrong credentials, and a resend link on the confirmation notice.

Acceptance: an expired session on a protected page recovers without a visible logout, calling an edge function with no header returns 401 not 500, password reset works end to end from the email link, and querying another user's rows from the browser console returns nothing.
Design and apply the Supabase Postgres schema for a {{resource}} app before building any screens, and show me the SQL as migration files rather than ad hoc table edits.

Tables: profiles keyed to auth.users, a {{resource}} table with owner_id, name, status, and timestamps, a comments table referencing it with cascade delete, and a join table for tags with a composite primary key.

Types and constraints: a Postgres enum for status instead of free text, not-null on every foreign key, a check constraint keeping name non-empty, and unique constraints wherever duplicates would corrupt meaning, one tag name per user for example.

Defaults and triggers: created_at defaulting to now, an updated_at column maintained by a trigger, and a trigger creating the profiles row when a user signs up.

Indexes: btree on every foreign key column, plus a composite index matching the main list query, owner_id with status and created_at descending.

Row level security: enabled on every table with select, insert, update, and delete policies written against auth.uid(), and nothing that depends on the service role.

Seed: a script inserting two demo users' worth of data so future screens have something to render.

Acceptance: the migrations run from scratch without errors, show me a query listing all tables with RLS enabled, demonstrate that user one cannot select user two's rows, and confirm the updated_at trigger fires on an update. List every migration file you created.
Build a file upload flow backed by Supabase Storage with server-side validation.

Bucket and paths: a private bucket named user-files, objects written under a path prefixed with the uploader's user id, and storage policies allowing each user to read, write, and delete only inside their own prefix.

Upload path: an edge function named request-upload checks the declared MIME type against an allow list of pdf, png, and jpeg, enforces a size ceiling, and returns a signed upload URL plus the final path. The browser uploads directly to storage with that URL, then calls a confirm step that inserts a row into a files table with name, size, mime, and path.

UI: a drop zone that also accepts click-to-browse, a per-file progress bar, image thumbnails after upload, a generic icon for pdfs, and a delete action that removes both the storage object and the files row.

Validation edge cases: a file renamed to fake its extension gets caught by checking actual content type at the confirm step, zero-byte files are rejected with a message, and duplicate names receive a suffix rather than overwriting.

Failure states: an expired signed URL triggers a fresh request automatically, a mid-upload network drop leaves a retry chip on the file card, and a scheduled function cleans storage objects that have no matching files row.

Acceptance: a signed-out call to request-upload returns 401, user A cannot fetch user B's file even with the raw path, an oversized file is refused before any bytes move, and deleting a file makes its old signed URL stop working.

Design 14 prompts

Add a hero to the very top of my landing page for {{product}}. Change nothing below it — this brief covers one section only.

Build it as a full-width, left-aligned stack rather than split columns:
- Announcement pill: a small rounded chip carrying a short news-style line derived from {{product}} (a launch, a version, an integration) plus a chevron; it should be clickable later.
- Headline: verb-first, eight words or fewer, stating what {{audience}} gets done with {{product}}. Never use the product name as the headline.
- Support line: about 20 words translating the headline into the concrete mechanism, written to {{audience}} in second person.
- Actions: the primary button reads "{{cta}}" and should be built so I can later connect it to the signup form or auth flow Lovable manages; beside it, a plain text link with an arrow for the demo.
- Trust microcopy: one line directly under the buttons — a star rating plus a count, or a no-card-required style note. Pick one, not both.
- Media band: a wide, short browser-frame placeholder, roughly 280px tall, spanning the content width at the bottom of the section.

Vertical rhythm: 72px top padding, 16px pill-to-headline, 20px headline-to-support, 28px before the buttons, 12px down to the microcopy, 48px to the media band, 64px bottom padding. The full section, media band included, must be visible on a 1366x768 screen without scrolling.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

On mobile: the pill truncates to one line, the two actions stack with the primary on top, and the media band crops to a 4:3 center cut.

After building, verify: (1) no scrolling is needed at 1366x768 to see the media band, (2) the primary action is a real button element ready for a click handler, (3) the microcopy stays on a single line at desktop width, (4) the published preview matches the editor preview. Then publish so I can test on a phone.
Ask Lovable to add a testimonial wall to the {{product}} landing page — a proof section placed right after the feature block, built for {{audience}} to skim, with carousel motion reserved for the small-screen fallback.

Build it in three layers:
- Layer 1, logos: a slim strip labelled "Teams using {{product}}" with six grayscale logo placeholders. Keep it quiet — its job is to prime the quotes below.
- Layer 2, the featured quote: one testimonial promoted above the rest, set in display-size type across about two-thirds of the container, with a headshot and a full attribution line (name — role, company). Pick the quote that names a measurable before/after.
- Layer 3, the wall: a 3-across grid of nine quote cards at staggered heights, each holding quotation then attribution. Write nine distinct voices from segments of {{audience}} — a converted skeptic, a numbers person citing a metric, a team lead describing rollout, and so on. No two quotes may share an opening word, and none may be generic praise.

Store the testimonials in a structured list in the app — or a small table if the project already uses Lovable's database — so entries can be added without touching layout. End the section with a short line ("Join them" or equivalent) and a button labeled "{{cta}}" hooked to the same destination as the hero button.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Spacing: roughly 6rem vertical padding; 2rem between the three layers; 1.25rem card gap. On phones, layers 1 and 2 stack unchanged while the wall converts to a horizontally swipeable card row with snap points and a "1 of 9" counter.

Before publishing, confirm: nine attributed cards render from data rather than hardcoded markup; the featured quote is visually dominant; the mobile view swipes with snap; the "{{cta}}" button and the hero button share a destination; no quote repeats another's opening word.
Add an FAQ section to the {{product}} landing page you're building in Lovable, placed after testimonials and before the closing CTA. It exists for {{audience}}, so treat it as objection handling, not documentation.

Question set — derive seven questions from whatever would stop {{audience}} from signing up for {{product}}: price justification, time to first result, whether existing tools and data carry over, contract and cancellation terms, security, who it is not for, and how fast support responds. Write answers as if a founder replied personally: 2–4 sentences, one specific number or fact in each, no hedging.

Accordion behavior:
- One open at a time: expanding a row collapses the previous one, so the page never becomes a wall of open text. Animate the collapse at a duration consistent with the motion spec below.
- Every question row is a button element carrying aria-expanded, and the panel it controls is labelled by the question — the section must work with a keyboard (Tab between rows, Enter to toggle) and a screen reader out of the box.
- The first item starts open on page load so visitors see the interaction pattern.

Layout: a narrow centered column (about 720px max) — an h2 in the territory of "What {{audience}} ask before switching", a one-line subhead, then the stacked rows divided by thin rules. After the last row, add a short line with a button labeled "{{cta}}" for readers whose question wasn't answered — wire it to the same action as the hero button so both count as one goal in the deployed app.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Spacing: about 5rem of padding above and below the section, 1rem internal padding per row, answers indented to align with the question text rather than the chevron. On phones, keep the full-width column and enlarge row padding so taps don't misfire.

Check before deploying: exactly one row open at any moment; the first row is open on load; Enter toggles the focused row; the "{{cta}}" button triggers the same flow as the hero CTA; all seven answers contain a concrete fact.
Build a portfolio site for {{product}} whose job is getting {{audience}} to start a conversation — so treat the contact form as a first-class feature. Store submissions in a messages table (name, email, project_type, budget_band, message, created_at) and tell me where to read them. One page, deployed when done.

Sections in order:
1. Hero — the name or studio as the largest element on the page, one sentence beneath it naming the discipline and the clients served, and a single button that scrolls to contact.
2. Selected work — five projects in an alternating editorial layout (image left, text right, then flipped), each with title, client type, a two-line result summary, and a link placeholder; hovering an image lifts it slightly and reveals a "view case" label.
3. About — a short band: a three-sentence bio plus one row of past clients or employers as plain text, no logo wall.
4. Capabilities — a two-column list of services with the concrete deliverable named for each ("brand identity: logo system plus usage guide").
5. Contact — the wired form: fields matching the table above, budget as a select, required-field checks, and a success state that thanks the sender by name and promises a reply window.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

- Vertical rhythm: 112px between sections on desktop, 64px on mobile; inside a section nothing tighter than 16px or looser than 48px.
- Mobile: the alternating rows become image-over-text cards, and the budget select stays a native control.

The primary call to action is "{{cta}}"; put that text on the hero button and the form submit, nowhere else.

Verify after building: a test submission appears in messages with all six fields; an empty required field blocks submit and marks only that field; the success state prints the sender's name; and the deployed URL takes a submission end to end.
Create a one-page waitlist site for {{product}} — a pre-launch page whose only job is collecting emails from {{audience}}. Wire the form to a real database table (waitlist: id, email, created_at, referral_code) so signups persist, and get the page ready to deploy as-is.

Page order:
1. Hero: eyebrow "Launching soon", a headline promising the concrete result {{product}} delivers, a one-sentence subhead on why joining now beats waiting, and the email field with its button immediately under.
2. Teaser trio: three blocks in a row — "What you'll get" (three launch features as bullets), "Who it's for" (one line naming the segments), and "Why now" (a first-cohort-access scarcity line).
3. Signup section: the form again with a supporting line above it; on submit, insert the row, then replace the form with a confirmation card showing a queue number derived from the row count and a copyable referral link built from referral_code.
4. FAQ: four pairs — when it launches, launch pricing, whether emails are shared, how referrals move the queue.
5. Footer: contact email plus a one-line privacy note about email use.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Rhythm and behavior:
- 96px vertical section padding on desktop, 64px on mobile; blocks inside sections sit on a 24px gap grid.
- Validate the email client-side before insert; catch duplicates gracefully with "you're already on the list" plus their existing number.
- On phones the teaser trio stacks single-column and the header collapses to the logo plus one anchor link to the form.

The primary call to action is "{{cta}}"; use that exact text on both submit buttons and the header anchor.

After building, verify: a test email lands in the waitlist table; the same email twice shows the duplicate message and adds no second row; the confirmation card shows a number and a working copy button; and the deployed page accepts a signup in production.
Create a single-page marketing site for {{product}} and make it deploy-ready. The audience is {{audience}}, and every headline should name their problem or their win — no generic feature talk anywhere on the page.

Page anatomy in order:
- Fixed navigation: logo, three anchor links (Features, Pricing, FAQ) that smooth-scroll, and the CTA button.
- Hero: eyebrow label naming the category {{product}} belongs to, an H1 stating the single biggest outcome, a subhead of at most two sentences, the CTA button, and one line of reassurance microcopy beneath it.
- Logo bar: six muted client logos with a caption counting teams or users.
- Alternating feature rows: three rows, image one side and copy the other, sides swapping each row; each row gets a short label, an H3, one paragraph, and an inline text link.
- Product screenshot framed inside a soft container, caption underneath.
- Pricing teaser: two tiers side by side — name, price, five bullet features, button — with a badge on the recommended tier.
- FAQ: five expandable questions {{audience}} would genuinely ask before paying.
- Closing CTA section, then a footer with legal links and social icons.

Wire the hero and closing CTA buttons to a working email-capture form stored in the built-in database (table: leads, columns: email, created_at) with an inline success state on submit — create the table and connect the form.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Rhythm and responsive rules:
- Uniform 96px vertical padding per section on desktop, 64px on mobile; one consistent max-width container throughout.
- On mobile, feature rows always show copy first then image, and pricing tiers stack with the recommended tier on top.

The primary call to action is "{{cta}}" on every button that captures an email.

After building, check that: submitting a valid email writes a row to leads and shows the success state; an invalid email is blocked with an inline message; anchor links land with the section heading visible below the fixed nav; the deployed preview loads with no console errors.
Create a one-page site in Lovable for {{product}}, aimed at {{audience}} — an agency page where the work does the talking and the contact form actually submits.

Page order:
1. Hero — a two-line claim built from {{product}}'s specialty (what they make, who wins from it), with a thin strip of 5 client names underneath.
2. Featured case — one project at full width: large image area, client name, the problem in one sentence, the result as a number.
3. More work — 4 additional projects in a 2-up grid, each with title, category tag, and a single result stat.
4. Capabilities — an accordion of 4 service groups; each opens to a 2–3 sentence description plus 3 deliverable bullets.
5. Process — 3 phases (shape / build / ship — rename to fit {{product}}'s discipline) with a week-range and an outcome per phase.
6. Studio — a 2-sentence manifesto beside a team grid (photo placeholder, name, role) for up to 6 people.
7. Contact — a working form (name, email, budget range select, message) with inline validation; store submissions in Lovable's database and send an email notification on submit. Beside the form, a direct email address and a response-time promise.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Rhythm and responsive behavior:
- Keep section spacing on one scale: 96px desktop, 56px mobile; accordion rows use 20px internal padding.
- On phones the featured case stacks image-over-text, the team grid drops to 2 columns, and the budget select becomes a full-width control.

The primary call to action is "{{cta}}" — a button in the hero and the label on the contact form's submit. When the page works in preview, deploy it and give me the live URL.

Before handing it back, verify: the form rejects an empty email and writes a row to the database; all 5 work entries show a stat; the accordion opens one panel at a time; nothing overflows at 390px; the deployed URL loads.
Build a product landing page in Lovable for {{product}}, aimed at {{audience}}. This is a one-product page, not a store: everything drives toward a single purchase action, and the page should deploy at the end.

Section order:
1. Hero buy section — an image gallery (5 images, click-to-swap main) on one side; on the other, the product title, a benefit-led subhead answering "what changes for me", review stars with a count, the price, and the purchase button with a reassurance line under it (delivery estimate plus returns policy).
2. Social proof bar — press or rating badges in one row.
3. Why it works — 3 benefit sections, each with a headline in the buyer's words, a short paragraph, and a visual slot; alternate which side the visual sits on.
4. Details — a tabbed block: Specs, In the box, Shipping, and an FAQ tab with 4 questions specific to buying {{product}}.
5. Reviews — average rating, 6 entries with reviewer name, stars, and text, plus a "load more" that reveals 6 additional entries.
6. Final offer — the price restated, the strongest benefit line, guarantee terms, and the purchase button again.
7. Sticky mobile buy bar — on phones only, a bottom-fixed bar with price and the purchase button.

Wire the purchase button to a checkout placeholder route and log each click to the database so I can see conversion counts. In Final offer, add an email field ("get 10% off") that validates and stores addresses.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Spacing and responsive:
- Sections separated by 88px desktop, 52px mobile; tab content keeps a fixed min-height so switching tabs never jumps the page.
- On phones the gallery becomes swipeable and the hero stacks gallery-first.

The purchase action reads "{{cta}}" on every buy button. Deploy when preview passes and give me the URL.

Verify: buy clicks write rows to the database; the email capture rejects invalid addresses and stores valid ones; the mobile bar shows only under 768px; switching tabs causes no layout shift; the deployed page loads over HTTPS.
Add a custom 404 screen to my {{product}} app — a single viewport-height page that turns a dead end into a recovery moment for {{audience}}. Register it as the catch-all route so any unknown URL lands here, and make sure it responds with an actual 404 status.

Compose it as a split layout:
- Left, 60% width: a short stack — small {{product}} wordmark, an error headline written in the product's voice (playful but useful, hinting at what the visitor was probably looking for), one supporting sentence, then two recovery paths: the primary button and a text link that goes back to the previous page via history.
- Right, 40% width: a decorative panel that visualizes "lost" in a way that fits the brand — an abstract composition using the palette's accent tones, never clip art.

Below the buttons, add a compact "Were you looking for one of these?" list: the four most useful pages, each with a one-line description.

Make the page earn its keep: log every 404 hit to a broken_links table (path, referrer, timestamp) using the built-in database, and include a one-field "Report this link" form that flags the matching row when submitted, swapping to an inline thank-you state.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Rules:
- The whole page fits 100vh on desktop; internal spacing uses 12/20/32px steps, and no gap between siblings exceeds 32px.
- On mobile, the decorative panel shrinks to a slim banner above the text stack and the page may scroll naturally.

The primary call to action is "{{cta}}" on the main recovery button.

After building, confirm: visiting a garbage URL renders this page with a 404 status; a row appears in broken_links with the correct path; submitting the report form flags that row and shows the thank-you state; the desktop layout fits 1280x800 without scrolling.
On the landing page you already have in Lovable for {{product}}, insert a pricing section directly after the feature grid — this brief covers only that section, aimed at {{audience}}, not a separate pricing page.

Structure it as:
- Header block: small caps label, then an h2 that states what a customer gets for the money (derive it from {{product}}'s core promise), then a one-line subhead addressed to {{audience}}.
- Billing toggle: a two-state control, "Monthly" and "Yearly (2 months free)". Store the state once at section level and drive all three prices from it so a single tap flips everything.
- Tier row: three cards — Starter, Growth, Scale. Growth is the recommended plan: give it a "Recommended" tag, a slightly stronger card treatment, and a touch more height; the other two stay quiet.
- Card contents in order: plan name, who it's for in under ten words, price plus unit, divider, feature bullets, button. Starter shows its full feature list; Growth and Scale show "All of Starter/Growth, plus" and 3–4 additions only. No comparison table inside this section — link out to one if it exists.
- Per-tier buttons: Starter and Scale get their own verbs; Growth's button reads "{{cta}}" and should be wired to the app's real signup flow so clicking it works in the deployed preview, not just visually.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Rhythm and responsiveness:
- Keep roughly 96px of vertical padding around the section and 24px gaps between cards; inside cards use one consistent spacing step.
- On phones, cards stack with Growth on top and the toggle becomes full-width.

After you build it, check that: toggling billing changes all three prices; only Growth carries the recommended treatment; the "{{cta}}" button navigates to signup; the section's h2 doesn't compete with the page hero; nothing above or below the section shifted.
Add a bento grid section to my existing Lovable landing page for {{product}}, directly below the hero. Leave the hero and everything beneath the new section exactly as they are.

Header block above the grid: an overline word, then a headline of six to eight words stating what {{audience}} can stop doing once they have {{product}}. Center both, with 48px between header and grid.

Grid definition — 3 columns, five cells, 20px gaps, one message per cell:
- A: spans 2 columns and 2 rows. The core capability, shown rather than told: a framed interface-snippet placeholder plus a two-line explanation.
- B: 1 column, 2 rows, tall. A single metric with a simple sparkline or bar placeholder and a one-line caption tying the number to {{audience}}.
- C and D: 1x1 each. Two supporting features, each as icon, four-word title, one sentence. If a feature needs a second sentence, it is two features — split or cut.
- E: 1x1. A linked card labelled "{{cta}}" pointing at the live demo or signup route; Lovable should wire this to a real route now, not a dead href.

Cell treatment: 24px interior padding, the same corner radius on every card, captions bottom-anchored in A and B.

Vertical rhythm: 96px of section padding above and below; the section background may differ from the page background, but the container width must match the hero's.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Mobile: one column in the order A, B, E, C, D — the action card moves up so it is never stranded at the bottom of a long stack.

After building, verify: (1) no card overflows or clips its content at desktop and phone widths, (2) the E card navigates to a real route in preview, (3) A reads as the obvious anchor — the first card the eye lands on, (4) container edges align exactly with the hero above. Publish once all four pass.
Add a footer section to the existing landing page for {{product}} in this Lovable project, replacing whatever placeholder footer is there now, and make it earn its place. Wire the newsletter form for real — store submissions in a subscribers table and show an inline success state — because {{audience}} will judge the product by whether small things work.

Four stacked layers:
- Capture: a heading naming the concrete thing subscribers get from {{product}} (a weekly teardown, release notes, a template drop — derive it), an email field, and a quieter-than-primary submit button. Directly beneath, one sentence pointing back to the main offer with "{{cta}}" as its anchor text.
- Navigation: link columns grouped by reader intent — evaluate (pricing, comparisons), learn (docs, blog), trust (about, security, contact). Pick 3-4 groups that fit {{product}}; plain-word headings.
- Legal: a single row with the copyright line, privacy, terms, and social icons sized to the small text, not larger.
- Optional: the product name oversized and bleeding off the bottom edge at whisper contrast, only if the style block below suits it.

Form behavior: validate email format client-side, disable the button while submitting, swap the form for a one-line confirmation on success — no page reload.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Rhythm and responsive rules:
- Same top padding as the page's other sections (about 6rem), then tighten: 3rem between layers, 1rem inside each.
- On phones: layers stack full width, link groups go two columns, and the email field stays within the first screen of the footer.

After building, verify: a test email appears in the subscribers table, the success state renders inline, link group headings are specific to the product, the legal row is one line on desktop, and the footer background differs enough from the section above that the boundary is visible.
My Lovable landing page already has a hero for {{product}} — headline, buttons, maybe an email field. Add an animated background layer behind that hero without rewriting any of its content. This task touches only the hero's container and adds one layer; everything else on the page stays as it is.

Layering: give the hero container relative positioning with hidden overflow, insert the effect as an absolutely positioned full-bleed div stacked beneath the existing content, and set pointer-events to none on it so buttons and inputs keep working — Lovable heroes often carry a signup form, and the layer must never intercept a click or a focus.

Prefer CSS-only animation here: two or three large, heavily blurred gradient shapes on looping keyframes if the visual direction reads soft; a slowly panning geometric line pattern if it reads stark or editorial; fall back to a canvas particle field only for genuinely technical, dark directions, capped at 60 particles.

Non-negotiables:
- Animate transform and opacity only — nothing that triggers layout.
- A prefers-reduced-motion media query pauses every animation and shows the static arrangement.
- The area behind the headline and the primary button labelled "{{cta}}" stays calm, so copy read by {{audience}} at a glance never fights the effect; add a soft scrim if contrast dips.
- Keep roughly 64px of visual quiet around the copy block; shapes drift around it, never through it.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Motion sets the tempo: quieter settings mean fewer shapes moving shorter distances more slowly.

On phones, drop to two shapes at most and slow the loop — dense motion feels frantic on a small screen.

Before publishing, verify: (1) every hero button and field still clicks and focuses, (2) enabling reduced motion in the browser stops all movement, (3) headline contrast holds over the brightest moving shape, (4) the published site animates exactly like the editor preview. Then publish and check once on a phone.
Insert a feature grid section into the {{product}} landing page in this Lovable project, directly after the hero, leaving every other section untouched — this is a surgical addition, not a rebuild.

From the top:
1. Header block: an eyebrow of 2-3 words naming the category, a headline stating the outcome {{audience}} is buying (not a list of nouns), and one supporting sentence. Match the hero's alignment; do not introduce a second alignment system.
2. The grid: six equal cards, three across on desktop. Deliberately not a bento — no card spans two columns, no featured tile, no mosaic. Uniform cells build a scan rhythm; mixed spans build hierarchy, and this section's job is enumeration, not argument.
3. Under the grid: a single centered sentence inviting the next step, with "{{cta}}" as the linked text.

Card recipe, identical for all six:
- Icon on top — one library, one size, and all six either enclosed in matching rounded containers or all bare. Mixed icon treatment is the clearest tell of a rushed grid.
- Title: the capability in 2-3 words.
- Body: one line answering "so what?" for {{audience}} — lead with the result ("Know which invoice is late before the client does"), mention mechanism only if space remains. Derive all six from what {{product}} actually does; no two bodies may open with the same verb.

Hover: the full card responds — background tint or a 2px lift, pick one and apply it consistently; pointer cursor only if cards truly link somewhere.

Visual direction:
{{style}}

Palette: {{palette}}
Typography: {{type}}
Motion: {{motion}}

Spacing and mobile:
- Copy the vertical padding of the adjacent sections so the insertion is seamless; 3rem header to grid; 1.5rem grid gap.
- Phones: single column, icons one step smaller, and bodies rewritten to hold one or two lines rather than wrapping to three.

Verify after building: the new section sits between the hero and the section that used to follow it, both unchanged; all six cards match height at 1440px and 768px; no card spans columns; each body opens with a distinct verb; hover covers whole cards.

Features 4 prompts

Add search so users can find {{resource}} records by typing.

Backend:
- Use Postgres full-text search in Supabase: a tsvector column on the {{resource}} table covering its name and description fields, a GIN index, and a trigger keeping the column current on insert and update. Do not fetch all rows and filter them in JavaScript.
- Sanitize the query text so punctuation or stray quotes cannot break the tsquery.

UI:
- A search input in the app header, focusable with the / key, showing a dropdown of the top 8 matches. Arrow keys move the highlight, Enter opens the record, Escape closes.
- Debounce keystrokes by roughly 300ms and discard out-of-order responses so a slow early request cannot overwrite a later query's results.
- A full results page at /search?q= listing all matches with matched terms highlighted, reached by pressing Enter with the input focused.

States and edge cases:
- Under 2 characters: show a hint, run no query.
- Zero matches: say so plainly, then offer close partial matches using an ilike fallback.
- Search must respect existing Row Level Security and never return rows the current user cannot already open.
- An empty q on the results page redirects home.

Match the current header and list styling; introduce no new visual language.

To verify: seed several records sharing a distinctive word, search it, confirm the dropdown and results page agree, then log in as a second user and confirm the first user's private rows never appear in their results.
Add an LLM chatbot to this app as a slide-over panel opened from a button in the header.

Backend: an edge function named chat that reads the provider API key from a Supabase secret, forwards the conversation, and streams the reply so text appears token by token in the panel. Keep the system prompt in a chat_settings table so I can edit it from an admin screen without redeploying.

Data model: conversations and messages tables keyed to user_id with row level security, storing role, content, and token counts when the provider returns them.

Behaviors: enter sends, shift-enter inserts a newline, a stop button aborts the stream, and the last twenty messages of the active conversation travel as context. New chat starts a fresh conversation, and a sidebar lists past conversations titled by their first message.

States: a disabled composer with an explanatory notice when the secret is missing, a retry link on provider timeouts, and a skeleton bubble while the first tokens arrive.

Styling: user messages right-aligned in a filled bubble, assistant messages left-aligned with a copy button, markdown rendered with proper code blocks.

Acceptance: replies stream rather than arriving in one block, refreshing mid-conversation restores history from the messages table, aborting a stream keeps the partial text in place, and a second signed-in user cannot read another user's conversations.
Add transactional email notifications to this app through a single edge function named send-email that talks to Resend using an API key stored as a Supabase secret.

Events to wire: a welcome email after signup confirmation, a notification when someone comments on a record you own, and a weekly digest sent by a scheduled function that skips users with nothing to report.

Preferences: a notification_settings table with a per-user boolean for each event type, defaulted on, editable from a settings screen with instant saves. Every email footer carries an unsubscribe link containing a signed token that flips the matching boolean without requiring login.

Reliability: log every attempt to an email_log table with recipient, template, status, and provider error text, retry a failed send once, and never let a failed email break the user-facing action that triggered it. Posting a comment must succeed even when the notification fails.

Templates: a shared header and footer, plain readable HTML with a single button per message, and a preview route under /admin/emails that renders each template with sample data.

States: the settings screen confirms each toggle save inline, and the admin preview shows a clear notice when the Resend secret is missing instead of rendering a blank page.

Acceptance: toggling comment emails off stops that type while the digest still arrives, the unsubscribe link works from a logged-out browser, email_log holds a row with status for every attempted send, and deleting a user stops all sends to that address.
Add CSV import and export for {{resource}} records to this app.

Import flow: an Import button on the {{resource}} list opens a dialog with a drop zone, the file parses in the browser, and a mapping step shows my CSV headers beside selects for each target column, with obvious names pre-matched. A preview table then shows the first rows with invalid cells highlighted and a count of rows that will be skipped.

Validation: required columns enforced before the confirm button enables, dates accepted in a few common formats and normalized to ISO, numbers stripped of currency symbols, and duplicate detection against an existing unique field with a choice to skip or update.

Write path: inserts batched through the Supabase client in chunks so large files do not stall, a progress bar advancing per batch, and an import_runs table recording file name, row counts, and a JSON list of skipped rows I can download afterward.

Export: an Export button that respects the currently applied filters and sort, writes the visible columns to a CSV named with today's date, quotes fields containing commas, and prefixes a BOM so spreadsheet apps detect the encoding.

Edge cases: a file with a BOM, quoted fields containing embedded newlines, a header-only file, and a completely empty file must each produce a clear message rather than a crash.

Acceptance: importing the exported file back produces zero new rows when update-on-duplicate is chosen, skipped rows appear in the downloadable report, and a malformed file never leaves partial data behind, either the batches complete or the report states exactly what landed.

Frontend 4 prompts

Build an analytics dashboard for an app that tracks {{resource}}.

Layout: fixed left sidebar (Overview, {{resource}}, Reports, Settings), a top bar with a date range picker (presets for last 7 days, last 30 days, and custom) and a user menu. Main area on a 12-column grid.

Overview page:
- Four stat cards: total {{resource}}, count added this period, percent change versus the prior period with a signed value, and a fourth card labeled Placeholder that I will define later.
- A line chart of daily counts across the selected range and a bar chart of the top five categories, both using Recharts inside responsive containers with explicit heights.
- A table of the 20 most recent records: sortable columns, a status badge, a row action menu, and pagination beyond 20 rows.

Data: create a Supabase table and seed roughly 90 days of plausible demo rows so every card and chart renders from real queries, not hardcoded arrays. Changing the date range must refetch and update every widget on the page.

States: skeleton loaders while queries run, an empty state with one line of explanation when the range has no data, and an inline retry button on query failure.

Styling: neutral grays with a single accent color, generous whitespace, no gradients. Works at 1280px wide; on mobile the grid collapses to one column and the sidebar becomes a drawer.

Skip auth for now. When finished, list which component reads from which table and column so I can point them at production data later.
Build a landing page for a developer tool called Relay that syncs environment variables across machines.

Sections in order: a hero with a one-line value statement, a subline, and a primary Get Early Access button, a three-step How It Works row, a feature grid of six cards titled with short verbs, a single quote block, and a closing call to action above a minimal footer.

Waitlist: the hero button scrolls to an email capture form that writes email, referrer, and created_at to a waitlist table in Supabase, blocks duplicate emails with an already-signed-up message backed by a unique constraint, and swaps the form for a success state on submit.

Behaviors: a sticky header that gains a bottom border after scrolling, smooth scrolling to section anchors, and a mobile menu that collapses the nav into a sheet.

States: inline validation for malformed emails before any insert, and a fallback message with a mailto link if the insert itself fails.

Styling: dark background, high-contrast type, one accent color used only on buttons and links, generous vertical spacing between sections, and monospace accents on the product name to match the developer audience. No stock illustrations.

Acceptance: the page renders at phone width with no horizontal scroll, submitting the same email twice produces the duplicate message and exactly one row, every image carries alt text, and heading levels descend from a single h1 without skipping.
Build a pricing page at /pricing with three tiers named Hobby, Team, and Scale.

Layout: three cards in a row on desktop, stacked at phone width, with the Team card visually promoted by a border, a badge, and slightly larger scale. Above the cards, a monthly and annual toggle rewrites prices in place and shows the annual saving as a small note, with no reload and no layout shift.

Content per card: the price, a one-line description of who the tier is for, a feature list where included items are checked and excluded items are dimmed rather than hidden, and a call-to-action button. Hobby routes to signup, Team routes to signup with a plan query parameter, and Scale opens a contact dialog that writes name, email, and message to a sales_leads table in Supabase.

Below the cards: a comparison table with feature rows and tier columns, a sticky first column when it scrolls horizontally at narrow widths, and a short FAQ accordion with five entries.

Edge cases: the toggle state persists in the URL hash so a shared link opens on annual, the contact dialog validates the email before insert and confirms the send, and keyboard users can operate both the toggle and the accordion.

Styling: prices large and baseline-aligned across cards so the tiers scan in one glance, a restrained palette with the accent reserved for the promoted tier and the buttons.

Acceptance: switching the toggle changes all three prices at once, the comparison table scrolls inside its own container rather than the page, and submitting the Scale dialog creates exactly one sales_leads row.
Build a data table screen for {{resource}} rows backed by Supabase.

Columns: name, status as a colored badge, owner, created_at shown as relative time with the absolute date in a tooltip, and a numeric amount column right-aligned.

Sorting: clicking a header cycles ascending, descending, then cleared, with a direction arrow in the header. Sorting runs server-side through the Supabase query so it holds past the first page, and the sorted column plus direction sync into the URL so a shared link reproduces the view.

Pagination: server-side, 25 rows per page, a footer showing the visible range against the total from a count query, and previous and next buttons disabled at the edges.

Extras: a column visibility dropdown persisted to localStorage, a checkbox column with select-all scoped to the current page, and bulk delete on selection behind a confirmation dialog naming the exact count.

States: a loading skeleton with the same row height so nothing jumps, an empty state with a create button when no rows exist, and an inline error row with a retry action when the query fails.

Styling: a sticky header row inside a scrollable container, compact density with comfortable line height, and badge colors that keep readable contrast in dark mode.

Acceptance: sorting by amount descending across pages surfaces the true top values, not the loaded page reordered, the URL restores sort and page on reload, select-all touches only the visible page, and deleting the last row of a page steps back one page instead of stranding an empty screen.

Refactor 1 prompt

Audit every screen in this project for accessibility and fix what you find, without changing the visual design more than necessary.

Keyboard: make each interactive element reachable and operable with tab plus enter or space, add a skip-to-content link as the first focusable element, and confirm shadcn dialogs and sheets trap focus while open and return it to the trigger on close.

Semantics: replace clickable divs with buttons or links, give every icon-only button an aria-label naming its action, associate every input with a label element, and structure each screen with main, nav, and one h1, with heading levels that never skip.

Announcements: connect form errors to their fields with aria-describedby, announce async results like saves and deletions through a polite live region, and name loading spinners for screen readers instead of leaving them silent.

Color and motion: fix any Tailwind text and background pairs that fall below readable contrast, stop using color alone to convey status by adding an icon or text, and wrap non-essential animation in a prefers-reduced-motion check.

Focus visibility: keep a visible focus ring on every interactive element, and never remove an outline without providing a replacement.

Acceptance: I can complete signup, the primary create and delete flows, and navigation using only the keyboard, every image has meaningful alt text or an empty alt when decorative, and no interactive control remains a bare div. List each file you changed and the rule it violated.

Testing 1 prompt

Audit this app for unhandled failures and add consistent error handling. Do not change feature behavior or visual design while doing it.

Cover these layers:
- React: an error boundary around routed page content that shows a plain fallback with a reload button instead of a white screen. The shell and navigation stay usable when one page throws.
- Supabase queries: supabase-js returns { data, error } rather than throwing, so check the error object on every select, insert, update, and delete. Reads render an inline error with a retry button in place of the data; writes show a toast with a short human message and preserve whatever the user typed.
- Forms: validate required fields and formats before submit with field-level messages; the database rejecting bad input must never be the only feedback.
- Edge functions: wrap handlers so unexpected exceptions return JSON with a 500 instead of an empty response, and log enough context to find the failure later.
- Network: word the message differently for offline or timeout versus a server error, and never surface a raw error object, stack trace, or Postgres error code to the user.

Conventions: one shared toast helper and one shared error-to-message mapper so wording stays consistent across the app.

When finished, list every file you changed with one line on what is now handled there, plus any call sites that still swallow errors silently so I can decide about those separately.

Prompting patterns that work in Lovable

Write it like a short PRD

Open with one sentence on what the product is, then labeled sections for pages, data model, behaviors, and states. A structured prompt turns into a structured build; a vague one turns into a guessed one you renovate message by message.

Name your tables and access rules

List the tables, their key columns, and who can read or write each one. Lovable generates the Supabase migration and Row Level Security policies directly from this text, so precision here is the difference between real multi-tenancy and client-side filtering.

One change per message

After the first build, request a single feature or fix at a time and check the preview before continuing. Bundled requests fail together, and you will not know which sentence caused the regression.

Demand the unhappy paths

Every feature request should say what happens with no data, while data loads, and when a query fails. Left unstated, Lovable ships the happy path and blank screens stand in for the rest.

Common mistakes

The one-sentence app

"Build me a CRM" produces a generic shell you then reshape over dozens of messages, which costs more than writing the spec would have. Spend five minutes listing pages, data model, and roles before your first prompt.

Bolting auth on late

Adding login after the app works means retrofitting protected routes and rewriting RLS policies across every table. Say up front which pages require a session, even if the auth UI comes later.

Debugging with vibes

"It's broken, fix it" makes Lovable guess, and its guesses often restyle things you liked. Paste the exact error message, name the page and the action that triggered it, and say what should have happened instead.

How Lovable compares

Prompts for other tools