Seeing your work
How your AI checks its work on LazyFrog: screenshots, trying pages in a real browser, design checks and reading what your app returns.
- Press it, don't only look at it.
preview_tryopens the preview in a clean browser and runs your steps: click, type, select, press, scroll, wait,expect(is this on the page now?),media(is each audio and video's time really moving, and at what volume?) andscreenshot. Name things as a visitor sees them (text), or useselector. Anything people press gets tried on a phone (viewport: "mobile", the default) before you say it works; a screenshot of a button isn't proof it does anything. Each step says what happened;mediawith no sound moving means the player doesn't play, whatever its button shows. It changes the preview's data as a visitor would, and never the live site. It is a browser: it hears nothing and isn't a real phone, so say what you tried and ask the user to try the rest. - Every project has a preview address,
https://p-<id>.lazyfrog.app(project getshows it;project createreturns it). It always shows your current work, live, so give it to the user and they can watch the app in their browser as you build. It is unguessable and markednoindex. If the user wants it private,project settingswithpreview_passwordasks visitors for a password;rotate_preview_urlgives it a new address. Never put it in the site's own files (a share image, a canonical link, a sitemap): use the live address or a path; publishing names the files that still carry it. On the live site, arobots.txtyou write is served after a few comment lines Cloudflare adds about AI use; without one, only those show. - A sleeping preview wakes when someone visits it (a short "waking up" page) and sleeps after 15
minutes without visits or tool calls. What a page does by itself doesn't keep it awake or wake
it: an open tab's connections (the dev server's hot reload, a WebSocket, an event
stream) count only when they open, a reconnect to a sleeping preview gets 503 with Retry-After,
and a page that reloads itself shows "Preview asleep" and wakes it once the tab is looked at.
Reading a project (
project_readget) never wakes it either: a sleeping preview is reported asleep. - Check the app yourself with
http_get(any path, against the running app;http_requestfor other methods and a body) andpreview_screenshot(an image of a page, desktop or mobile). - Browser errors.
preview_screenshotanddesign_checkopen the page in a clean browser (no extensions, a fresh profile) and list what went wrong there under "Browser errors in a clean browser": uncaught errors, console errors and the app's own files that failed to load (include_warnings: trueadds console warnings), or "none". Fix what it lists like any other bug. The preview runs the app's development server, so it shows the framework's developer overlay (the error box over the page) and development-only warnings; the live site doesn't show the overlay to visitors. - When the person reports an error from their own browser, check it with a screenshot of
that page first. If the clean browser shows nothing and the error mentions things the code
never wrote (attributes such as
data-lastpass-*,data-gr-*,data-1p-*,cz-shortcut-listen, or elements the code doesn't render), tell them in plain words: it's a browser extension on their side (a password manager, a spell checker) adding to the page; visitors on the live site don't see the overlay; a private window with extensions off shows the page without it. Change nothing in the code. Never sprinkle hydration-warning suppression (suppressHydrationWarningand the like) to hide it. A real hydration mismatch, one the clean browser shows too, comes from the code: a time or date, a random value, the locale, or invalid nesting (a<div>inside a<p>, a link inside a link). Fix it in the code so the server and the first render in the browser agree (render the changing value after the page has loaded, fix the nesting). - Publishing puts the preview live at
https://<slug>.lazyfrog.app(see Publishing below). execruns commands as the project's user in/workspace. Default timeout 60 s (max 300); usebackground: truefor longer work (up totimeout, default an hour) and follow it with thejobtool. Long output keeps its end: send it to a file andfs_readit for all of it. ImageMagick (magick) andffmpegare installed, e.g. for photos the user brings:magick in.jpg -auto-orient -strip -resize '1600x1600>' -quality 72 out.webp. For text on an image use an installed font (magick -list font: the URW set, such asNimbusSans-Regular); a missing one only warns and the image still comes out, in a fallback. Anything a command leaves running is stopped when it finishes: servers belong in services.json. Commands share the sandbox's memory with the database and services (768 MB on Free): a command that would use more than what is left is stopped ("Stopped: the command used more than N MB"), and they keep running; work in smaller batches or stream instead of loading everything at once. A commit (its secret scan) or a publish stopped the same way fails withworkspace_out_of_memory(see When something fails): change course, don't repeat it. Free workspaces are small, but on Free and Hobby a command gets extra room while it runs: a foregroundexec(notbackground),gitandproject_scanhave 512 MB more than the plan's memory for their run, taken back after, so a commit, an install, a type check or a build usually fits beside the dev server: don't stop the dev server first. When the node is busy a command runs without it, and the result says so ("the node is busy, so this command had no extra room"): try again in a few minutes. Run one heavy thing at a time (notproject_scan,design_checkordeploy preflightwhile a build, a test run or a second dev server runs), and prefer one page at a time fordesign_check. These checks take their turn, and when one fails the way a starved app does it is tried again by itself (after a big service restarts, when the workspace is nearly full). If it still fails it says why: the workspace short of memory (on Free that is its size, not a fault in the app), a page that didn't load (look at it withhttp_getandlogs_tail), or a page that kept LazyFrog's checking browser busy or crashed it (it draws without a graphics card; try one page at a time,preview_screenshotmeanwhile). Tell the user what was skipped and go on. A build on Free (it has nodeploy preflight) that still runs out of memory with the extra room: stop the dev server for the build (servicestopname "web"), run the build withexecagain, andservicerestartit when the build is done; meanwhile the preview says the site has stopped.
For your AI: this page as Markdown · llms.txt