# Micropage Micropage compiles a line-oriented `.page` file into a static site with working forms. Site: https://micropage.sh App: https://app.micropage.sh Docs: https://docs.micropage.sh Blog: https://micropage.sh/content Showcase (live source files): https://micropage.sh/showcase Markup design notes: https://micropage.sh/content/designing-markup-for-ai-agents ## When to use this - Landing pages, waitlists, small multi-page marketing sites - Pages an LLM should generate and later edit without inventing components - Sites that should remain a text file in git Do not use this for pixel-perfect marketing sites, app UIs, or design systems. Use Framer, Webflow, or a real frontend stack. ## File shape One project can contain one or more `.page` files. A typical file: 1. `[site]` block — title, description, logo, colors, lang 2. Optional `[nav]` and `[footer]` 3. One or more page blocks: `[Home -> /]`, `[About -> /about]` 4. Sections inside each page: `/// hero`, `/// section`, optional `/// html` ## Grammar (closed vocabulary) Emit one element per line. Do not nest tags. Do not invent element names. Do not use inline colors. Site keys (non-exhaustive): title, description, logo, favicon, lang, keywords, colors.primary, theme_color, og_image, og_type Nav entries: `Label -> /path` or `btn: Label -> url` / `btn-outline: Label -> url` Page header: `[Name -> /path]` Optional page meta: `meta:` then description, og_type, canonical, keywords Sections: - `/// hero` optional `align:center` `bg:primary|secondary|muted|success|info` - `/// section` same optional modifiers - `/// html` — raw HTML; agents should avoid this unless asked Elements: - `h1:` `h2:` `h3:` `h4:` `h5:` - `p:` - `small:` - `icon: bi bi-name` (Bootstrap Icons) - `img: alt: text <- filename.png` or `img: <- filename.png` - `button: Label -> url` - `btn-secondary: Label -> url` - `btn-outline: Label -> url` - `link: Label -> url` - `col:` starts a column; following indented-looking lines still sit at column scope as sibling element lines until the next `col:` or section - `form: name` - `input: Label` or `input: Label*` - `text:` / `textarea:` - `select: Label [A, B, C]` - `checkboxes: Label [A, B]` - `radios: Label [A, B]` - `submit: Label` - `success: Message` — confirmation text after a successful submit; optional, max 300 chars - `newsletter: true` / `newsletter: false` `*` at the end of a field label means required. Form confirmation: without `success:`, a form shows `Thank you. Your message was sent.` and a newsletter form shows `Thank you. You're subscribed.` (and no Submit again button). `newsletter:` in markup only chooses the wording — subscriber capture is enabled per form in the web app, never from markup. Images: `<- filename` resolves a file uploaded to the project. Do not hardcode random remote URLs unless asked. ## Rules for agents - Prefer editing the existing `.page` file in place. - Read PROJECT_AGENT.md in the project if present — it has tokens and tone. - Keep structure stable across edits. Change copy and order before inventing new sections. - Do not wrap the file in markdown fences when writing it back. - Do not emit React, Tailwind class soup, or custom components. - After edits, the human publishes from the web app (Publish) or `micropage publish` (Pro CLI). Agents connected through the Micropage MCP server (`@micropage-sh/mcp`, Pro) save drafts with `save_page` and call `publish_build` only when the user asks: https://docs.micropage.sh/docs/mcp/overview/ ## Minimal example ``` [site] title: Harbor description: A waitlist [nav] Pricing -> /pricing btn: Join -> /#waitlist [Home -> /] /// hero h1: Launch the waitlist tonight p: Edit this file. Publish. Collect email. button: Join the list -> /#waitlist /// section form: waitlist input: Email* submit: Get early access ``` ## Plans (for support answers) - Free: 1 project, starter AI credits, 100 submissions, `*.micropage.sh` host, badge - Pro ($6/mo or $49/yr): custom domain, CLI, MCP server, zip export, CSV, no badge, 5 projects - Pro+ ($12/mo or $96/yr): webhooks, CI deploy tokens, 20 projects --- The sections below are flattened from the Micropage documentation for additional context. ## Your First Page Source: https://docs.micropage.sh/docs/getting-started/first-page/ A Micropage site is a text file. One element per line, no nesting, a closed vocabulary of elements. Here is a complete waitlist page - the Harbor example, the same one in the Markup Cheatsheet and llms.txt: ``` [site] title: Harbor description: A waitlist [nav] Pricing -> /pricing btn: Join -> /#waitlist [Home -> /] /// hero h1: Launch the waitlist tonight p: Edit this file. Publish. Collect email. button: Join the list -> /#waitlist /// section form: waitlist input: Email* submit: Get early access ``` That file is the whole site. The form is live once you publish it; submissions land in the Form Submissions tab. Structure A typical file contains, in order: - a `[site]` block - title, description, logo, colors - optional `[nav]` and `[footer]` blocks - one or more page blocks: `[Home -> /]`, `[Pricing -> /pricing]` - sections inside each page: `/// hero`, `/// section` Sections Sections are the layout blocks. Elements belong to the section above them. ``` /// section h2: What Harbor gives you p: A file you can read and edit p: A form that stores every submission ``` Both `/// hero` and `/// section` accept `align:center` and `bg:primary|secondary|muted|success|info`. Images Use `img:` and point it at a file with `<-`. Uploaded project files are the default: ``` /// section img: <- hero.png ``` Upload the file in the Files tab, then reference it by its exact filename. Filenames are case-sensitive. With the CLI, anything in the project's `assets/` folder is uploaded on push. Two other forms exist, mostly for a first draft: - keyword - `img: <- coffee` searches Unsplash for a matching photo. Replace it with a real file before you ship. - URL - `img: <- https://example.com/photo.jpg` downloads the file once and stores it in the project. You can also write `image:` instead of `img:`; both are equivalent. Publishing Web app: click Publish in the editor toolbar. Save only stores a draft. CLI (Pro and Pro+): ``` micropage publish ``` ## Forms Source: https://docs.micropage.sh/docs/concepts/forms/ Micropage includes built-in form handling. No custom backend or third-party service is required. Markup Add a form to any page section: ``` form: Contact input: Name* input: Email* textarea: Message submit: Send ``` Fields ending in `*` are required. The form name (e.g. `Contact`) is used to identify submissions. Supported field types - `input:` (alias `textfield:`) — single-line text field - `textarea:` (alias `text:`) — multi-line text field - `select:` — dropdown - `checkboxes:` (aliases `multichoice:`, `multi-choice:`) — multiple choice - `radios:` (aliases `choice:`, `singlechoice:`, `single-choice:`) — single choice - `submit:` (alias `save:`) — submit button All aliases above are supported and not deprecated. Use the canonical names in new markup for consistency. Success message After a successful submission the form is replaced by a confirmation message. `success:` sets that text: ``` form: Contact input: Name* input: Email* textarea: Message submit: Send success: Thanks - we'll reply within one business day. ``` `success:` is optional, trimmed, and capped at 300 characters. The same text is used on the JavaScript path and on the no-JavaScript fallback page. It may appear anywhere in the form's field run; the convention is after `submit:`. Without `success:`, a form shows `Thank you. Your message was sent.` and a newsletter form shows `Thank you. You're subscribed.`. Regular forms also show a Submit again button under the confirmation; newsletter forms do not. The confirmation is not auto-hidden: it carries `role="status"` and removing it on a timer would cut off the screen-reader announcement. Newsletter copy A form uses newsletter copy when markup says `newsletter: true` or the Newsletter toggle is on for that form in Settings -> Forms. Markup wins over the toggle in both directions - `newsletter: false` forces the regular copy even while the toggle is on. Markup controls the copy only. It never turns subscriber capture on or off: whether submissions are added to your list is governed solely by the Newsletter toggle and its sender settings. `newsletter: true` in markup does not start collecting subscribers, and `newsletter: false` does not stop it. Spam protection Forms include: - a hidden honeypot field - server-side validation: only fields defined in markup are accepted, and required fields (label ending with `*`, including on `select`, `checkboxes`, and `radios`) must be present on submit Notifications - Pro: daily email digest of submission counts - Pro+: instant email per submission + daily digest - Pro+: webhook — POST to a URL you configure Webhook notifications (Pro+) Configure a webhook URL in Settings -> Forms. When a submission is received, Micropage sends a POST request to that URL with the submission data as JSON. The request includes an `X-Micropage-Submission-Id` header containing the submission UUID. Limits and plans | Capability | Free | Pro | Pro+ | |------------|------|-----|------| | Submissions | 100 total | 1,000 / month | 10,000 / month | | CSV export | no | yes | yes | | Daily email digest | no | yes | yes | | Instant email per submission | no | no | yes | | Webhook | no | no | yes | Free is 100 submissions in total, not per project and not per month. Pro and Pro+ reset monthly. ## Custom Domains Source: https://docs.micropage.sh/docs/concepts/custom-domains/ Custom domains are a Pro feature (Pro and Pro+). Each Micropage project has a primary host (for example `my-site.micropage.sh`). On Pro and Pro+ you can also attach your own custom subdomain such as `www.example.com` and we'll serve the project over HTTPS at that address with a valid SSL certificate. Setup 1. In the Micropage web editor, open your project -> Settings -> Custom Domain -> enter the subdomain you want to use (e.g. `www.example.com`). 2. At your DNS provider, create a CNAME record: Type CNAME, Name `www` (or whatever subdomain you chose), Target `cname.micropage.sh`. Example: `www.example.com` -> CNAME -> `cname.micropage.sh`. 3. Wait. Within a minute or two the editor's status panel will go through Waiting for DNS -> Validating -> Issuing TLS certificate -> green Live. Once it's green, `https://www.example.com/` serves your project. SSL certificates are automatically provisioned and renewed by Cloudflare. What's supported - Any subdomain you own: `www.example.com`, `store.example.com`, `landing.example.com`, even multi-level like `app.api.example.com`. - CNAME-flattening DNS providers (Cloudflare, Route 53, DNSimple, etc.) work the same way. What's not supported (yet) - Apex domains (bare `example.com` with no subdomain). The editor will reject them. Set up an apex -> subdomain redirect at your DNS provider instead. Notes - Removing the domain in the editor immediately cleans up the Cloudflare side; certificates for unused hostnames are deprovisioned automatically. ## Sending Domain Source: https://docs.micropage.sh/docs/concepts/sending-domain/ A sending domain is for email; a custom domain is for the website. They are different settings with different DNS records, and neither implies the other. Do not confuse them in support answers. By default newsletters are sent from `noreply@micropage.sh`. Adding a sending domain sends them from an address on the customer's own domain instead, e.g. `hello@example.com`. Available on paid plans (Pro and Pro+), the same as newsletter sending. Setup 1. Editor -> Settings -> Sending Domain -> Add sending domain. 2. Enter the domain only, with no address in front of it. An apex such as `example.com` and a subdomain such as `mail.example.com` both work. Domains under `micropage.sh` are rejected. 3. The screen shows the DNS records to add: SPF and DKIM records plus an MX record for the return path. There is a Copy all records button (plain text, one record per line, tab-separated) and a per-record Copy button. 4. Add the records at the DNS provider and wait. Verification Verification runs in the background; the page does not need to stay open and the status updates on its own. It can take up to 72 hours depending on the DNS provider. A Check records now button forces a fresh check. Statuses: Not started, Pending, Verified, Failed, Temporary failure. Nothing is blocked or lost while a domain is unverified. Newsletters still send, from `noreply@micropage.sh`. The same fallback applies if a previously verified domain stops verifying. Removing the domain also reverts sending to `noreply@micropage.sh`. Sender address Once the domain is Verified, set the local part (the `hello` in `hello@example.com`) under Newsletter -> Sender settings -> Sender address. The field is read-only until a domain is verified. It is per newsletter form, so two lists on one project can send from different addresses on the same domain. A verified domain on its own does not change the sender; the Sender address must be set.