DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS /// DOCS
PAGES·EMBEDS

Embeds

An embed is a block inside a Page that renders live data from somewhere else in your workspace. Unlike a reference pill, which is a frozen inline link, an embed is its own card and fetches fresh data every time the page loads.

Six embed types are available today. You insert them from the slash menu (/) or the + menu, each with its own picker.


At a glance

EmbedWhat it showsSlash command
TableA preview of a table — first 100 rows, your chosen view's columns./embed-table
RecordA single row as a card with the primary field, a breadcrumb, and your first few columns./embed-record
RoutineA button to run a routine./embed-routine
GalleryA grid of page tiles — subpages of this page, every page in a project, or pages you pick by hand./embed-gallery
ExportButtons to export the current page to PDF or Markdown./embed-export
FormA submit-new-record form built from columns you pick./embed-form

Table embed

Drop a snapshot of any workspace table into a page. The picker walks you through:

  1. Pick a table.
  2. Pick a view (optional). A view's column order, hidden columns, and filters carry over.

The embed shows the table name in the header, a [N ROWS] count on the right, and the first 100 rows with select/multiselect pills inlined. Sort and filter from the original view are preserved.

The embed stays live: change the underlying records and the embed reflects them on next page load.

//NOTE

For tables larger than 100 rows, the embed currently shows the first page only. Pagination beyond 100 rows is wired at the API level but the UI control hasn't shipped yet — coming in a follow-up.


Record embed

Pin a single row to a page. Useful for "this contact" / "this customer" / "this project" anchor cards.

The picker is two steps:

  1. Pick a table.
  2. Pick a record by primary field.

The card shows:

  • The row's primary field in large type.
  • A tableName · row #<short> breadcrumb in monospace.
  • The next few columns as labelled fields, with SELECT / MULTISELECT cells rendered as colored pills and LONGTEXT cells truncated to three lines.
  • An OPEN ↗ button (workspace view) or a tap target (public view) to jump to the full row.

The card refetches on every page load, so renames and field edits show up next time someone opens the page.


Routine embed

A "Run [routine name]" button. Clicking it triggers the routine.

Picker: pick a routine. That's it.

The button shows the routine name and a status indicator that cycles through [READY] → [RUNNING] → [OK] or [FAIL] after a run.

On the public surface (when the page is shared via its public URL), the routine button opens a popover that asks for the visitor's email + name + a Cloudflare Turnstile challenge before triggering. See Sharing and publishing for the visitor-facing flow.


A grid of page tiles, useful for index pages ("everything in this project", "all subpages of this guide").

Picker offers three sources:

  1. Subpages — every direct child of the current page.
  2. Project — every page in a project you choose.
  3. Manual — pick specific pages by name.

Each tile shows the page's cover image (or a brand-colored gradient fallback), icon, name, optional description, and last-updated timestamp.

On a public page, gallery tiles that point at other public pages turn into navigation links to those public pages. Tiles that point at private pages open the signup CTA — there is no link leakage to private content.


Export embed

Two buttons: Export to PDF and Export to Markdown. Clicking either downloads the current page as a file.

No picker — /embed-export inserts the buttons directly.

PDF export renders the page in @react-pdf/renderer with the page's font, headings, lists, callouts, code blocks, and inline references preserved. Markdown export uses the same content_text mirror the AI sees, so what you export matches what AI ingests.


Form embed

Lets anyone who can read the page submit a new record to a table you choose. This is the public-surface flagship — workshop registrations, contact forms, support intake, signup waitlists.

Picker is three steps:

  1. Pick a table.
  2. Pick the fields to expose. You toggle each column on with a checkbox, reorder with the ↑↓ buttons, and mark per-field required (overrides the column's own required flag).
  3. Optional metadata — a custom submit-button label and a success message shown after submission.

Field types that are safe to expose publicly are allowed: text, long text, email, phone, URL, number, datetime, boolean, single-select, multi-select. Columns that wouldn't make sense on a public form (formula, computed, AI-generated, reference) are not selectable.

On the workspace side the form behaves like a normal "create record" interface — it calls the same mutation. On the public side it POSTs to a public-submit endpoint that validates the field whitelist, checks Cloudflare Turnstile, and hashes the visitor's IP + user agent for an audit log.

If you didn't include an EMAIL column, an extra "your email" row is auto-added so we can attribute the submission. The endpoint returns success, the visitor sees your custom success message, and the row appears in the target table.

Admins see every public submission in a SUBMISSIONS tab on the table panel. Click OPEN ↗ to jump straight to the new record.


How embeds differ from references

Reference (@)Embed (/embed-*)
Where it livesinline inside a paragraph or listits own block, taking up a row
What it showsthe entity name as a pilllive data from the entity
Refreshes?no — the label is frozen at insert timeyes — refetches on every page load
Public surface behaviordisplay-only pillinteractive (link, button, form, popover)
Best formentioning an entity inline ("contact @Acme Inc.")featuring an entity ("here is Acme's record")

Use both — they aren't mutually exclusive. A page might mention a routine inline via @ and embed a Run button further down.


Markdown and round-trip

Every embed serializes to a single markdown line of the form:

[Optional Label](embed:type:base64-encoded-config)

The base64 segment carries the embed's stable identity and configuration. This means embeds survive copy/paste through any markdown-aware tool — you can paste a page into another page (or an external markdown editor and back) and the embeds reappear unchanged.

The identity is per-insertion: two embeds of the same table on the same page each have their own identity, so independently configured embed instances don't fight each other.