Overview
Lovable generates and iterates on web apps from natural-language prompts. It doesn't connect to MCP servers, so the integration with chisel.to is context-based: you pin the project brief as a knowledge document, then every prompt — first or fiftieth — sees the same backend description. With that in place, Lovable produces apps that call your real endpoints, use the right auth flow and respect the column types you've defined.
Three things you get from this setup:
- Iteration without context drift. "Add a comments section" works on prompt 30 the same way it works on prompt 1, because the brief is pinned.
- Consistent auth handling. Once the init snippet lands in the generated project, every screen uses the same client.
- Schema-aware UI. Form fields, validation messages and table columns map to your real model instead of placeholder fields.
Requirements
- A Lovable account.
- A chisel.to project with at least one publishable API key.
- Your
llms.txtdownloaded from the Connect page (or copied to clipboard).
No installs, no environment variables to set on your machine — Lovable provides the runtime.
Get the llms.txt brief
- Open your project in the chisel.to dashboard.
- Open the Connect card.
- Click Download llms.txt (or copy its contents from the inline preview).
The brief is short markdown — base URL, auth conventions, response shape, every resource with its columns, every platform endpoint. Designed to fit into a prompt context window with room to spare.
Pin llms.txt as a knowledge document
Lovable lets you attach reference documents that persist across the whole chat. Use that mechanism for the brief — it stays in scope as you iterate, no repasting needed.
- Open or create a Lovable project.
- In the chat sidebar, open Knowledge (or the equivalent attachment area for your Lovable workspace).
- Add the contents of
llms.txtas a document named chisel.to backend reference. - Mark it as always-included in context.
If your Lovable workspace doesn't expose a separate knowledge layer, drop the brief into the first message of the chat with a clear framing line — the conversation keeps it in scope as long as it's not pruned out for length.
prompt — fallback if no pinned knowledgeThe following backend brief is the reference for every screen in this project.
Always use the URLs, auth conventions and resource shapes described here.
Do not invent endpoints or columns.
<<< llms.txt
[paste the entire contents of llms.txt here]
>>>
Acknowledge by listing the resources you see. Don't generate UI yet.
The init snippet
Get Lovable to add one small client module up front so every later screen uses the same wiring. Run this prompt right after pinning the brief:
promptBefore we build any screens: create src/lib/chisel.ts. It should:
1. Read VITE_CHISEL_URL and VITE_CHISEL_KEY from env vars.
2. Export a `chisel(path, init)` helper that prepends the base URL and adds the
Authorization: Bearer header.
3. Provide a tiny session store (useChiselSession hook) that holds the current
access_token in memory and exposes signIn, signOut, refresh.
4. Throw friendly errors when responses are 4xx/5xx; surface the validation
error map on 422.
After you create the file, add VITE_CHISEL_URL and VITE_CHISEL_KEY to the
project env config.
Set the env values in Lovable's project settings panel (search for env / secrets in the workspace). Use the publishable key only.
Verify it works
Confirm the brief is loaded and the init module is in place:
promptSanity check before we start: list every resource on the backend (from the
pinned brief), and confirm src/lib/chisel.ts exists and reads its config from
VITE_CHISEL_URL / VITE_CHISEL_KEY.
Then a tiny end-to-end smoke test:
promptAdd a /diagnostic page that uses the chisel helper to fetch the first 5 posts
and renders their titles in a list. If the request fails, render the raw error
so I can see it. This is throwaway; I'll delete it after verification.
If the preview shows your real titles, the integration is live. If you see "Failed to fetch" or 401, jump to Troubleshooting.
Common workflows
1. Build a feed + composer pair
promptBuild /feed and /compose.
/feed: lists posts with status=published, sorted by created_at desc, paginated
at 20 per page. Render each card with title, meta_description and a relative
timestamp.
/compose: a form with title, body (text_long), status (draft/published). On
submit, call createPost from the chisel helper. Show inline field errors when
the API returns 422.
Both pages require the user to be signed in; redirect to /sign-in otherwise.
2. Wire auth screens
promptBuild /sign-up and /sign-in:
- Use the auth endpoints described in the brief.
- On success, hold the access_token in the useChiselSession hook; do not write
it to localStorage.
- Store the refresh_token via a Lovable-side server action that sets an
httpOnly cookie.
- After sign-in, redirect to /feed.
3. Admin table with column-aware filters
promptBuild /admin/posts. Render the posts table with sortable columns. Derive the
filter bar from the column types in the brief — enum columns become dropdowns,
booleans become toggles, dates become range pickers. Allow inline editing of
mutable columns. Add a Publish button that calls the custom action.
4. Public site shell from /site
chisel.to projects expose a public /site endpoint with branding and SEO defaults. Use it for the marketing shell:
For the public marketing pages (/, /about, /pricing), fetch /site on the server
and use the returned site name, description, logo_url and SEO defaults to
populate the layout's <head> metadata and the header brand. No auth required.
Iterating safely
Lovable's strength is fast iteration — but rapid iteration is also where prompt-only tools tend to drift. A few habits keep behavior consistent:
- Refer to the brief explicitly. Even with knowledge pinned, sentences like "use the columns described in the brief" are worth a couple of extra tokens to keep the model anchored.
- State the data shape first in styling prompts. "The cards show meta_title and author (looked up via author_id). The styling: …" — flipped order, the model is more likely to invent fields.
- Catch drift quickly. When you spot a fabricated endpoint or column, name it explicitly and replace it: "There's no 'category' column. Use 'tags' (which is a JSON array) instead."
Auth in generated apps
Tell Lovable up front how to handle tokens — otherwise the default behavior is to drop them in localStorage. A safe baseline:
- Access token in memory (useChiselSession). React context or a Zustand store both work.
- Refresh token in an httpOnly cookie set by a Lovable server action — never visible to client JS.
- API key in
VITE_CHISEL_KEY, publishable only. Never paste a server-scope key.
If the brief lists social providers (Google, Apple, GitHub, etc.), Lovable will use them when you ask for "sign in with X" — the redirect flow uses the project's existing OAuth setup. You don't need to configure anything extra inside Lovable.
Realtime & subscriptions
For live updates (comments appearing as they're posted, leaderboards updating in real time), the chisel.to platform exposes a realtime layer that the brief describes. Ask Lovable to wire it up explicitly:
promptOn /feed, subscribe to the "posts:published" realtime channel using the chisel
helper. When a new post arrives, prepend it to the list with a small "New"
badge that fades out after 5 seconds. Unsubscribe on unmount.
Realtime is easy to forget in a prompt-only flow — pin it as a follow-up todo when you ask for the initial list view.
Refreshing context when the schema changes
The pinned knowledge document is static — it doesn't auto-update when you change the schema on chisel.to. Two ops habits:
- Replace the pinned doc on every schema change. Download the new
llms.txtfrom the Connect page and update the Knowledge entry. One step. - Call out the change in your next prompt. "I added a tags column on posts. Use it on the /feed cards." This nudges the model to actually use the new field rather than fall back to the cached pattern.
Security & key hygiene
- Use a publishable test key while building. Switch to a live key only when deploying.
- Don't paste server-scope keys into the chat or Knowledge layer. Assume anything in a prompt could leak.
- If you've enabled an IP allowlist, Lovable's outbound IPs need to be on it for any server-side calls (e.g. fetching
/siteduring SSR). Skip the allowlist for now if you're not sure.
Troubleshooting
Generated screens fetch the wrong URL
The brief at the top of the chat lists the project's actual base URL. If a screen hits a different URL, the brief either wasn't pinned or the chat got long enough to drop it. Repin and try again.
"Failed to fetch" with CORS errors
Lovable's preview runs on a temporary domain. Add it to your project's CORS allowlist in Domains & access. Use a wildcard https://*.lovableproject.com while iterating; tighten down once you have a fixed preview domain.
Auth requests return 401
Three usual causes: wrong key, key belongs to a different project, or env vars not actually set in Lovable's project settings. Open the preview console and confirm the request includes the Authorization header with the expected value.
Lovable keeps writing tokens to localStorage
The default. Add a rule to the chat: "Tokens never go in localStorage. Use the useChiselSession hook for access tokens and a server-side cookie for refresh tokens." Repeat it on the first prompt where it lands incorrectly.
Long chat is starting to invent things
Repin the brief — even with a Knowledge document attached, very long chats can prune attachments out of working context. A quick "Re-read the chisel.to backend reference and list the columns on the posts table" forces a refresh.