Repository navigation
AI Friendly JSON
Because every Selldone page is structured JSON with a small, fixed set of element types, software can create and update pages reliably. You can build pages from code, convert content from another system, or let an AI model write or fill sections, and the result renders exactly like a page designed by hand. This page shows the options and the hooks the editor provides.
-
One element shape everywhere —
component,style,classes,data,children(see Page JSON Structure). -
Closed vocabulary — only registered
X*components are accepted; unknown components are skipped, not rendered as broken HTML. - Layout is data — responsive columns are numbers from 1 to 12 per device, visibility is a set of booleans.
-
Text is separate from structure — titles and paragraphs live in
XText.data.value, so you can translate or rewrite copy without touching layout.
Use the element classes and their Seed() helpers, then export with toJson():
import { XSectionObject } from "@selldone/page-builder/components/x/section/XSectionObject.ts";
import { XContainerObject } from "@selldone/page-builder/components/x/container/XContainerObject.ts";
import { XRowObject } from "@selldone/page-builder/components/x/row/XRowObject.ts";
import { XColumnObject } from "@selldone/page-builder/components/x/column/XColumnObject.ts";
import { XTextObject } from "@selldone/page-builder/components/x/text/XTextObject.ts";
function textSection(title: string, body: string) {
const section = XSectionObject.Seed();
const container = XContainerObject.Seed();
const row = XRowObject.Seed();
const column = XColumnObject.Seed(12, 10, 8);
column.addChild(XTextObject.Seed(title, "h2", ["mb-3"]));
column.addChild(XTextObject.Seed(body, "p"));
row.addChild(column);
container.addChild(row);
section.addChild(container);
return { label: "Text", object: section.toJson() };
}
const content = {
title: "About us",
style: { font_size: 16 },
sections: [textSection("Our story", "We started in 2020...")],
};Store content as the page content, or load it into an open editor with
$builder.loadPage({ content, css: null, direction: "ltr" }). Section uids are generated when missing.
You can also produce the JSON elsewhere, for example with an AI model or a migration script. Give the generator a real example (export one with the editor or copy one from Page JSON Structure) and check the output before saving:
- every element has a
componentfrom the registered list, - every section has an
objectwhose root is usuallyXSection, -
XColumn.data.gridvalues are integers from 1 to 12 ornull, -
XText.data.tagis one ofp,h1–h6,span,div, -
uidvalues are unique (or omitted), - images (
XUploader.data.src) point to URLs you are allowed to use.
To move a page between shops, use the .landing export and import flow instead; it carries the content plus title,
description, image and direction.
LPageEditor exposes two optional props so you can connect your own content generator. The Page Builder does not call
any AI service by itself; you decide what runs behind these functions.
When set, an AI button appears beside each section (except raw code sections). On click, the editor calls your
function with the Section instance and expects a Promise:
async function aiAutoFillFunction(section) {
const current = section.object.toJson(); // send the current structure as context
const response = await myApi.fillSection({ label: section.label, object: current });
return { object: response.object }; // same shape as `current`, with new texts
}The editor applies the result with section.object.updateObjectWithFeed(generated.object). This walks both objects and
replaces only existing string and number values whose keys match. It never adds or removes elements or keys, so
the layout stays intact. Return the same tree with rewritten values (for example new data.value texts).
When set, a generate action appears in the editor's top menu for saved pages (pages with an id). The editor calls
your function without arguments and expects a Promise that resolves to { page }:
async function aiPageGenerateFunction() {
const page = await myApi.generatePage(/* your prompt or settings */);
return { page }; // page = { content, css, direction }
}The editor then calls $builder.loadPage(page). Save as usual to keep the result.
- Keep generated text in
XText.data.value; HTML such as<b>and<br>is allowed there. - Reuse the built-in section seeds as templates and only change texts and images; this keeps pages consistent with the editor.
- Validate generated JSON in a staging page before publishing.