Custom pages
A custom space starts with no opinion. It has no preset sections or fields: you decide the shape, and the reader follows it. People use it for a landing page, a small marketing site, a pricing page, a link-in-bio, a waitlist, a portfolio, or a long trust or security page. Its reader address is /x/{orgId}/{spaceId}/… on our host, or wherever you mount it on your own domain.
A custom space is built from ordinary pages, written in the same editor as documentation, with the same blocks. This guide covers what is particular to it: the arrangements and looks, the site-level effects, the per-block layout hooks, CMS template pages and Lottie animations.
Arrangements
PUT /orgs/{orgId}/spaces/{spaceId}/preset picks one of three. They render differently.
Preset | What it does |
|---|---|
| The space is one page. Its address shows your home page full width, with nothing around it but your header and footer. |
| A small site. Each top-level page is a link in the header, and a page with children becomes a dropdown. A page's |
| A long read such as a security or trust page: the page tree, an on-this-page rail, a breadcrumb, the date it was updated and the previous/next links. |
A space that stored the older standard preset reads as landing.
Space choices. A custom space accepts only the choices its reader implements, and the API refuses the rest with a 422:
Choice | Values | Default |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
A root with nothing published is kept out of search engines, and shows you (in preview only) a hint about what to add.
Looks are patches
theme.custom.look gives the space a starting aesthetic in one key. Each look sets a few page keys (from theme.docs, which a custom page reads) and the corner radius. Every one of them is a key you can set yourself, and a key you set beats the look's.
Look | What it sets |
|---|---|
| Nothing beyond the custom page layer below. |
| The same: the way back in one key if you were on another look. |
| A long read: |
| A product site: |
|
|
The custom page layer. Under every look, a custom page reads as a page, not a docs site: no top rule, the article aligned with its title, no page tree or rail, no breadcrumb, contributors, updated date, feedback or previous/next links, and full width unless you set contentWidth. A contentWidth you set on the space always wins over the full-width default and over a look's width. The article arrangement swaps this layer for the docs frame.
Set a look with the space theme:
PATCH /orgs/{orgId}/spaces/{spaceId}/theme
{ "custom": { "look": "editorial" } }Combinations that are not any template's look:
1. portfolio's square corners on an editorial column.
{ "custom": { "look": "editorial" }, "components": { "radius": 0 } }2. product's full bleed, centred, with the date back.
{ "custom": { "look": "product" }, "docs": { "articleAlign": "center", "pageHead": { "updated": "top" } } }3. Any look with a site-level effect (next section):
{ "custom": { "look": "portfolio", "pageTransition": "fade", "cursor": { "style": "ring", "color": "#111827", "size": 28 } } }The docs keys a custom space reads are the page keys (width and alignment, top rule, page head, frame, page actions, table of contents, panel, aside, feedback, previous/next, edit and issue links), plus sidebar, mobileNav, search and localeSwitcher, which the article arrangement draws. The documentation-site keys are not read. See Theme a docs space.
Site behaviour
theme.custom also holds three site-wide effects, in the studio under Settings → Site behaviour:
Key | Default | What it does |
|---|---|---|
| 640 | Where "phone" ends, 360–900 px. |
| 1024 | Where "tablet" ends, 600–1600 px, above |
|
| How a page arrives: |
| the system's |
|
Transitions and the cursor stay still for readers who ask their system for less motion, and the cursor only appears with a mouse or trackpad, never on touch.
Layout and effects on any block
Every block, in every space type, carries optional layout hooks (Webflow's and Framer's per-element style panel). In the editor they are in the block's panel under Layout and effects.
Hook | Values | What it does |
|---|---|---|
| up to two of | Hide on those screen sizes. |
| -10 to 100 | Its layer, above or below its neighbours. |
|
| Clip what spills out, or let it scroll sideways (a wide table, a strip of logos). |
| 0–200 | Stick to the top of the screen while its section scrolls, this many px down. |
| -180 to 180 | Degrees. |
| 25–300 | Percent; 100 is its own size. |
| -400 to 400 | Nudge right and down, px. |
| 0–24 | Blur, px. |
| 0–100 | Greyscale, percent. |
| 20–200 | Brightness, percent; 100 is unchanged. |
| 0–100 | Opacity, percent; 100 is opaque. |
|
| A hover effect. |
Every value is a fixed choice or a bounded whole number, printed as a data-* flag and a CSS variable composed from that number, so nothing you type here reaches the page's styles as raw text. In markdown the hooks are an attribute list on the block, for example {hideAt=phone fxRotate=-3 fxHover=lift} (Markdown directives).
Copy style and Paste style in the same panel carry a block's look and layout keys (never its content or anchor) to another block.
Lottie animations
The Lottie animation block plays a Lottie JSON animation. Upload the .json to your library from the block; only a file in your own library is accepted, so the animation is never fetched from a third party.
Attribute | Default | What it does |
|---|---|---|
| The library file ( | |
| none | What it shows, for screen readers. |
|
|
|
| on | |
| 100 | 25–400 percent. |
| Width over height (1.777 for 16:9), 0.2–5. The box is reserved before it loads, so nothing shifts. | |
| the column | 48–2400 px. |
The player is a light SVG build that runs without eval, so the page's security policy holds, and it loads only when the block nears the screen. Without JavaScript, or when the reader asks for less motion and the animation would play by itself, the block stays a still box.
CMS template pages
A custom page can be a template for a content type from one of your organization's content libraries, like Webflow's Collection pages:
/<page>/<entry-slug>shows one published entry through the page you designed.{{ entry.<field> }}in the page's text, image sources and link targets is replaced by that entry's value (links are checked as safe URLs), the page title is the entry's title, and the canonical points at the entry./<page>itself lists the entries, newest first, each linking to its own address.
Bind a page in its details panel under CMS template, or with page metadata:
curl -X PATCH "https://forumulate.com/api/orgs/$ORG/spaces/$SPACE/pages/$PAGE/metadata" \
-H "Authorization: Bearer $FORUMULATE_TOKEN" -H "Content-Type: application/json" \
-d '{ "cmsBinding": { "libraryId": "…", "type": "case-study", "summaryField": "excerpt", "limit": 50 } }'Key | Default | What it does |
|---|---|---|
| (required) | The content library. |
| (required) | The content type's key in it. |
| the entry's title | The line under each entry in the list. |
| 50 | How many entries the list shows, 1–100. |
cmsBinding: null removes the binding. Only published entries are shown, read exactly as the delivery API serves them, so a template can never show a draft or a field the library marks internal. An entry address the library does not publish is a real 404. Binding a page publishes the library's entries on your site, so it needs space.update on the space and content.read on the library; a writer who may edit the page but not read the library gets a 403.
Page settings that matter here
These are page metadata (PATCH …/pages/{pageId}/metadata), in the page's details panel:
Key | What it does |
|---|---|
|
|
| The page's words in the header under the |
| What this page says it is in JSON-LD: |
| The same page-head controls as documentation pages. |
| This page's own head code. |
(password) | A per-page password. |
Head code and passwords have their own guide: Page passwords and head code.
Your shape is enforced. The fields you declare for the space's pages are checked when a page is written: minLength, maxLength, pattern, min and max refuse a value that breaks them, and properties that only content libraries understand (localized, unique, hasMany…) are refused by name rather than accepted and ignored. A section's role and schemaProperty are set in the shape panel; a schemaProperty value fills the page's JSON-LD.
Per-page overrides
A custom page can carry its own customization in page metadata: theme keys, CSS, share card and JSON-LD for that page alone. The theme takes the shared tokens (colours, fonts, type, components, layout, motion, width) and the docs namespace, because the page is read by the page reader. theme.docs.frame set on one page changes that page's frame. Any other type's namespace (post, contact, custom…) is refused with a 422 that names it.
Theme outlets
A custom space has no outlets of its own: its pages are the page reader's, so the docs page outlets apply (docs-page-header, docs-page-footer, docs-sidebar-start, docs-sidebar-end, docs-rail, docs-rail-end; the sidebar and rail ones only where the article arrangement draws them), and a /c/<slug> collection hub has docs-hub-above-list and docs-hub-below-list. See Theme components.
Front door and reader tools
Setting | Default | What it does |
|---|---|---|
| off | A search box over the home page or the list. |
| none | Settings → Page tools: the search box, Download PDF, Copy as Markdown, Open in ChatGPT / Claude and Connect with MCP. A custom space starts with none of them, because a landing page rarely wants a toolbar. |
Other addresses
Address | What it is |
|---|---|
| The whole space on one printable page. |
| A page as markdown. |
| A page's updates feed. |
| A collection hub. |
| The space's sitemap (the root listed once, an empty root not at all). |
An address that names the home page by its id redirects to the space's root in one hop.
Importing a site
Housekeeping → Import a site in the studio brings pages in from a Webflow "Export code" ZIP, or from a published Webflow or Framer site by its address (up to 40 pages, same site only). Each page becomes a page here; navigation, header and footer stay behind, because the space draws its own. See Importers.
Templates
Nine custom templates start a space: Atelier Portfolio, Beacon Waitlist, Gridline, Harbor Site (the pages arrangement with dropdown navigation), Keystone Trust, Linkline Bio, Lumen Launch, Northstar Story and Tidepool Pricing.
In the studio
Settings → Site behaviour: screen sizes, page transition, cursor.
Settings → Page tools: the reader toolbar.
Housekeeping → Import a site.
Design: the look, the arrangement and every page key.
A page's details panel: layout, password, CMS template, Head code.
A block's panel: Layout and effects, Copy style, Paste style.