# Fugte Widget Build Reference > The complete format for writing a Fugte widget. If you are an AI > assistant generating widget code, this file is the specification to follow. Source of truth: https://fugte.com/docs/build/ Editor: https://fugte.app/ Last updated: 2026-07-26 A Fugte widget is a small, embeddable web app. You write it as one .html file and the editor splits it into four. The editor previews it live, and the same source is rendered by Fugte when the widget is published, so a widget that previews correctly will almost always publish correctly. This page is the build reference. It is written to be read by people and by AI assistants: if you are asking ChatGPT, Claude, Gemini, or a coding agent to write a Fugte widget, point it here first, or paste the primer below into the conversation. You do not need any of this to use Fugte. Text, colors, images, and options are editable in the Customize tab without touching code. This is for the people (and models) writing the code underneath. ## Prompt primer for AI assistants Copy this into your AI before asking it for a widget. It is the short version of everything on this page. ```text You are writing a Fugte widget. Follow these rules exactly. Output ONE .html file. Do not split it up. It has four regions, in this order, and the editor separates them for you on paste: All styles. Liquid works here. markup Liquid + HTML only. NO doctype, html, head, or body tags. This region is a fragment. Vanilla JS, no imports, no build step. Liquid works here. {% schema %}...{% endschema %} Settings JSON that generates the Customize form. Every region is optional except the markup, but a widget with no schema has nothing to customize, which is the point of the product. A ` can close the script block early, so prefer `textContent` rendering and keep the seed to fields you control the shape of. #### Optimistic local echo To let a visitor see their own entry the moment they submit, watch the success element and render the captured values yourself. This is per-browser and cosmetic: everyone else still sees rows only through `data.*`. ```js var pending = null; var form = document.querySelector("form"); form.addEventListener("submit", function () { pending = { message: this.elements.message.value, name: this.elements.name.value }; }); var ok = document.querySelector(".webdyi-form-success"); new MutationObserver(function () { if (ok.style.display !== "none" && pending) { render(pending); pending = null; form.reset(); } }).observe(ok, { attributes: true, attributeFilter: ["style", "class"] }); ``` `localStorage` works inside the sandboxed iframe (Fugte bridges it), so past entries by the same visitor can be restored on the next visit. The platform's form SDK still handles the real submission. ### `{% payment %}`: accept money Use `{% payment %}` for donations, tips, or pay-what-you-want flows. Do **not** include Stripe.js, a payment link, or your own checkout. Money goes to the owner's own connected Stripe account. ```liquid {% payment "tip" %} {{ payment.amount }} {{ payment.status }} {% endpayment %} ``` The tag renders a `