一、安装和使用准备
1) 拉取工程
git clone https://github.com/builderio/gpt-crawler
2)确定和切换node版本
Be sure you have Node.js >= 16 installed.
利用nvm管理和切换node版本
nvm use v20.17.0
3) 安装依赖
npm i
4)找到配置文件config.ts
import { Config } from "./src/config";
export const defaultConfig: Config = {
url: "https://www.builder.io/c/docs/developers",
match: "https://www.builder.io/c/docs/**",
maxPagesToCrawl: 50,
outputFileName: "output.json",
maxTokens: 2000000,
};
5)后续执行命令
npm start
二、实战测试
1) dusa文档网站
https://docs.dusa.io
配置如下:
import { Config } from "./src/config";
export const defaultConfig: Config = {
url: "https://docs.dusa.io",
match: "https://docs.dusa.io/concepts/**",
maxPagesToCrawl: 1000,
selector: ".theme-doc-markdown markdown",
outputFileName: "docs.dusa.io.json",
maxTokens: 2000000,
};
实践结果:
INFO PlaywrightCrawler: Crawling: Page 1 / 1000 - URL: https://docs.dusa.io/...
WARN PlaywrightCrawler: Reclaiming failed request back to the list or queue. page.waitForSelector: Timeout 1000ms exceeded.
Call log:
- waiting for locator('.theme-doc-markdown markdown') to be visible
at PlaywrightCrawler.requestHandler (/Users/shareit/Workspace/work/research/gpt-crawler/dist/src/core.js:47:36) {"id":"7Jk4DLt77vfStH7","url":"https://docs.dusa.io","retryCount":1}
INFO PlaywrightCrawler: Crawling: Page 2 / 1000 - URL: https://docs.dusa.io/...
WARN PlaywrightCrawler: Reclaiming failed request back to the list or queue. page.waitForSelector: Timeout 1000ms exceeded.
Call log:
- waiting for locator('.theme-doc-markdown markdown') to be visible
at PlaywrightCrawler.requestHandler (/Users/shareit/Workspace/work/research/gpt-crawler/dist/src/core.js:47:36) {"id":"7Jk4DLt77vfStH7","url":"https://docs.dusa.io","retryCount":2}
INFO PlaywrightCrawler: Crawling: Page 3 / 1000 - URL: https://docs.dusa.io/...
WARN PlaywrightCrawler: Reclaiming failed request back to the list or queue. page.waitForSelector: Timeout 1000ms exceeded.
Call log:
- waiting for locator('.theme-doc-markdown markdown') to be visible
at PlaywrightCrawler.requestHandler (/Users/shareit/Workspace/work/research/gpt-crawler/dist/src/core.js:47:36) {"id":"7Jk4DLt77vfStH7","url":"https://docs.dusa.io","retryCount":3}
INFO PlaywrightCrawler: Crawling: Page 4 / 1000 - URL: https://docs.dusa.io/...
ERROR PlaywrightCrawler: Request failed and reached maximum retries. page.waitForSelector: Timeout 1000ms exceeded.
Call log:
- waiting for locator('.theme-doc-markdown markdown') to be visible
at PlaywrightCrawler.requestHandler (/Users/shareit/Workspace/work/research/gpt-crawler/dist/src/core.js:47:36)
at async wrap (/Users/shareit/Workspace/work/research/gpt-crawler/node_modules/@apify/timeout/index.js:52:21) {"id":"7Jk4DLt77vfStH7","url":"https://docs.dusa.io","method":"GET","uniqueKey":"https://docs.dusa.io"}
INFO PlaywrightCrawler: All requests from the queue have been processed, the crawler will shut down.
INFO PlaywrightCrawler: Final request statistics: {"requestsFinished":0,"requestsFailed":1,"retryHistogram":[null,null,null,1],"requestAvgFailedDurationMillis":32327,"requestAvgFinishedDurationMillis":null,"requestsFinishedPerMinute":0,"requestsFailedPerMinute":1,"requestTotalDurationMillis":32327,"requestsTotal":1,"crawlerRuntimeMillis":53530}
INFO PlaywrightCrawler: Error analysis: {"totalErrors":1,"uniqueErrors":1,"mostCommonErrors":["1x: page.waitForSelector: Timeout 1000ms exceeded. (/Users/shareit/Workspace/work/research/gpt-crawler/dist/src/core.js:47:36)"]}
INFO PlaywrightCrawler: Finished! Total 1 requests: 0 succeeded, 1 failed. {"terminal":true}
Found 0 files to combine...
结论:
直接timeout error 不可用,实际网页可以打开
2) github.io文档网站:
https://datawhalechina.github.io/
配置如下:
import { Config } from "./src/config";
export const defaultConfig: Config = {
url: "https://datawhalechina.github.io/easy-rl/#/",
match: "https://datawhalechina.github.io/easy-rl/#/**",
maxPagesToCrawl: 1000,
selector: ".content",
outputFileName: "datawhalechina.github.io.easy-rl-1.json",
maxTokens: 2000000,
};
实践结果:
[
{
"title": "蘑菇书EasyRL",
"url": "https://datawhalechina.github.io/easy-rl/#/",
"html": " \n\n蘑菇书EasyRL\n\n李宏毅老师的《深度强化学习》是强化学习领域经典的中文视频之一。李老师幽默风趣的上课风格让晦涩难懂的强化学习理论变得轻松易懂,他会通过很多有趣的例子来讲解强化学习理论。比如老师经常会用玩 Atari 游戏的例子来讲解强化学习算法。此外,为了教程的完整性,我们整理了周博磊老师的《强化学习纲要》、李科浇老师的《世界冠军带你从零实践强化学习》以及多个强化学习的经典资料作为补充。对于想入门强化学习又想看中文讲解的人来说绝对是非常推荐的。\n\n本教程也称为“蘑菇书”,寓意是希望此书能够为读者注入活力,让读者“吃”下这本蘑菇之后,能够饶有兴致地探索强化学习,像马里奥那样愈加强大,继而在人工智能领域觅得意外的收获。\n\n使用说明\n第 4 章到第 11 章为李宏毅《深度强化学习》的部分;\n第 1 章和第 2 章根据《强化学习纲要》整理而来;\n第 3 章和第 12 章根据《世界冠军带你从零实践强化学习》 整理而来。\n纸质版\n\n推荐购买链接:京东 | 当当\n\n\n\n\n推荐京东扫码购买\n\n\t\n\n\n当当扫码购买\n\n豆瓣评分:https://book.douban.com/subject/35781275/\n\nℹ️ 勘误修订表:https://datawhalechina.github.io/easy-rl/#/errata\n\n在线阅读(内容实时更新)\n\n地址:https://datawhalechina.github.io/easy-rl/\n\n最新版PDF下载\n\n地址:https://github.com/datawhalechina/easy-rl/releases\n\n国内地址(推荐国内读者使用):链接: https://pan.baidu.com/s/1isqQnpVRWbb3yh83Vs0kbw 提取码: us6a\n\n压缩版(推荐网速较差的读者使用,文件小,图片分辨率较低):链接: https://pan.baidu.com/s/1mUECyMKDZp-z4-CGjFhdAw 提取码: tzds\n\n纸质版和PDF版的区别\n\nPDF版本是全书初稿,人民邮电出版社的编辑老师们对初稿进行了反复修缮,最终诞生了纸质书籍,在此向人民邮电出版社的编辑老师的认真严谨表示衷心的感谢!(附:校对样稿)\n\n内容导航\n章节\t习题\t相关项目\t配套代码\n第一章 强化学习基础\t第一章 习题\t\t\n第二章 马尔可夫决策过程 (MDP)\t第二章 习题\t\t值迭代算法\n第三章 表格型方法\t第三章 习题\tQ-learning算法实战\tQ-learning,Sarsa,蒙特卡洛\n第四章 策略梯度\t第四章 习题\t\t策略梯度\n第五章 近端策略优化 (PPO) 算法\t第五章 习题\t\tPPO\n第六章 DQN (基本概念)\t第六章 习题\t\tDQN\n第七章 DQN (进阶技巧)\t第七章 习题\tDQN算法实战\tDouble DQN,Dueling DQN,PER DQN,Noisy DQN\n第八章 DQN (连续动作)\t第八章 习题\t\t\n第九章 演员-评论员算法\t第九章 习题\t\tA2C\n第十章 稀疏奖励\t第十章 习题\t\t\n第十一章 模仿学习\t第十一章 习题\t\t\n第十二章 深度确定性策略梯度 (DDPG) 算法\t第十二章 习题\tDDPG算法实战\tDDPG\n第十三章 AlphaStar 论文解读\t\t\t\n视觉强化学习论文清单(Awesome Visual RL)\t\t\t\n算法实战\n\n算法实战部分包括附书代码和JoyRL代码:\n\n蘑菇书附书代码\nJoyRL离线版\nJoyRL上线版\n经典强化学习论文解读\n\n点击或者网页点击papers文件夹进入经典强化学习论文解读\n\n扩展资源\n对强化学习玩我的世界(Minecraft)游戏感兴趣的读者,可阅读 LS-Imagine\n对视觉强化学习感兴趣的读者,可阅读Awesome Visual RL\n对深度学习感兴趣的读者,可阅读李宏毅深度学习教程LeeDL-Tutorial\n相关视频内容\n《Datawhale强化学习教程》出版\n蘑菇书起源与RL入门指南\n蘑菇书开源组队学习活动\n蘑菇书开源学习与成长\n贡献者\n\nQi Wang\n\n教程设计(第1~12章)\n上海交通大学博士生\n中国科学院大学硕士\n\n\t\nYiyuan Yang\n\n习题设计&第13章\n牛津大学博士生\n清华大学硕士\n\n\t\nJohn Jim\n\n算法实战\n北京大学硕士\n\n引用信息\n王琦,杨毅远,江季,Easy RL:强化学习教程,人民邮电出版社,https://github.com/datawhalechina/easy-rl, 2022.\nQi Wang, Yiyuan Yang, Ji Jiang,Easy RL: Reinforcement Learning Tutorial,Posts & Telecom Press,https://github.com/datawhalechina/easy-rl, 2022.\nCopy to clipboard\nError\nCopied\n@book{wang2022easyrl,\ntitle = {Easy RL:强化学习教程},\npublisher = {人民邮电出版社},\nyear = {2022},\nauthor = {王琦,杨毅远,江季},\naddress = {北京},\nisbn = {9787115584700},\nurl = {https://github.com/datawhalechina/easy-rl}\n}\nCopy to clipboard\nError\nCopied\n@book{wang2022easyrl,\ntitle = {Easy RL: Reinforcement Learning Tutorial},\npublisher = {Posts & Telecom Press},\nyear = {2022},\nauthor = {Qi Wang, Yiyuan Yang, Ji Jiang},\naddress = {Beijing},\nisbn = {9787115584700},\nurl = {https://github.com/datawhalechina/easy-rl}\n}\nCopy to clipboard\nError\nCopied\n\n如果您需要转载该教程的内容,请注明出处:https://github.com/datawhalechina/easy-rl。\n\n致谢\n\n特别感谢 @Sm1les、@LSGOMYP 对本项目的帮助与支持。\n\n另外,十分感谢大家对于Easy-RL的关注。 \n\n关注我们\n\n扫描下方二维码关注公众号:Datawhale,回复关键词“Easy-RL读者交流群”,即可加入“Easy-RL读者交流群”\n\nLICENSE\n\n\n本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。\n\nStar History"
}
]
结论:
不符合预期,只爬取了第一章的第一部分内容
3) dailymotion影视网站https://www.dailymotion.com/search/%E5%93%AA%E5%90%922/videos
配置如下:
import { Config } from "./src/config";
export const defaultConfig: Config = {
url: "https://www.dailymotion.com/search/%E5%93%AA%E5%90%922/videos",
match: "https://www.dailymotion.com/search/%E5%93%AA%E5%90%922/videos",
maxPagesToCrawl: 1000,
outputFileName: "dailymotion.json",
maxTokens: 2000000,
};
实践结果:
[
{
"title": "Dailymotion",
"url": "https://www.dailymotion.com/search/%E5%93%AA%E5%90%922/videos",
"html": ""
}
]
结论:
不符合预期,请求成功,但没有拿到url内容
4) PDF文件网站:清华大学云盘
配置如下:
import { Config } from "./src/config";
export const defaultConfig: Config = {
url: "https://cloud.tsinghua.edu.cn/f/b6c7766f06d44ed289f2/",
match: "https://cloud.tsinghua.edu.cn/f/b6c7766f06d44ed289f2/",
maxPagesToCrawl: 1000,
outputFileName: "cloud.tsinghua.edu.cn.json",
maxTokens: 2000000,
};
实践结果:
[
{
"title": "清华大学云盘",
"url": "https://cloud.tsinghua.edu.cn/f/b6c7766f06d44ed289f2/",
"html": "《”十五五“金融规划研究白皮书》.pdf\n\nShared by: 陈放\n\nThumbnailsDocument OutlineAttachmentsLayers\nToggle Sidebar\nFind\nPrevious\nNext\nPresentation ModeOpenPrintDownloadCurrent View\nTools"
}
]
结论:
不符合预期,只拉取到标题,没有PDF的文件
5)Builder.io docs官方文档:
https://www.builder.io/c/docs/
配置如下:
import { Config } from "./src/config";
export const defaultConfig: Config = {
url: "https://www.builder.io/c/docs/developers",
match: "https://www.builder.io/c/docs/**",
selector: `.docs-builder-container`,
maxPagesToCrawl: 50,
outputFileName: "output.json",
};
实践结果:
[
{
"title": "How to make a Symbol",
"url": "https://www.builder.io/c/docs/make-a-symbol",
"html": "Make a Symbol\n\nYou can use Symbols to create and control content that you can use in multiple places throughout your app. This article guides you through creating and updating a Symbol.\n\nPrerequisites\n\nTo get the most out of this document, make sure you are familiar with the following:\n\nReusing blocks: get to know the different types of reusable blocks, which include Symbols.\nIntroduction to Symbols\nOpening and editing Symbols\n\nThe following video covers the process for creating a Symbol, and below the video the steps are outlined.\n\nCreating a Symbol\n\nTo create a Symbol:\n\nSelect the block you'd like to convert to a Symbol and click on the arrow next to the Edit button.\nClick Convert to Symbol.\nIn the dialogue, name your Symbol and leave the Model field with the default Create Symbol Model text.\nClick the Convert button.\n\nYour Symbol is ready to use throughout your Space.\n\nTip: If you've created your Symbol through the Models section, rather than converting a Block as in this article, you must Publish your Symbol to make it available for use.\n\nUpdating Symbols\n\nEdit your Symbol by selecting Edit and then the Edit Symbol button.\n\nThe Symbol opens so you can make your changes.\n\nTo Publish, select the green Publish button in the upper right of the Symbol.\n\nUsing a Symbol\n\nTo use your new Symbol in a page, in the Insert tab, select the My Symbols tab and drag and drop your Symbol block onto the page."
},
{
"title": "Creating a Private Model",
"url": "https://www.builder.io/c/docs/private-models",
"html": "Create a Private Model\n\nWhen you need a model that is only privately accessible, you can adjust the configuration of your model, use a Private API Key, as well as the Content API to ensure privacy.\n\nMake a model private\n\nBy default, Builder Page, Section, and Data models are publicly readable.\n\nWhen setting a model to be private, consider whether you want all entries of that model to be private. If some of them need to be publicly readable, create a model specifically for private content entries.\n\nTo make a model private:\n\nGo to Models.\nOpen your page model.\nGo to Advanced.\nSwitch the Public Readable toggle to off.\nClick Save.\nCreate content entries from this model for any that you'd like to be private.\n\nThe following video shows how to toggle off the Public Readable setting for a Page model, but you can change this setting on any kind of model.\n\nCreate a Private API Key\n\nTo leverage a private model, you need to create a Private API Key in your Organization Settings. Follow the instructions in the Managing Private Keys section of the API Keys documentation.\n\nWhen you have your Private API Key, continue with the instructions below.\n\nAdd the code\n\nUse the Content API with your Private API key with the following code, where you replace these values with your own:\n\nmodelName\nyourPublicAPIKey\nyourPrivateAPIKey\nlet apiUrl = 'https://cdn.builder.io/api/v3/content'\nlet modelName = 'private-page'\nlet content = await request(`${apiUrl}/${modelName}?apiKey=${yourPublicAPIKey}&limit=1&userAttributes.urlPath=/some-page`, {\n headers: { Authorization: `Bearer ${yourPrivateAPIKey}` },\n})\n\n\nNext, pass the JSON to render as needed; for example as in this React snippet for a model named private-page:\n\nlet page = content.results[0];\n\nif (page) {\n return <BuilderComponent model=\"private-page\" content={page} />\n}\n\nWhat's next\n\nModels are a foundational part of Builder that you can customize to countless use cases. For more information on what you can do with models, refer to the following documentation:\n\nUsing Custom Fields: You can edit or create many kinds of custom fields on models with a variety of types.\nTargeting and Scheduling: Get the right content to the right people at the right time."
},
{
"title": "Content API",
"url": "https://www.builder.io/c/docs/content-api",
"html": "Content API\n\nWith the Content API, you can make requests to retrieve data about any of your models within Builder. The Content API supports advanced query filtering with URL parameters to help you get exactly the data you need.\n\nUse cases for querying data could include searches, populating content for a collection, or getting all links that meet certain criteria.\n\nTo access this data, write queries with dot notation and, optionally, MongoDB style operators.\n\nFor more details on querying, see the Querying Cheatsheet.\n\nSet up\n\nTo start using the Content API, make sure to import the Builder SDK into your project.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nAt the command line, use npm to install the Builder SDK:\n\nnpm install @builder.io/react\n\nIn your code, be sure to import the SDK:\n\nimport { builder } from \"@builder.io/react\";\nQuery requirements\n\nTo use the Builder Content API to retrieve data from your models, be sure to always provide the following request parameters in your queries:\n\nRequired: my-model-name (replace with your model's name)\nRequired: apiKey query param (replace with your Public API Key)\n\nAs an example, you'd replace my-model-name with the name of your model, such as page, and YOUR_API_KEY with your own Public API Key.\n\nhttps://cdn.builder.io/api/v3/content/my-model-name?apiKey=YOUR_API_KEY\n\nYou can learn about the response structure using the Builder API Explorer.\n\nContent API query params\n\nThis section covers the available Builder Content API query params.\n\napiKey\n\nUse your API key when integrating with Builder.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\nbuilder.init(YOUR_API_KEY);\n\nenrich\n\nSet it to true include references and Symbols in the response, ensuring consistency between the Visual Editor and the live site.\n\nFor more information on enrich, read Fetching References and Symbols with enrich.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('model', {\n ...\n options: { enrich: true }\n ...\n})\n\nquery\n\nMongoDB style query of your data.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from '@builder.io/react'\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n query: {\n id: 'abc123',\n data: {\n myCustomField: 'someValue',\n someNumber: { $ne: 2 }\n }\n }\n}\n\n// to get all entries from a page model that are using a specific symbol\n// where SYMBOL_ID is your Symbol's ID\nconst entry = await builder.get('page', {\n query: {\n 'meta.symbolsUsed.SYMBOL_ID': true\n }\n});\n\n\nBuilder supports the following operators: $eq $gt $in $lt $lte $ne $nin $and $not $or $nor $exists $type $elemMatch $gte $regex $options. For more information, including examples, see the Builder Querying Cheatsheet.\n\nuserAttributes\n\nUse it to specify targeting attributes, such as urlPath, device, and any of the defined custom targeting, to fetch the most relevant entry when the model contains multiple entries.\n\nBy default, the response is limited to one entry. Without targeting attributes, it will only include the topmost entry.\n\nFor more details on User Attributes, read targeting content.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n userAttributes: {\n urlPath: '/about',\n device: 'desktop',\n userLoggedIn: true\n },\n})\n\nfields\n\nOnly include the specified fields from the response.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n fields: 'id,name,data.customField'\n})\n\nomit\n\nExclude only specific fields from the response and return everything else.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n omit: 'data,bigField,data.blocks'\n})\n\nlimit\n\nMax number of results to return. The default is 30 and the maximum is 100.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entries = await builder.getAll('my-model-name', {\n limit: 10\n})\n\noffset\n\nUse to specify an offset for pagination of results. The default is 0.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n offset: 10\n})\n\n\nTo fetch all content beyond the limit of 100, use limit and offset together by paginating results and making multiple API calls as follows:\n\nconst limit = 100;\nlet offset = 0;\nconst pages = await getResults({limit, offset});\nwhile(pages.length === (limit + offset)) {\n offset += pages.length;\n pages.push( ... (await getResults({ limit, offset})));\n}\nreturn pages;\n\nFor more detail, see this forum post and this forum post.\n\nincludeRefs\n\nInclude content of references in response.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n includeRefs: true\n})\n\ncacheSeconds\n\nSeconds to cache content. This sets the maximum age of the cache-control header response . Set value higher for better performance, and lower for content that changes frequently.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n cacheSeconds: 10\n})\n\nstaleCacheSeconds\n\nBuilder uses stale-while-revalidate caching at the CDN level, serving content from the edge cache while updates occur in the background for optimal performance.\n\nThe more frequently content is requested, the fresher it becomes. By default, Builder holds content in the stale cache for up to one day, but you can adjust this to a shorter duration if needed.\n\nWe recommend keeping this duration high unless you have low-traffic content that must update rapidly.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n staleCacheSeconds: 86400\n})\n\nsort\n\nUse the property to order results by setting the value to 1 for ascending and -1 for descending.\n\nThe key specifies the field to sort on. For example, sorting by createdDate with a value of 1 results in ascending order.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n sort: {\n createdDate: 1\n }\n})\n\nincludeUnpublished\n\nInclude content entries in a response that are still in draft mode and unarchived.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n includeUnpublished: true\n})\n\nnoTraverse\n\nThough the default is true, you can pass false to include Symbol JSON in the response. This is helpful if you want to render your page all at once such as in server-side rendering.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n noTraverse: false\n})\n\ncachebust\n\nSet this to true to ensure you get the most up-to-date data. This may be particularly relevant for frequently changing content or situations where updated information is preferred.\n\nThis will bypass the default cache settings. Note that as a result response times will be significantly slower when using this option.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n cachebust: true\n})\n\n\nOnly set cachebust to true in the SDKs or APIs for build-time requests, such as when statically generating Pages, as response times will be slow when bypassing all caching. We do not recommend it for runtime requests — such as when serving Pages.\n\nfetch\n\nUse the fetch option to override the default behavior of the global fetch() function used in the API.\n\nThis is helpful for:\n\nAdding specific headers or handling authentication\nUsing libraries like Axios\nDefining custom HTTP request logic, such as integrating custom agents\n\nThe fetch property expects a function with the same parameters as the global fetch() function. It takes url.href as the first parameter and optionally a configuration object as the second.\n\nFor more information, see fetch() parameters.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nThe fetch option does not apply to Gen 1 frameworks.\n\nfetchOptions\n\nSpecifies additional RequestInit options to configure the overridden fetch request, including:\n\nheaders for custom request headers\ncredentials to control authentication\nkeepalive for background requests and sending analytics\nmethod to define the HTTP method\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { builder } from \"@builder.io/react\";\n\nconst MyFetchOptions: RequestInit = {\n method: \"GET\",\n cache: \"no-cache\", \n keepalive: true // Ensures the connection remains open for reuse\n}\n\n// replace model with your model name\nconst entry = await builder.get('my-model-name', {\n fetchOptions: MyFetchOptions\n})\n\n\nContent API v3 is currently the default. Learn more in Content API Versions.\n\nTo experiment with the Content API, you can use the Builder API Explorer, which offers a way for you to compose queries in your own Builder Space. This way, you can confirm that your queries are correct before editing your code base.\n\nBuilder API Explorer"
},
{
"title": "Settings",
"url": "https://www.builder.io/c/docs/settings#organization-settings",
"html": "Settings\n\nThere two levels of Settings, Organization and Space. By changing settings at the appropriate level, you can manage many settings for your Organization and for individual Spaces.\n\nThis document covers how to get to Organization and Space Settings, and includes links to related documentation on the many features available in Settings.\n\nOrganization Settings\n\nThe Settings section of your Builder account is where you manage your Organization, your Space(s), and users.\n\nTo get to your Organization Settings:\n\nLogin to Builder.\nEnter your Organization.\nClick on the Settings icon at the bottom left of the UI.\n\nThe following video shows this process. In this case, the Organization is named Enterprise Docs demos, a space we use for our documentation demo videos and screenshots.\n\nThe name of your Organization will likely be different. However, getting to your Organization Settings is the same, regardless of plan.\n\nFor more information, read the following documents.\n\nUnderstanding Organizations: a conceptual overview of what an Organization is.\nManaging Your Organization: a how-to guide for the most common Organization tasks.\nSpace Settings\n\nTo get to your Space Settings:\n\nLogin to Builder.\nEnter the Space you'd like to manage.\nClick on the Account Settings icon at the bottom left of the UI.\n\nThe following video shows this process. In this case, the Space is named My Favorite Space, a space we use for our documentation demo videos and screenshots.\n\nThe name of your Space will likely be different. However, getting to your Space Settings is the same, regardless of plan.\n\nFor more information, read the following documentation.\n\nUnderstanding Spaces: a conceptual overview of what a Space is.\nManaging Spaces: a how-to guide for the most common Space tasks.\nLogging out of your account\n\nTo log out of your Builder account:\n\nGo to Space Settings or your Organization Settings (either one works).\nClick on the cog icon at the upper right.\nSelect Log Out.\n\nThe following image shows where the Log Out option is in Settings:\n\nWhat's next\n\nThrough Account Settings, you can manage many settings, and fine tune Builder features for your team, including:\n\nOrganization\nSpaces\nUsers for your organization as well as your Space(s)\nRoles and Permissions\nPublic and Private API Keys\nSubscription\nBilling\nTargeting Attributes\nSocial Media integrations\nEnvironments"
},
{
"title": "Managing Your Organization",
"url": "https://www.builder.io/c/docs/managing-organizations",
"html": "Manage your Organization\n\nAn Organization is the top-most entity in Builder and contains users and Spaces.\n\nView and edit account details\n\nBuilder creates your first Organization automatically the first time you sign in.\n\nTo view or edit account details for your Organization, go to the Organization's Settings. With Admin permissions, you can:\n\nEdit the name of an Organization\nEdit and view billing information\nAccess private key information\nView invoices\nManage users\n\nThe following image is a screenshot of the Organization-level Settings, which features the Organization tab with account information and users, as well as the My Profile tab, which includes information about the name of the Organization and user account info. This document discusses each section in detail.\n\nManage Spaces\n\nOrganizations contain Spaces. This means that you can access high-level data about a Space or create new a Space from within your Organization.\n\nAdd a Space\n\nTo view all the spaces in an Organization, along with the number of users, bandwidth, and Visual Views for those Spaces:\n\nGo to the Organization's Spaces tab.\nTo optionally filter data on the available spaces, click the three dots at the upper right and select a month and year.\nTo create a new Space within this Organization, click the + New Space button. Each space will have separate content, separate models, and separate Public API Keys.\n\nYou can also create a new Space by going to your Organization using the fly-out menu. Under your Organization, click + New Space.\n\nThe video below shows creating a new Space called My New Space :\n\nArchive Spaces\n\nTo remove a Space from an Organization, you must archive that Space. Visit the Archiving a Space instructions in Managing Spaces.\n\nManage payment and billing\n\nTo manage payment and billing information for your Organization:\n\nGo to the Organization Settings.\nTo the right of Payment, click Add Payment Info to add a credit card or Update Billing Info as required.\n\nSelf-Service customers can pay for the subscription with American Express, MasterCard, and Visa credit cards. Enterprise customers have the option of paying with ACH or wire transfer.\n\nView invoices\n\nTo view invoices, or billing history, for your Organization:\n\nGo to the Organization Settings.\nTo the right of Invoices, click View.\nAccess invoices for Enterprise, Shopify, and Legacy plans\n\nEnterprise plans\n\nIf you need to change payment methods or access invoices, contact finance@builder.io.\n\nBuilder invoices for Shopify app users\n\nYou can find billing and invoices through Shopify's billing platform. Review your Shopify invoice to see any Builder charges.\n\nLegacy plans\n\nFor older accounts on legacy self-serve plans that only have a single space, you can see invoices within the Space Settings.\n\nManage your billing and tax information\n\nTo update your billing and tax information — such as Tax ID or Tax Type — for your Organization:\n\nGo to the Organization Settings.\nOn the Payment line, click Update Billing Info.\nManage Private API Keys\n\nPrivate API Keys help you keep certain content private. For detailed information on Private API Keys, see the Managing Private API Keys section of Using Builder API Keys.\n\nManage users\n\nYou must have users at the Organization level as well as in the Space they work in. Set up your users in this order:\n\nSet up your users in the Organization.\nSet up your users in the Space you want them to access.\n\nFor detailed instructions, see Managing Users.\n\nView Organization insights\n\nenterprise plans\n\nViewing the contents of the Insights tab for an Organization is an add-on feature available on the Enterprise plan.\n\nWhen this feature is enabled, Admins can access data such as who the most active users are, which, for example, can inform re-allocating user licenses based on activity.\n\nAdmins for the Organization have access to the Organization Insights, accessible from the Builder left sidebar. Organization Insights show you, by Space:\n\nUser names\nUser e-mail addresses\nUser role\nLast sign-in date\nCreation date\nLast refresh date\nDelete an Organization\n\nIf you need to delete an Organization, contact us.\n\nWhat's next\n\nTo learn more about what's inside an Organization, see Roles and Permissions, Settings, and Spaces.\n\nIf you want to jump right in, visit Popular Tutorials."
},
{
"title": "Get around Builder with the Command Palette",
"url": "https://www.builder.io/c/docs/command-palette",
"html": "Get around Builder with the Command Palette\n\nGetting around Builder quickly can help you make the most of your time while working. Using the keyboard shortcut Cmd/Ctrl+k to open the Command Palette, you have direct access to Builder's most in-demand features.\n\nThe video below demonstrates one of the many Command Palette shortcuts, toggling the code editor.\n\nThis document covers:\n\nCommand Palette shortcuts\nUsing the Command Palette\nCommand Palette shortcuts\n\nTo search for content, grab key info, or navigate to any part of Builder use the Command Palette. You can directly and immediately access these features:\n\nToggle Dark Mode and Developer Options\nGo to the different sections of the Builder UI, such as Account Settings, or the Models section\nCopy your Public API Key\nSwitch to another Organization or Space\n\nWithin a content entry, the Command Palette has additional options specific to the Visual Editor including:\n\nImporting from web\nToggling the code editor, console, JSON view, templates\nDuplicating the current content entry\nLaunching Responsivizer\nImporting liquid\nViewing liquid output\n\nSelecting any of the suggested options in the Command Palette opens that section of Builder or feature.\n\nUsing the Command Palette\n\nWith the Command Palette you can immediately jump from one part of Builder to another, whether it be your content, areas of Builder — such as Account Settings or the documentation — or even launch Builder features such as JSON view or the code editor. To use the Command Palette:\n\nPress Cmd/Ctrl + k.\nType in your query or scroll to the option.\nPress Enter.\n\nTo filter content entries, type the word go followed by the name of the content entry; for example: go about, where the name of the entry you're searching for is \"about\".\n\nThe following video gives a brief demo of using the Command Palette to pull up a content entry in the Builder documentation called \"Breakpoints\", jump to the docs, copy your Public API Key, and toggle JSON view.\n\nWhat's next\n\nFor more on making the most of your workflow, visit:\n\nKeyboard shortcuts\nOrganize content with folders"
},
{
"title": "Introduction to Symbols",
"url": "https://www.builder.io/c/docs/symbols-intro?_host=www.builder.io",
"html": "Intro to Symbols\n\nWhen you want to create one element, reuse it throughout your site, and update all instances at once, use a Symbol. When you edit and Publish updates, the Symbol updates apply immediately to all occurrences of that Symbol throughout your app.\n\nYou can use Symbols for any content you want to reuse, such as a header, footer, or products. In fact, you can use it for repeated content that you want to use many places, such as a definition, an introductory paragraph or even a section of illustrated code.\n\nMake it once, reuse infinitely\n\nSave time by creating reusable elements such as headers, footers, navigation, and forms. Updates apply automatically to all instances of your Symbol.\n\nTo create your own Symbol, see How to create a Symbol.\n\nCustomizing your Symbols\n\nOccasionally, you might require an element like a product recommendation section or banner that needs to vary under specific conditions. In such cases, you can detach a Symbol from its source, Making a Symbol inline, which converts it into a standard Builder block. This way you can make inline changes for that particular instance.\n\nFor more on customizing Symbols, visit Adding Inputs to Symbols.\n\nTip: For a reusable component that you can edit individually, see Creating Templates. Templates are like Symbols, but when you edit a Template on a page, the other instances of that Template don't change.\n\nAdding a symbol to another account\n\nAt this time, you cannot transfer a symbol from one account to another. One workaround is to download your symbol and upload it to your other account.\n\nOpen the symbol you want to copy.\nRight click on the symbol and select Download content as JSON.\nCreate a new page in your other account, right click in the editor window, and select Upload builder.json file."
},
{
"title": "Intro to Models",
"url": "https://www.builder.io/c/docs/models-intro",
"html": "Intro to Models\n\nA model is a paradigm—a pattern for something else. Builder offers three kinds of models that define content types:\n\nA Page model: the basis for a full Page built in Builder\nA Section model: the basis for a part of a Page\nA Data model: gives structure to a collection of data that you render as you choose\n\nYou use these models as the defining source for content entries. Like a rubber stamp, the model provides a basic foundation. Each time you use a rubber stamp, the fundamental characteristics are the same but you might use the resulting image differently by varying other factors such as color and surface.\n\nSimilarly, with models in Builder you can define what a Page, Section, or collection of Data is and use those models over and over to build your site and populate it with content. And you can create as many models as you like.\n\nThe following graphic compares Builder models. Follow the Try it out link to play with a demo of each.\n\nVisual Pages\n\nTry out Pages\n\nUse Pages to manage entire pages, such as:\n\nMarketing and content pages\nLanding pages\n\nVisual Sections\n\nTry out Sections\n\nenterprise plans\n\nUse Sections to maintain parts of your site or app, such as:\n\nAnnouncement bars\nProduct editorial\nCollection heroes\nCart upsells\n\nStructured Data\n\nTry out Data\n\nUse Structured Data to manage structured data, such as:\n\nNavigation links\nProduct details\nBlog post authors\n\nAll models in Builder support:\n\nA/B Testing: Test different versions of your content.\nTargeting: Deliver specific content to the right people.\nScheduling: Publish your content at the right time.\nRoles and Permissions in a Space: Admins and Developers can edit models by default, but you can also specify permissions by content model using Custom Roles.\n\nThis means that you can granularly grant permissions, test, and precisely deliver content.\n\nExplore common integration patterns:\nLanding pages\nBlog Article\nHero Section\nNavigation Links\nAnnouncement Bar\nProduct Details\nProduct Editorial\nHomepage\nUse models to build your app\n\nWhen you use models to build your app, you can create exactly the Pages, Sections, and Data specific to your use case. With your integrated app, you can, for example, use your Sections in the Pages you choose as well as reuse Data wherever you need it.\n\nExamples of models include:\n\nA seasonal announcement banner placed on a page between certain dates.\nMarketing tile targeting a specific persona on certain pages.\nBlog authors whose profiles you want to link to from different parts of your site.\n\nBy creating models for each type of content you need, you can ensure consistency while making the process of iterating more efficient. The developer creates and integrates a model and non-developer teammates can use that model to create as many content entries as they need.\n\nThe following diagram shows a typical Builder documentation page. The left side navigation is a Section, the body of the document is a Page, and the font colors are stored in a Data content entry.\n\nComparing models\n\nWhen deciding which model to use, consider your use case.\n\nUse a Page model if you're creating Pages that use URLs and you want your teammates to edit them in the Visual Editor.\nUse a Section Model if you're creating parts of a page — with or without a URL — and you want your teammates to edit them in the Visual Editor.\nUse a Data Model if you want to bring your data into Pages or Sections and bind your data.\n\nAll models support structured data fields. The table below compares models in Builder to help you decide which to use when:\n\nModel Type\tPurpose\tRequires URL\tEditable in Drag-and-Drop Visual Editor\tSupports Structured Data Fields\n\nPage Model\n\n\t\n\nUse to create Pages\n\n\t\n\nYes\n\n\t\n\nYes\n\n\t\n\nYes\n\n\n\n\nSection Model\n\n\t\n\nUse to create Sections\n\n\t\n\nOptional, but most use cases don't need a URL.\n\n\t\n\nYes\n\n\t\n\nYes\n\n\n\n\nData Model\n\n\t\n\nUse to manage data\n\n\t\n\nN/A\n\n\t\n\nWhile you can use your Data in the Visual Editor, you must edit the data in the Data entry.\n\n\t\n\nYes\n\nWhat's next\n\nTo get the most out of Builder Models, be sure to integrate and learn about each type of model:\n\nPage Model: Learn what a Page model is and how to use one.\nIntegrating Pages: Integrate Page building with your code base so non-dev team members can create as many pages as they need and developers can focus on code.\nSection Models: Learn about Section use cases and how to use Sections in your app.\nIntegrating Sections: Integrate Builder Sections with your codebase so teammates can create and use Sections wherever they need them.\nData Models: Give shape to data and learn how to query that data.\nIntegrating CMS Data: Integrate data to create reusable data across your site.\nCustom Fields: Learn about the wide array of options available for shaping your models."
},
{
"title": "Live Previewing Data Models and Custom Fields",
"url": "https://www.builder.io/c/docs/previewing-data-models",
"html": "Live preview Data models and custom fields\n\nWith the React SDK, you can use live previews to render edits in your data model without publishing them.\n\nAlthough you can fetch Builder's Data Models using Content API directly like a typical API resource, with the <BuilderContent> component, you can use features such as live editing, previewing, and A/B testing of your Data Models within the Builder Visual Editor, all while using standard JS/TS syntax.\n\nPrerequisites\n\nTo get the most out of this document, you should already be familiar with:\n\nPage building or Section building\nData Models\nIntegrating Structured Data\nImportance of using live preview\n\nLive preview is crucial when working with custom fields, data models, and structured data in Builder. It offers several benefits.\n\nReal-time updates by displaying changes immediately in the Visual Editor without publishing.\nImproved user experience to meet your expectations with an intuitive experience.\nIterate more quickly on your content and designs more efficiently.\nMake sure your Sections, Pages, and structured data are exactly as intended before publishing.\n\nLive previewing can support a smoother experience, with changes in Custom Fields, Data Models, or Structured Data updates in real-time.\n\nLive preview examples\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nSpecify the name of your data model in BuilderContent with the model prop.\nUse a render prop pattern with the required data, an optional loading, and fullData parameters in case of SSR.\nAdd code that accesses your data in the return() statement. This code varies and depends on your use case.\nSet the Preview URL on the data model. For detailed instructions on setting a Preview URL on a model, visit the Setting a persistent Preview URL on a model in Editing and Previewing Your Site.\nTest the live preview by editing your data model in the Builder Visual Editor and checking that the changes are reflected in your application.\n\nThe following snippet shows this structure.\n\n// Add your data model's name\n<BuilderContent model=\"YOUR_DATA_MODEL\"> \n // add function to render data\n {(data, loading, fullData) => {\n if (loading) return <div>Loading...</div>;\n return (\n // Add your code to access your data\n );\n }}\n</BuilderContent>\n\nCustom fields in a blog post\n\nThis example uses a custom data model named blog-article, which includes a title, author, handle, and publishedDate fields, each of type text.\n\nThe component calls builder.get() to retrieve the published entry from the blog-article model by matching the urlPath to the route parameter.\n\nThe retrieved data is passed to BlogArticle component as a prop.\n\nimport { useEffect } from \"react\";\nimport { builder, BuilderContent, useIsPreviewing } from \"@builder.io/react\";\nimport { useParams } from \"react-router\";\nimport BlogArticle from \"./BlogArticle\";\n\nbuilder.init(/* ADD YOUR PUBLIC API KEY HERE */);\n\ntype ArticleData = {\n title: string;\n description: string;\n author: string;\n};\n\ntype Article = BuilderContent & {\n data: ArticleData;\n};\n\nexport default function BuilderPage() {\n const isPreviewingInBuilder = useIsPreviewing();\n const [notFound, setNotFound] = React.useState(false);\n const [content, setContent] = React.useState<Article | null>(null);\n const { slug } = useParams();\n\n // get the page content from Builder\n useEffect(() => {\n async function fetchContent() {\n const content = await builder\n .get(\"blog-article\", {\n url: slug,\n })\n .promise();\n setContent(content);\n setNotFound(!content);\n\n if (content?.data.title) {\n document.title = content.data.title;\n }\n }\n fetchContent();\n }, [slug]);\n\n if (content === null) {\n return;\n }\n\n if (notFound && !isPreviewingInBuilder) {\n return <div>404 Page Not Found</div>;\n }\n\n return (\n <>\n {/* Render the Builder page */}\n <BlogContent article={content} />\n </>\n );\n}\n\n\nThe fetched article data is passed to the <BuilderContent> component for rendering. The inline function used within <BuilderContent> accepts the following parameters:\n\ndata (required) – The resolved data from the blog-article model. If A/B testing is active, <BuilderContent> automatically serves the winning variant without additional setup.\nloading (optional) – A boolean indicating whether the data is still loading.\nfullData (required for SSR) – Includes all raw data from the Content API, such as A/B variations and metadata. In client-side rendering, <BuilderContent> fetches the most recently published entry of the specified model if the content prop is not provided.\n//app/src/components/BlogArticle.tsx\n\nimport {\n BuilderComponent,\n BuilderContent,\n useIsPreviewing,\n} from \"@builder.io/react\";\n\ntype ArticleData = {\n title: string;\n description: string;\n author: string;\n};\n\ntype Article = BuilderContent & {\n data: ArticleData;\n};\n\nexport default function BlogContent({ article }: { article: Article }) {\n const isPreviewing = useIsPreviewing();\n if (!isPreviewing && !article) {\n return (\n <>\n <div>404 - Page Not Found</div>\n </>\n );\n }\n return (\n <>\n <BuilderContent\n content={article}\n options={{ includeRefs: true }}\n model=\"blog-article\"\n >\n {(data, loading, fullData) => {\n return (\n <>\n <!-- data coming from the blog-article data model -->\n <div>Blog Title: {data.title}</div>\n <div>Blog Author: {data.author}</div>\n <div>Blog handle: {data.handle}</div>\n \n {loading && <div>Loading...</div>}\n \n <!-- You can render builder components from Page/section model -->\n <BuilderComponent\n content={article}\n model=\"page\"\n options={{ includeRefs: true }}\n />\n\n <div>Published Date: {data.publishedDate.Default}</div>\n </>\n );\n }}\n </BuilderContent>\n </>\n );\n}\n\n\nFields such as title, author, handle, and publishedDate update in real time within the Visual Editor and do not require a publish action.\n\nThe <BuilderContent> component enables dynamic visual layouts for content entries and supports drag-and-drop editing.\n\nAn example with navigation links\n\nThis example uses a custom data model called site-settings, which includes a navigationLinks field of type list. Each link contains a linkURL and linkText sub-field.\n\nimport { BuilderContent } from \"@builder.io/react\";\n\nexport const Navigation = (props) => {\n return (\n <BuilderContent model=\"site-settings\">\n {(data, loading, fullData) => {\n if (loading) {\n return <div>Loading...</div>;\n } else {\n return (\n <>\n <ul>\n {data?.navigationLinks?.map((link) => {\n return (\n <div key={link.linkUrl}>\n <a target=\"_blank\" href={link.linkUrl}>\n {link.linkText}\n </a>\n </div>\n );\n })}\n </ul>\n {props.children}\n </>\n );\n }\n }}\n </BuilderContent>\n );\n};\n\n\nThe BuilderContent component uses the site-settings data model to fetch the most recent published entry of the provided model for rendering.\n\nThe inline function provides three parameters:\n\ndata (required): The resolved data from the site-settings model is the structured data from the most recent entry. If A/B testing is active, <BuilderContent> automatically serves the winning variant without additional setup.\nloading (optional): A boolean indicating whether the data is still loading.\nfullContent (required for SSR): Includes all raw data from the Content API, such as A/B variations and metadata. In client-side rendering, <BuilderContent> fetches the most recently published entry of the specified model if the content prop is not passed.\n\nThe video below shows using this example data model in the Visual Editor:\n\nWhat's next\n\nFor more information on the variety of custom fields, visit Custom Fields."
},
{
"title": "Editing and Previewing Your Site",
"url": "https://www.builder.io/c/docs/guides/preview-url",
"html": "Editing and Previewing Your Site\n\nWhen you've integrated your app with Builder, you can edit and preview your site using a preview URL. Setting a preview URL gives you a way to develop and preview your site in the browser, just as you would any other site.\n\nTip: If you are using the HTML API to serve Builder content, follow the steps in the Previewing content on your site section of Builder HTML API to set up previewing for your content.\n\nPrerequisites\n\nTo get the most out of this document, you should have already completed the following:\n\nintegrated Page building or Section building\nPreview URLs work with all models\n\nYou can set a preview URL on a Page, Section, or Data model. Using a preview URL on any model gives you a way to render content and data to preview Pages, Sections, or Data while you're working.\n\nData Model Preview URLs\n\nLive editing and previewing works for Data Models when the content is rendered on your site, but it requires some basic configuration in your code. For detailed examples, visit Live Previewing Data Model and Custom Fields.\n\nSetting a persistent preview URL on a model\n\nWhen you're still building out your site before going live, you need to work locally for extended periods with the convenience of a persistent preview URL. In this scenario, you can set the preview URL on the model so that all content using that model is automatically configured with the preview URL.\n\nFor example, if you're creating pages and need to preview all pages on localhost, you can set the preview URL on the Page model to localhost so that all Page content has that preview URL of localhost.\n\nWhen your site is ready to go live, change the URL on the model to your staging or production URL.\n\nThe following video demonstrates opening a model and setting the URL.\n\nImpact of changing a model's Preview URL\n\nIf you change the preview URL of a model — for example, from a live URL that is in production to localhost — any content relying that model will no longer be live, and all parts of your app using that model will be affected.\n\nIf you need to set the URL on the model, you must be certain that no published content is using that model.\n\nSetting a temporary preview URL\n\nWhen developing your app, you can set a temporary preview URL that resets upon refresh or if you leave the Visual Editor.\n\nThe following video shows how to click on the preview URL in the Visual Editor and edit it. This method is helpful if you're working on a page that is currently in production but that you would like to develop further. In this example, the preview URL is http://localhost:3000/test-page; that is, the localhost with the name of the page url, here, /test-page.\n\nSetting a temporary preview URL host in Developer Options\n\nWhen you need to test out new changes or components in your local code across multiple content entries or models, it can be handy to override your preview URL host (e.g. from your production host, like your-site.com, to your localhost) for the duration of your session.\n\nThis can save you from entering a temporary URL repeatedly as you move across content models or entries, when you want to be connected to your localhost throughout.\n\nTo set a preview URL temporarily for just your session, without affecting other teammates, use the Developer Options as follows:\n\nIn the Visual Editor, press Cmd+Ctrl+a or ⊞ Win +Ctrl+a to open the Developer Options. You must have Admin or Developer permissions to open this dialogue.\nIn the Override preview URL host field, enter the preview URL you'd like to use. This example uses http://localhost:4200, but your URL might be different.\nClick the X to close the dialogue.\n\nThis setting takes effect for the duration of your session, or until you remove it.\n\nSetting the URL in Developer Options only affects the user who changes this setting, not other developers, teammates, or site visitors.\n\nThe following video demonstrates using Developer Options to set the preview URL to localhost.\n\nWhen working on static sites, such as with Gatsby, Nuxt, or Next.js in static mode, there is some additional configuration you might need to do to get your preview URL to render previews.\n\nBy default, when creating a page and editing it in Builder, the editor and preview loads the URL for that page. For example, if you create a new page at /example but your static site has no such page, you could get a 404. There are two options for this scenario:\n\nAdding the Builder component to your 404 page\nToggling off this behavior of previewing and editing on the specific URL for a page\n\nIf you're getting a 404, add the Builder component to your 404 page to support previewing and editing.\n\nOn your 404 page in your code base, add <BuilderComponent> as in the following code snippet. In this example, if the page isn't found, BuilderComponent still returns a Builder page, so Builder gets the message it expects and returns a page.\n\nimport { Builder, BuilderComponent } from '@builder.io/react';\n\nexport function NotFoundPage() {\n if (Builder.isPreviewing || Builder.isEditing) {\n return <BuilderComponent model=\"page\" />\n }\n\n return <Your404Page />\n}\n\n\nTo turn off the default behavior of previewing and editing on the specific URL for a page, do the following.\n\nGo to Account Settings > Advanced Settings > Advanced.\nToggle Reload preview on URL path change to the off position.\n\nYou can turn off this setting to load the preview and editor on your hardcoded URL; for example, /builder-editing, regardless of the current editor path.\n\nThe following video demonstrates how to turn off the Reload preview on URL path change setting:\n\nYou can add logic to Page and Section models to dynamically create the preview URL. For example, you can use a snippet like the below to preview blog posts:\n\n// Check to see if the content is live. If so,\n// use your site's URL followed by the \n// dynamic path you specify.\nif(contentModel.isLive) {\n return `https://your-site.com/your-directory/${content.data.slug}`\n}\n// If the site's not live, use a placeholder URL\nreturn `https://your-site.com/your-directory/__builder_editing__`\n\nYou can customize the Dynamic Preview URL logic on a model so that you can use features such as targeting, custom fields, and localization while previewing. For more details, refer to Dynamic Preview URLs.\n\nWhat's next\n\nIf you've integrated and followed all the instructions above but your iframe contents still aren't loading, check out Getting Your Preview URL Working."
},
{
"title": "Creating a Page",
"url": "https://www.builder.io/c/docs/create-page",
"html": "Popular Tutorials\n\n>\n\nHow to Create a Page\nCreating a Page\n\nThis tutorial is an introduction to creating a blank page, dragging in a template, previewing, and publishing. Perfect if you're new to Builder.\n\nSkill set: Basic\n\nArea: UI only\n\nLength: < 1 minute\n\nPrerequisites\n\nTo get the most out of this tutorial, you should have the following:\n\nYou'll need a Builder account.\nAn evergreen browser; that is, a modern, up-to-date browser such as Google Chrome.\nCreating a Page\nGo to Content.\nClick + New and select Page.\nName the page; for example, About. Builder auto generates a URL based on the name you provide, but you can customize the URL if you like.\nChoose a template or use the blank template and create a page from scratch.\nWhen your page is ready, click the Publish button.\nTo view your page, click the eyeball icon next to the Publish button and choose View current draft or View live page. If View Live Page isn't clickable, be sure that you've published.\n\nThe following video demonstrates creating and publishing a Page:\n\nTip: For step-by-step instructions on building a landing page inspired by Everlane, check out Making a Landing Page.\n\nBuilding with Templates\n\nWhile you can use blocks to build Pages (or Sections) as in the instructions above, you can also take advantage of Builder's pre-built Templates, which already feature design elements and layouts to help you get started faster.\n\nTip: Though this example uses a Page, you can use the same process to build Sections.\n\nGo to Content.\nClick + New and select Page.\nIn the Insert tab, open the Featured Templates section and drag in one or more templates.\n\nThe following video demonstrates creating and publishing a Page:\n\nBuilder comes with a built-in Page model for you to use. The Page model is what defines a Page. When you create a Page content entry, as this tutorial shows, Builder uses the Page model to determine the characteristics the Page content entry.\n\nThe default Page comes with a Title and Description field. If you need to edit the default Page model or create additional models, check out Intro to Models. Working with models is an ideal way for developers to define content paradigms that all team members can use."
},
{
"title": "Targeting Content",
"url": "https://www.builder.io/c/docs/targeting",
"html": "Targeting Content\n\nenterprise plans\n\nTargeting content for specific audiences can help you drive customer acquisition and retention.\n\nYou can target content based on attributes such as whether customers have purchased from a specific collection, their current product page, or if they have a product with a specific tag in their cart. These are just a few examples—there are endless possibilities for targeting.\n\nPrerequisites\n\nTo get the most out of this article, you should be familiar with Scheduling Content.\n\nTargeting options by plan\n\nTargeting options in Builder depend on your plan.\n\nAll plans come with the URL Path targeting attribute.\nPro and Enterprise plans offer both URL Path and Device targeting capabilities.\nWith Pro plans and above, can use your own Custom Targeting Attributes.\nBuilder provides e-commerce plugins for various platforms, each equipped with custom targeting attributes.\nAccessing targeting attributes\n\nTo use targeting:\n\nOpen the content entry for which you'd like to configure targeting.\nClick the Targeting icon at the top of the Visual Editor.\nIn the Targeting dialog, click +Target, and choose a property from the dropdown menu.\n\nAs an example, the following video shows targeting where the URL is /demo and the Device is mobile. This means this page is to be delivered when the device the visitor is using is a mobile device.\n\nTargeting by device with SSR? When using SSR or SSG, and targeting by device—such as mobile, tablet, or desktop—you must reference the targeted device in userAttributes as in the following example:\n\nuserAttributes: {\n ...\n device: \"mobile\"\n}\n\n\nFor more details on userAttributes, visit the userAttributes entry in the Content API documentation.\n\nFor a Next.js-specific example, refer to this example on GitHub for retrieving userAgent and device type server side.\n\nUsing order with targeting\n\nThe order of content entries in Builder determines how Builder evaluates and determines which content entry to deliver. Builder starts at the top of the list of entries at the specified URL and works its way down to find the entry to render.\n\nFor example, when you have multiple pages set up as alternatives for a specific targeting condition, they all share the same URL. When a user requests that URL, Builder checks each page in the list associated with that URL, starting at the top. The first page that meets the specified targeting condition is the version that is displayed to the user.\n\nExample\n\nConsider three versions of a homepage; home, home 2, and home 3. Each has different content, but they are all at the same URL, as in the following:\n\nhome 3, targeting mobile\nhome 2, targeting desktop\nhome (fallback), with no targeting\n\nHere's how Builder determines which Page to deliver:\n\nFirst, Builder considers all published Pages at the requested URL, /.\nIf home 3 has the Device targeting attribute set to Mobile, and your user visits yoursite.com from their phone, they get the content from home 3.\nIf home 2 targets Tablet, Builder delivers that Page to tablet users.\nThis example also has a fallback, home (fallback), just in case. It's a best practice to be sure all your conditions have a fallback Page in case none of the conditions are met.\n\nWhen you configure targeting, you establish a condition about a user and then deliver the appropriate content to that user. For example, you might want a user on a mobile device to have a different UI from a user on a laptop. Targeting statements follow the below pattern:\n\nWhere condition + operator + value\n\nBuilt-in conditions are:\n\nDevice\nURL Path\n\nSome examples of targeting statements are:\n\nWhere URL is /shoes\nWhere device is tablet\n\nThe operators available are:\n\nis means equal to the value\nis not means not the value. Available for conditions with one possible value; for example, a Boolean.\ncontains means the condition includes in it the string you specify for the value\nstarts with means the condition begins with the string you specify for the value\nends with means the condition ends with the string you specify for the value\n\nAdditionally, if you're on a Pro or Enterprise plan, you can customize targeting to meet your specific needs. For more information, read Custom Targeting Attributes.\n\nTargeting in-depth\n\nThe following video provides an in-depth introduction to targeting in Builder:\n\nFor more information targeting based on query parameters, visit this Builder Forum discussion.\n\nShopify custom attributes\n\nWith Shopify, Builder offers several ways to target content. For example, you can leverage your Shopify customer tags or if a user has specific items in their cart, you can display and even A/B test your content.\n\nDepending on the type of theme page you're working on, such as a homepage, a collection page, or a product page, Builder populates additional targeting parameters specific to the theme page."
},
{
"title": "Search Engine Optimization",
"url": "https://www.builder.io/c/docs/seo",
"html": "Search engine optimization techniques\n\nBy default, Builder pages offer a graphical UI for Search Engine Optimization (SEO). To take the best possible advantage of SEO with Builder.io content, make sure you provide metadata for search engines.\n\nSetting page metadata\n\nPage metadata is the data about your page that search engines use to display information in search results. For any page you publish, make sure that you include, at the very least, a title and description for your page.\n\nThe built-in Page model in Builder includes title and description fields by default. To specify a title and description on a page content entry made using the default Builder Page model:\n\nGo to Content.\nClick on the page to open it in the Visual Editor.\nIn the Options tab, expand the section titled Docs Content Fields.\nEnter the title and description for your page.\n\nThe following video demonstrates filling out the title and description metadata in a page created with the default page model in Builder:\n\nTo add additional fields to your page model, see the Adding custom fields to a model section of Custom Fields.\n\nRendering custom fields into your pages\n\nBy creating custom fields, you can render these fields into your Pages as needed. Consider the examples below for implementations of a title field:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n// Next.js example with SEO custom fields\nimport Head from \"next/head\";\nimport { builder, BuilderComponent } from \"@builder.io/react\";\n\nexport default class extends React.Component {\n static async getInitialProps({ res, req, asPath }) {\n const page = await builder.get(\"page\", { req, res }).promise();\n return { builderPage: page };\n }\n\n render() {\n const page = this.props.builderPage;\n return (\n <>\n <Head>\n <title>{page.data.title}</title>\n </Head>\n <BuilderComponent name=\"page\" content={page} />\n </>\n );\n }\n}\n\nReferencing dynamic values\n\nTo reference dynamic values in your SEO tags, use custom fields on the content. As an example, consider dynamically referencing product prices.\n\nBy referencing your external product through custom fields instead of hardcoding product prices, price updates propagate throughout your Builder content without the need for manually bulk editing content.\n\nFor more information, see the Write API documentation and Intro to Plugins.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nexport function getStaticProps() {\n const builderContent = await builder.get(\"page\" /*...*/).promise();\n // assumes there is a custom field called \"productReference\" that lets the user pick a product ID\n const productReference = await getProductInfo(builderContent.data.productReference);\n\n return {\n props: {\n productReference,\n builderContent,\n },\n };\n}\n\nexport default function Mypage(props) {\n return (\n <>\n <Head>\n <title>\n {props.builderContent.data.title} - ${props.productReference.price}\n </title>\n </Head>\n <BuilderComponent /*...*/ />\n </>\n );\n}\n\n\nTip: Other possibilities for custom fields for SEO include making file fields for meta tags such as og:image or boolean fields for flagging which pages should be crawled or not crawled using the meta robots tag.\n\nManaging indexing in Builder\n\nSometimes you want to link to or maintain content that doesn't need to inform your online presence. With Builder custom fields, you can customize your Page model, so non-coding teammates can specify settings such as nofollow and noindex, which tells search engines not to convey reputation or index your page, respectively.\n\nnofollow\n\nFor credibility, link to reputable and relevant sources outside your website. When you link to another site, you share some of your site's reputation with it.\n\nThe nofollow attribute prevents reputation transfer, which is useful when linking to user-added links in comments or mentioning sites negatively. It's also handy for third-party widgets that might add unintended links to your site, ensuring control over your site's reputation.\n\nIn code, you can include the <meta name=\"robots\" content=\"nofollow\"> tag in the head section of a page to apply nofollow to all its links.\n\nnoindex\n\nThe noindex rule, implemented through either a meta tag or an HTTP response header, prevents search engines like Google from indexing specific content. When Googlebot encounters this rule, it excludes the page from Google Search results, even if other sites link to it. It's vital that the page remain unblocked by a robots.txt file and remain accessible to the crawler to ensure the effectiveness of the noindex rule.\n\nFor more detail, read Google's Block Search indexing with noindex and Using the robots meta tag.\n\nExample: a noindex custom field\n\nIn your Page model, you can add as many custom fields as you like. Custom fields could include any meta robots tags of your choice such as the noindex or nofollow.\n\nWith Builder's custom fields, you can select the input type so a noindex or nofollow setting can be a toggle. This way, non-dev teammates can quickly adjust this setting on their own. With almost 30 available custom input types, you can add as many inputs (such as for metadata or directives) to your Page model as needed, along with default values, requirements, localization as well as helper text so you users have context.\n\nThe image below shows a custom input for a noindex toggle that Builder uses in its documentation when, for example, there's a little-used page that is being phased out but the content is still occasionally needed.\n\nThe first image is of the custom field in the Page model:\n\nThis second image is how the noindex toggle appears in the Visual Editor.\n\nTip: The index and follow directives are search engine defaults, so you don't need to specify them. You'd only specify noindex and nofollow if you wanted to toggle these settings off.\n\nCreating a sitemap\n\nTo create a sitemap based on your content, you first need to obtain the relevant JSON data. Here's an example of how to retrieve the JSON data for a Space we use for documentation demos:\n\nQuerying your content\n\nTo create a sitemap based on your content, you first need to obtain the relevant JSON data. Here's an example of how to retrieve the JSON data for a Space we use for documentation demos:\n\nhttps://cdn.builder.io/api/v2/content/page?apiKey=2b5ffc858d74425485135b88d2fc307a&fields=data.url&query.data.includeInSitemap.$ne=false\n\nFor your own JSON, replace the Public API Key with your Public API Key. With your JSON, you can now create your sitemap.\n\nThings to keep in mind:\n\nIf your sitemap is bigger than 50MB, create multiple sitemaps.\nTo impact all files on your site, place the sitemap at the root. To focus on a particular area, place it in specific directories.\nUse complete URLs, not slugs.\nUse canonical URLs.\nBuild out your URLs\n\nNow that you have your JSON, which includes all the Page slugs, create a script to write out all the URLs:\n\nconst pageUrls = pages\n .map((page) => page.data.url)\n\nThis snippet:\n\ntakes an array of page objects\nextracts the URLs of those pages using the map() function\ncreates a new array containing only the URLs\nCreate the XML file for your framework\n\nThe next part depends on your framework. You can create your sitemap manually or use a sitemap generator tool.\n\nHere's an example of an XML sitemap based on the documentation demo query:\n\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n <url>\n <loc>https://www.example.com/</loc>\n </url>\n <url>\n <loc>https://www.example.com/nextjs-test</loc>\n </url>\n <url>\n <loc>https://www.example.com/remix-test</loc>\n </url>\n <url>\n <loc>https://www.example.com/ai-demo</loc>\n </url>\n</urlset>\n\nFor more information, refer to Google's Build and submit a sitemap or your framework's documentation.\n\nBuilder doesn't use iframes or canvases when rendering content with the Builder SDK on your site. In this way, what you create in Builder is as optimized as the code your developers write."
},
{
"title": "BuilderComponent",
"url": "https://www.builder.io/c/docs/buildercomponent#code-render-link-code",
"html": "Using BuilderComponent\n\nThe BuilderComponent from Builder's Gen 1 SDK is how you specify where in your app you want to feature Builder content. It offers a number of props to help you specify exactly what to render in your integrated app.\n\nRecommended usage\n\nWhen using BuilderComponent :\n\nYou must specify the model.\nWe highly recommend that you also pass content.\n<BuilderComponent model=\"page\" content={contentJSON} />\nProps\n\nProps are key to customizing component behavior and managing content. With BuilderComponent props, you can define how the component interacts with Builder, control content sources, and pass necessary data or context.\n\nmodel\n\nrequired\n\nAlias: modelName\n\nUse to specify the name of the Builder model whose content this component is rendering. This is often a Page or Section model. If you had a model named announcement-bar, for example, you'd pass that in. In this example, the model is page.\n\n<BuilderComponent model=\"page\" ... />\n\nFor more information, visit Introduction to Models.\n\ncontent\n\noptional but recommended as a best practice\n\nExplicitly specify the Builder content JSON object to render. Helpful for server-side rendering or custom content fetching logic.\n\n<BuilderComponent model=\"page\" content={contentJSON} />\n\nFor more information, visit Content API.\n\ndata\n\noptional\n\nUse to pass custom data into the rendered Builder content. This is an object containing data passed to the Builder component, accessible in the Visual Editor. Enables dynamic content rendering by passing different data based on application state or user interaction.\n\n <BuilderComponent model=\"page\" data={{ myVar: 'Hello' }} />\n\nFor more information, visit Data Models and Building Interactivity Using State and Actions.\n\ncontext\n\noptional\n\nUse to provide an object available in actions and bindings inside Builder.io. Helpful for passing additional context or global data for use in Builder.io's actions and data bindings.\n\n<BuilderComponent model=\"page\" context={{ user: 'Marie Lorenzo' }} />\nstopClickPropagationWhenEditing\n\noptional, for advanced use cases\n\nSet to true to prevent event.stopPropagation() in the Visual Editor. This method is essential in scenarios where the default event propagation behavior interferes with intended interaction.\n\n<BuilderComponent model=\"page\" stopClickPropagationWhenEditing={true} />\nlocale\n\noptional\n\nSet the locale in your <BuilderComponent> as a prop to match one of the locale keys configured in Space Settings. This ensures localized inputs are automatically resolved based on the user's locale. To learn more, see Adding Locales.\n\nTo ensure content renders properly on your site, set the locale in both the builder.get() API call and the <BuilderComponent>.\n\n // 1. add the locale in builder.get()\nconst localizedContent = await builder\n .get(modelName, {\n // other fields\n\n // When content is localized through Targeting, \n // the locale should be passed to the userAttributes\n userAttributes: { locale: \"en-US\" },\n\n // When content is localized in-page, \n // the locale should be passed directly to the options\n options: {\n locale: \"en-US\"\n }\n }).toPromise();\n \n // 2. Pass the **locale** as a prop to provide component level context.\n <BuilderComponent locale=\"en-US\" model={modelName} content={localizedContent} />\n\nThis setup helps deliver content tailored to different languages and regions using locale-specific configurations. To learn more, see Content entry localization.\n\nMethods\n\nHelpful for advanced content handling and user interaction, BuilderComponent methods handle events and actions for advanced control and interactivity.\n\ncontentLoaded\n\noptional\n\nA callback function that is invoked when the Builder content is successfully loaded. Helpful for adding logic or state updates on load.\n\n<BuilderComponent \n model=\"page\" \n contentLoaded={(data, content) => console.log('Content loaded!', content)} \n/>\n\n\nFor more information, visit Building Interactivity Using State and Actions.\n\ncontentError\n\noptional\n\nA callback function that is invoked if an error occurs while fetching the content. Provides a way to handle errors gracefully, such as displaying a user-friendly message or fallback content.\n\n<BuilderComponent \n model=\"page\" \n contentError={(error) => console.error('Error loading content', error)} \n/>\n\nonStateChange\n\noptional\n\nA callback that runs when the Builder state changes, like from user interactions or dynamic content updates. In this way, your app can respond to dynamic changes in the application state for more interactive and responsive user experiences.\n\n<BuilderComponent \n model=\"page\" \n onStateChange={(newData) => console.log('State changed', newData)} \n/>\n\n\nFor more information, visit Building Interactivity Using State and Actions.\n\nrenderLink\n\noptional\n\nProvides a custom component for handling links throughout your Builder content. This prop is important for supporting client-side routing in single-page applications (SPAs), preventing full Page reloads when navigating between Builder Pages.\n\nYour custom link component can receive all attributes that an HTML anchor tag can receive, with href and target being the most common. Here are examples for React and Next.js:\n\nHere is an example for React:\n\n// React example\nfunction CustomLink(props) {\n return <a {...props} />\n}\n\n\nHere's a Next.js example:\n\n// Next.js example\nimport Link from 'next/link'\n\nfunction CustomLink(props) {\n return <Link {...props} />\n}\n\n\nThen use renderLink in BuilderComponent:\n\n<BuilderComponent \n model=\"page\" \n renderLink={(props) => <CustomLink {...props} />} \n/>\n\n\nYour custom link can receive all attributes that an HTML anchor tag, <a>, can receive, with href and target being the most common.\n\nrenderLink is equivalent to the linkComponent prop in Gen 2 SDKs. For details, visit the linkComponent entry in Using the Content Component.\n\nLegacy props\n\nWhile legacy props like builder, entry, and options are part of the component's history, their usage is no longer recommended. For optimal performance, use the content prop in conjunction with server-side data fetching with builder.get() as documented in Content API and in the Querying Cheatsheet.\n\nTheses legacy props are provided here only for reference.\n\nbuilder\n\nA specific instance of the Builder class.\n\n<!-- DO NOT USE -->\n<BuilderComponent builder={customBuilderInstance} />\nentry\n\nThe content entry ID to fetch for rendering.\n\n<!-- DO NOT USE -->\n<BuilderComponent model=\"page\" entry=\"your-entry-id\" />\noptions\n\nOptions for fetching content, including custom targeting and query parameters.\n\n<!-- DO NOT USE -->\n<BuilderComponent \n model=\"page\" \n options={{ cachebust: true }} \n/>\n\nWhat's next\n\nFor more information on fetching content, visit Content API."
},
{
"title": "Section Models",
"url": "https://www.builder.io/c/docs/models-sections",
"html": "Section models\n\nenterprise plans\n\nSection Models are the paradigm, or pattern, that defines what a Section is. When you make a Section content entry in the Content section of Builder, Builder uses the chosen Section model to create that Section content entry.\n\nIntegrate Builder Sections with your codebase\n\nWhen you integrate, non-coding team members can create as many Sections as they need for iterating, testing, targeting, and scheduling—leaving developers free to focus on the code.\n\nIntegrate Section Building\n\nAbout Section models\n\nA Section model describes a portion of a Page that your teammates can use in the Visual Editor. Use Section models to define editable parts of Pages, such as:\n\nAnnouncement bars\nMarketing sections on collection pages\nHeroes\nBlog posts\n\nLike Pages, you edit Sections in the Visual Editor's drag-and-drop interface. Unlike Pages, however, a URL is optional for Sections.\n\nAnd just like Page and Data models, Section models also support structured data fields.\n\nThe following image outlines an Add Block area of a Page. This area, a Section, is only a part of the Page.\n\nWith Sections, you can create your Section and then use targeting and querying to make it display in the right place at the right time. For more information, refer to Targeting Content and Scheduling Content.\n\nFinding Section models\n\nTo view the details of a Section model in a Space, do the following:\n\nGo to the Models section of the Builder UI.\nSelect the Section model.\n\nFrom within the Section model, you can edit and add fields. For details on fields in models, refer to Custom Fields.\n\nThe following video demonstrates the above steps for locating and opening a model. In this example, the Section model is named Blog article.\n\nCreate a Section model\nWhat's next\n\nModels are a foundational part of Builder that you can customize to countless use cases. For more information on what you can do with models, refer to the following documentation:\n\nUsing Custom Fields: You can edit or create many kinds of custom fields on models with a variety of types.\nTargeting: Deliver specific content to the right people.\nScheduling: Publish your content at the right time.\nLive Previewing Data Models and Custom Fields: Preview data and custom fields in your Sections."
},
{
"title": "Custom fields",
"url": "https://www.builder.io/c/docs/custom-fields",
"html": "Custom fields\n\nA field in Builder is a piece of data on a model. For example, the built-in Page model comes with two fields, a Title and a Description. These two fields help define what a Page is. Any time you make or edit any kind of model in Builder, you have the option of editing fields or adding custom fields.\n\nThe following video shows some example custom fields on the three kinds of models in Builder: the Page, Section, and Data models.\n\nPrerequisites\n\nTo get the most out of this document, make sure you've integrated Pages, Sections, or Data. The following tutorials give step-by-step instructions:\n\nIntegrate page building\n\nIntegrate section building\n\nIntegrate CMS data\n\nOverview of custom fields\n\nCustom fields are fields that you add to a model. You can add custom fields to models you create or to an existing model, such as the built-in Page model. All kinds of Builder models accept custom fields, so you can add the fields you need to Page models, Section models, and Data models.\n\nExamples of custom fields include data such as title, URL, name, timestamp, or any piece of data you want to define on a model. You define and specify aspects of your custom fields such as:\n\nType: There are many types available in Builder. Refer to Custom field types for more detail.\nLocalization: Translate fields according to region settings.\nDefault value: Pre-populate the custom fields you create.\nHelper text: Give your users a helpful hint about what to enter into the field.\nRequired: Make a field required or optional.\nEnum: Give users a predefined list of options.\nHidden: Make a given field hidden when editing content.\n\nThe following video shows where to find custom fields on a model, points out the available field Types, and then shows Page and Section custom fields in the Visual Editor's Option tab.\n\nAdd custom fields to a model\n\nTo delete a custom field, click the x to the right of the field.\n\nUse field values in your code\n\nTo interactively explore the data that is sent from the Builder API, check out the Builder API Explorer where you can query the Builder API using your actual data.\n\nFramework\nReact\n\nMeta-Framework\nNone\n\nSDK Generation\nGen 1\n\nimport { BuilderComponent, builder } from '@builder.io/react'\n\nexport const getStaticProps = async () => {\n const page = await builder.get('page', ...);\n return { props: { page } }\n}\n\nexport default ({ page }) => {\n return ( \n <MyLayout seoImage={page.data.seoImage} canonicalUrl={page.data.canonicalUrl}>\n // Your layout component that you pass in the custom fields\n <MyLayoutComponent showNavigation={page.data.showNavigation} layoutWidth={page.data.layoutWidth}>\n // Render the rest of the Builder page content\n <BuilderComponent model=\"page\" content={page} />\n </MyLayoutComponent>\n </MyLayout>\n )\n}\n\nCustom field types\n\nThe following table describes each Type in Builder along with an image of how each Type renders in the Builder UI.\n\nThis section covers the built-in types for models, but you can also make your own with plugins. For more information, see Make your own plugins overview.\n\nText\n\nText is analogous to the text type in HTML. With the Text type, you can specify minimum and maximum length.\n\nSelect\n\nCreates a select in content entries. With a select, teammates can choose from options you provide.\n\nLong Text\n\nLong Text accommodates multi-line text. With the Long Text type, you can specify minimum and maximum length.\n\nURL\n\nThe URL Type accommodates a URL, also known as a web address.\n\nFile\n\nUse the File Type to specify what kind(s) of file a user may upload to a custom field.\n\nNumber\n\nThe Number file type specifies that the value that the user enters must be a number.\n\nBoolean\n\nThe Boolean Type provides a toggle for a true/false setting.\n\nRich text/HTML\n\nThe Rick text/HTML Type provides a rich text interface with styling options and a toggle to write directly in HTML. Click the code icon, <>, at the upper right to toggle the HTML editor.\n\nDate\n\nUse the Date Type to accept a date from the user. When the user clicks on the input, a datepicker opens\n\nTimestamp\n\nUse the Timestamp Type to accept a date from the user. When the user clicks on the input, a date picker opens with a time picker. Though the Date and Timestamp Types appear similar, prefer Timestamp querying.\n\nColor\n\nUse Type Color to provide users with a color picker.\n\nList\n\nUse the List Type when for a series of items.\n\nReference\n\nUse the Reference type when you have Data entries that users choose from. For example, you could have a Blog Author custom field and when you click the Choose Entry button, all Blog Author Data entries display.\n\nMap\n\nText\n\nUse the Map type when you want users to provide a collection of key-value pairs.\n\nJavaScript\n\nUse the JavaScript type so users can provide JavaScript code snippets.\n\nCode\n\nText\n\nUse the Code type for accepting JavaScript, HTML, CSS, or other type of code.\n\nTags\n\nUse the Tags type for adding Tags. The field is empty by default. To add tags, type the tag you'd like and press Enter. Click the x to delete a tag."
},
{
"title": "Creating an App",
"url": "https://www.builder.io/c/docs/creating-an-app",
"html": "Creating an App\n\nWe highly recommend that you integrate Builder into an existing app; however, if you need to create an app, follow the steps for your framework.\n\nFramework\nReact\n\nMeta-Framework\nNone\n\nSDK Generation\nGen 1\n\n\nReact offers a number of ways to create an app with various frameworks.\n\nAt the command line, change directory with the cd command where my-app is the name of your app:\n\ncd my-app\nWhat's next\n\nAfter you have an app, you can integrate with Builder. For instructions, visit Integrating Pages."
},
{
"title": "Input types for custom components",
"url": "https://www.builder.io/c/docs/custom-components-input-types#code-strong-list-strong-code",
"html": "Input types\n\nTip: With plugins in Builder, you can create custom field types. For more information on using Builder's built-in plugins or creating your own, see Intro to Built-in Plugins and Making a Plugin.\n\nPrerequisites\n\nTo get the most out of this document, you should be familiar with Integrating Your Custom Components with Builder.\n\nRequired inputs\n\nWhen you register a component with Builder, you must include the name and type inputs as in the following table:\n\nName\tRequired\tDescription\n\nname\n\n\t\n\nYes\n\n\t\n\nA unique name for this input that should match the equivalent prop name on your React component.\n\n\n\n\ntype\n\n\t\n\nYes\n\n\t\n\nTypes correlate to what editing UI is appropriate to edit this field. Common types include:\n\n'boolean'\n'color'\n'date'\n'enum'\n'email'\n'file' // Uploads a file and provides the value as a url string\n'list'\n'longText' // String type but with a multiline text field editor\n'number'\n'object'\n'reference' // displays a content entry picker to reference\n'richText' // Displays a rich text editor and provides the value as html\n'string'\n'url'\nOptional inputs for further customization\n\nYou can use additional inputs to further customize your components in Builder. The following table contains Builder's optional inputs.\n\nName\tType\tDescription\n\nadvanced\n\n\t\n\nBoolean\n\n\t\n\nSet to true to put this component under the Show More section of the Options tab. Useful for things that are advanced or rarely used and don't need to be prominent.\n\n\n\n\nallowedFileTypes\n\n\t\n\narray\n\n\t\n\nFor the file input type, specify what types of files users can upload. This is an array that takes content-type files such as:\n\nallowedFileTypes: ['jpeg', 'png', 'mp4', 'gif', 'pdf', 'svg']\n\n\n\ndefaultValue\n\n\t\n\nany\n\n\t\n\nUse for showing an example value in the input form when creating a new instance of this component, to users understand its purpose.\n\n\n\n\nenum\n\n\t\n\narray\n\n\t\n\nFor any text-based field type, you can specify a set of options that the field can use.\n\nenum: ['option 1', 'option 2']\n\nInstead of a string, pass an object to customize the displayed label and internal value. This is useful if you are using code to modify state within your content entry.\n\nenum: [\n {\n label: \"option 1\",\n value: \"opt-1\",\n },\n {\n label: \"option 2\",\n value: \"opt-2\",\n }\n]\n\n\n\n\nfriendlyName\n\n\t\n\nstring\n\n\t\n\nThe name the Visual Editor displays for the input.\n\nfriendlyName: 'Open link in new tab',\n\n\n\nhelperText\n\n\t\n\nstring\n\n\t\n\nProvide text to help the end user know how to fill in this input. Displays below the input.\n\nhelperText: 'Some helpful description about how to use this input'\n\n\n\nmodel\n\n\t\n\nstring\n\n\t\n\nUse optionally with inputs of type reference. Restricts the content entry picker to a specific model by name.\n\nBuilder.registerComponent(ProductBox, {\n name: 'ProductBox',\n inputs: [{\n name: 'metafields',\n type: 'reference',\n model: 'product-metafields'\n }]\n})\n\n\n\n\n\nonChange\n\n\t\n\nFunction\n\n\t\n\nProvide a function that is called whenever the value of the input is updated. Useful for more complex validation than regex or running custom logic when an input value updates.\n\n// Example of how to validate and limit the length \n// of a list input called myList\n// \n// Note: the function is stringified and evaluated in \n// the context of the parent window, \n// so don’t try to use any references to other \n// variables or functions that you might have \n// within the file that your component defined\nonChange: (options) => {\n if (options.get('myList').length > 6) {\n options.set('myList', options.get('myList').slice(0, 6))\n alert('maximum items is 6, delete items to continue')\n }\n}\n\n\n\n\nregex\n\n\t\n\nobject\n\n\t\n\nFor any input that results in a string value you can provide a regex to validate user input.\n\n regex: {\n // pattern to test; such as \"^\\/[a-z]$\" \n pattern: \"^\\/[a-z]$\",\n // flags for the RegExp constructor; for example, \"gi\" */\n options: \"g\",\n // message to display to end-users if the regex fails\n message: \"You must use a relative url starting with '/...' \"\n }\n\n\n\n\nshowIf\n\n\t\n\nFunction\n\n\t\n\nShow and hide the input dynamically.\n\noptions is an object with the current options, that is, values from inputs, that are set on the component.\nparent is the component definition,\nparentElements is an array of all the parent elements of where the component is placed\n\nFor example, to only show the input if the component is inside of a Columns component has the input myInputOption set to true, you could write a function as follows:\n\nshowIf: (options, parent, parentElements) => {\n return options.get('myInputOption') \n && parentElements.some(el => \n el && el.component && el.component.name === 'Columns');\n}\n\n\n\nUse the state of other inputs with options to hide or show inputs that depend on one another. For example, you could show an input that opens a link in a new tab only if a link is present, instead of always showing all inputs.\n\nFor versions of @builder.io/react prior to 4.0.3 and Gen 2 SDKs for all Gen 2 packages prior to 2.0.3, if you use showIf in subFields, you must pass the value as a string, for example:\n\nsubFields: [\n {\n ...\n showIf: 'true'\n // or\n showIf: `options.get('someField') === 'someValue'`\n }\n]\n\n\nIn versions 4.0.3+ of @builder.io/react and 2.0.3+ of Gen 2 SDKs, showIf can be a function for subFields.\n\n\n\n\nsubFields\n\n\t\n\nInput[]\n\n\t\n\nIf the input type is list , you must include the subFields property that is a list of inputs, with this same schema, for each list item.\n\n{\n name: 'reviews',\n type: 'list',\n defaultValue: [ \n { reviewText: 'hello' \n }],\n subFields: [\n\t{\n name: 'reviewText',\n type: 'string',\n defaultValue: '\"You are \n the best\"',\n },\n {\n name: 'reviewAuthor',\n type: 'string',\n defaultValue: 'Jane Smith',\n },\n {\n name: 'image',\n type: 'file',\n allowedFileTypes: ['jpeg', 'jpg', 'png', 'svg'],\n required: true,\n defaultValue:\n 'https://cdn.builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d',\n },\n ],\n }\n\n\n\n\nlocalized\n\n\t\n\nboolean\n\n\t\n\nYou can mark any input type with localized to get a separate value for each of the locales configured on your space.\n\n{\n name: 'title',\n type: 'text',\n localized: true,\n}\n\nInput type examples\n\nThis section provides examples of the effects of input types in Builder and covers the following:\n\nInput type name\nDefinition of input type\nAlias/alternative input type you can use instead of the given input type\nScreenshot of input type's effect in Builder's Visual Editor\n\nTip: This section covers the built-in types for custom components, but you can also make your own with plugins. For more information, see Make Your Own Plugins Overview.\n\nboolean\n\nAn input field taking true or false.\n\n {\n name: 'darkMode',\n type: 'boolean',\n defaultValue: true,\n }\n\ncolor\n\nProvides a color value, in hex or rgb, to a component.\n\n {\n name: 'backgroundColor',\n type: 'color',\n defaultValue: '#fafafafa',\n }\n\ndate\n\nTakes same formats as the date constructor for Javascript.\n\n {\n name: 'event',\n type: 'date',\n defaultValue: 'December 17, 1995 03:24:00', \n }\n\nemail\n\nCreates an email value for a component.\n\n {\n name: 'signup',\n type: 'email',\n defaultValue: 'noreply@email.com'\n }\n\nfile\n\nUploads a file and provides the value as a URL string. Refer to allowedFileTypes for details.\n\n { \n name: 'image',\n type: 'file', \n allowedFileTypes: ['jpeg', 'png'] \n }\n\nlist\n\nA collection of items.\n\nRequires the defaultValue option.\n\nAlias: array\n\n{\n name: 'reviews',\n type: 'list',\n defaultValue: [ \n { reviewText: 'hello' \n }],\n subFields: [\n\t{\n name: 'reviewText',\n type: 'string',\n defaultValue: '\"You are \n the best\"',\n },\n {\n name: 'reviewAuthor',\n type: 'string',\n defaultValue: 'Jane Smith',\n },\n {\n name: 'image',\n type: 'file',\n allowedFileTypes: ['jpeg', 'jpg', 'png', 'svg'],\n required: true,\n defaultValue:\n 'https://cdn.builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d',\n },\n ],\n }\n\nlocalized text\n\nA localized text input is a key/value object where the keys are the locales configured in your space. For more information, see Introduction to Localization with Builder.\n\n{\n name: 'title',\n type: 'text',\n localized: true,\n}\n\nlongText\n\nSame as string type but with a multi-line text field editor.\n\n {\n name: 'description',\n type: 'longText',\n defaultValue: 'Builder is the first and only headless CMS with a powerful \n drag-and-drop visual editor that lets you build, \n optimize, and measure digital experiences with speed and flexibility'\n }\n\n\nTip: If the text is to be formatted, use richText.\n\nnumber\n\nSpecifies that an input field expects a number.\n\n {\n name: 'amount',\n type: 'number',\n defaultValue: 20,\n }\n\nobject\n\nA set of specific names and values.\n\nobject requires the defaultValue option. Additionally, if you want to specify default values, make sure you provide them at the object level, not in the subFields.\n\n {\n name: 'Carousel',\n type: 'object',\n defaultValue: {\n // Provide default value here,\n // NOT in the subFields\n text: 'This is the default text input',\n url: 'http://www.myexampleurl',\n variant: 'primary'\n },\n subFields: [\n {\n name: 'text',\n type: 'string',\n required: true,\n },\n {\n name: 'url',\n type: 'url',\n required: true,\n },\n {\n name: 'variant',\n type: 'string',\n enum: ['primary', 'info', 'dark', 'light', 'warning'],\n },\n ],\n }\n\n\nIf you have large objects with multiple fields:\n\nUse folded so that multiple inputs are collapsed by default to preserve space on the screen.\nUse keysHelperText to provide helpful copy to the user.\n {\n name: 'HugeObject',\n type: 'object',\n folded: true,\n keysHelperText: 'Pick a property to edit',\n helperText: 'Edit this enormous object',\n subFields: [\n ... /* Lots of subFields here */\n ] \n },\n\nrichText\n\nDisplays a rich text editor and provides the value as HTML\n\nAlias: html\n\n {\n name: 'description',\n type: 'richText',\n defaultValue: '<b>This text is bold</b>'\n }\n\nstring\n\nAny text, usually short in length and unformatted.\n\nAlias: text\n\n {\n name: 'buttonText',\n type: 'string',\n defaultValue: 'Click',\n }\n\nurl\n\nA valid URL. URLs must be absolute (start with http:, https:, mailto:, sms:, or tel: and have a hostname) or site relative (/page/name) or a hash (#something).\n\n {\n name: 'myUrl',\n type: 'url',\n defaultValue: 'https://builder.io',\n }\n\nTags\n\nTags, usually short text for adding tags to your content entries.\n\n {\n name: 'blogTags',\n type: 'Tags'\n }\n\nAn example using icons\n\nIf you have a design system that features an icon set, you can use a custom component that takes an icon name as input. In this way, you can manage and distribute your icons across your app. Register your icon component as below:\n\n Builder.registerComponent(Icon, {\n name: 'Icon',\n inputs: [{ name: 'icon', type: 'text', enum: ['error', 'warning' ..] }]\n },\n\nWhat's next\n\nEvery use case is unique. If you need further customization, you can add custom types with plugins."
},
{
"title": "Map Figma components with the Builder Plugin",
"url": "https://www.builder.io/c/docs/figma-components",
"html": "Map Figma components with the Builder plugin\n\nin beta\n\nfor developers\n\nenterprise plans\n\nThis feature requires an Enterprise plan. To try it, request an Enterprise trial.\n\nWith the Builder Figma plugin, you can map your Figma designs to your code components.\n\nAs an example, suppose you have a design system in Figma and a set of components in code that correspond to the designs in Figma. With the Builder Figma Plugin, you can map these components to each other and generate quality code.\n\nThe image below shows a design and its corresponding code, which component mapping can help you achieve.\n\nPrerequisites\n\nTo get the most out of this document, you should:\n\nHave a Next.js, Remix, React with Vite, or Angular app ready with React or Angular components.\nHave a Builder Space.\nHave design components in Figma.\nMapping Figma components\n\nTo map your Figma components using the Builder Figma plugin:\n\nIn Figma, open the Builder Figma plugin.\nClick the Login button that displays on the bottom left of the plugin or the Connect with Builder button.\nWhen prompted in the browser, choose the Space you want to authorize access to and click the Authorize button.\nGo back to Figma. When the authorization is successful, the plugin shows the Space you're connected to.\nSelect the design.\nOn the Export tab in the plugin, click Map. Note that this button only displays if there are components found in the selection. For pointers, read Make your components mappable later in this document.\nOn the Design System tab, copy the generated command.\nPaste the command at the command line. This command contains Figma IDs for mapping the components.\nWhen prompted, authorize the Builder CLI by clicking on the Allow access button.\nConfirm you have the right Space selected and Authorize Devtools by clicking on the Authorize button.\nBack at the command line, the CLI authenticates and detects components.\nSelect the components you want to map.\n\nFor details on the plugin, read Import from Figma. The video below shows using the plugin and CLI to authenticate, authorize the CLI and Devtools, and map components from an example Figma design.\n\nFor details on the plugin, read Import from Figma.\n\nMake your components mappable\n\nTo map components in your codebase, they need to be discoverable by Builder's Devtools. That means you must export your components from any JavaScript or TypeScript file in your code, and (ideally) define their prop types in TypeScript or JSDoc types.\n\nAdditionally, you must make sure the plugin has the correct Public API Key and that the model names match.\n\nUse the correct file type\n\nProvided components are properly exported, the plugin can detect components in the following types of files:\n\n.js\n.jsx\n.ts\n.tsx\nAlways export components\n\nIn order for the plugin to detect library components, always make sure to export the components you want to map from one of the file types listed earlier in this section.\n\nAs a best practice, export the component and use types for props:\n\n// ✅\nexport function MyComponent(props: { title: string }) {\n return ...\n}\n\n// ✅\nexport const MyOtherComponent = () => ...\n\nIt's also acceptable to export the component later in your file:\n\ntype MyProps = { title: string }\n\nconst MyComponent = (props: MyProps) => ...\n\n// ✅\nexport default MyComponent;\n\nYou must always export the components you want to map. If you do not export them, they do not show up in the plugin. As an example, notice that this component is never exported, so it will not work:\n\n// 🚩 doesn't work, needs to be exported!\nfunction MyComponent() { ... }\nDefine types for props\n\nThe plugin operates optimally with TypeScript, enhancing its ability to map your Figma designs to the respective code components efficiently. Because of this, we recommend that you always define types for your component props.\n\n// ✅\nexport function MyComponent(props: { title: string }) {\n return ...\n}\n\n\n// ✅\ntype MyProps = { title: string }\nexport function MyComponent(props: MyProps) {\n return ...\n}\n\n\nWhile JavaScript without TypeScript is compatible, adding types to your props is ideal for the Builder's automapper to function most effectively:\n\n/**\n * @param {Object} props\n * @param {string} props.title \n * @param {number} props.enabled\n * @param {number} props.count\n */\nexport function MyComponent(props) {\n return ...\n}\n\nMapping library components\n\nWhen integrating code into your project from libraries like shadcn, the Builder Figma plugin works out of the box because it recognizes components that are defined and exported directly from the code. However, if you're using components from a package that aren't explicitly present in your codebase, you can still map them by re-exporting as below:\n\n// src/components.tsx\nexport { Button, Card, TextField } from '@mui/material'\nexport { DatePicker } from 'antd';\n\nThe example shows a file called components.tsx — though the actual file name doesn't matter — and exports components from libraries. By being exported in this way, these components are discoverable by Builder's Devtools.\n\nBe sure to export each component you want to map. In the above example, only Button, Card, TextField, and DatePicker will be mappable. Export globs; for example, export * from 'package', are not currently supported.\n\nUpdating the Figma Imports Preview URL\n\nWhen using Builder Devtools with component mapping, a new route called figma imports is generated in your project so you can access imported Figma components.\n\nThis workflow assumes you are developing on localhost. To enable access for users who are not running Devtools locally, you must update the Preview URL in Builder for the Figma Imports model.\n\nUsing the techniques outlined in this document, map at least one Figma design to a code component in your project. After you've successfully mapped at least one component, a model named Figma Imports model displays in Builder and a route is added to your project.\nDeploy the project to a production environment.\nGo to Models in Builder and update the Preview URL for the Figma Imports model in Builder to match the production URL format; for example, yoursite.com/figma-imports. This makes sure that users accessing the Figma components without running Devtools locally can use the imported components.\n\nThe video below shows going to the Models section of Builder and selecting the Figma Imports model. Note that you won't find that model listed if you haven't completed at least one Figma import using component mapping.\n\nWhen you open the model, edit the Preview URL field so that others can use the newly mapped component.\n\nThis section covered Preview URLs specifically for Figma Imports. For more information on Preview URLs in other use cases, visit Editing and Previewing Your Site.\n\nWhat's next\n\nCertain parts of the this workflow use AI, for more information, visit How Builder Uses AI."
},
{
"title": "Understanding Impressions",
"url": "https://www.builder.io/c/docs/impressions",
"html": "Understanding Impressions\n\nBuilder provides detailed analytics to highlight how your content is performing, including how many Impressions your content is generating.\n\nHow impressions work\n\nPro plans\n\nAn impression represents a view of a piece of content on your site. Builder tracks impressions for analytics and heat mapping capabilities as part of Growth and Enterprise plans.\n\nEach Builder content entry is attached to JavaScript code that records when that content entry is loaded onto your page. In this way, Builder provides detailed analytics to highlight how your content is performing, including how many Impressions your content is generating.\n\nBuilder's code collects anonymous information about the current visitor (most importantly to distinguish between users), packages it with information about the content entry, and stores it to use in your Insights dashboards. For more on the Insights tab, read Content Entry Insights.\n\nFind your impressions metric\n\nTo display your impressions:\n\nWhile logged into Builder, go to the Home screen.\nFind the Impressions on the second row of the screen.\n\nThe image below shows the Builder Home screen with an arrow to the Impressions tile.\n\nTo display details about impressions, hover over the Impressions graph. When you hover over the graph line, numerical data shows for the given date:\n\nWhat's next\n\nFor more information, read Understanding Pageviews and Impressions Compared to Visual Views."
},
{
"title": "Start Building",
"url": "https://www.builder.io/c/docs/start-building",
"html": "LET'S BUILD TOGETHER\n\nLearn Builder\n\nGet to know Builder's core concepts — like Organizations, Spaces, and the Visual Editor, an intuitive drag-and-drop editor where you can quickly build Pages, Sections, and leverage your data.\n\nGET UP AND GOING\n\nCore Concepts\n\nLearn about Organizations, Space, and Environments\n\nThe Visual Editor\n\nCreate and iterate designs with drag-and-drop and AI\n\nImport from Figma\n\nGet your Figma designs into Builder with the Figma plugin\n\nChrome Extension\n\nImport any web content into Builder for editing and instantly access your content\n\nOVERVIEW OF THE BUILDER WORKFLOW\n\nDepending on whether you're using Develop or Publish, the workflow should follow one of these general outlines.\n\nTo get going with Builder Develop:\n\nImport your design from Figma.\nIterate with the Builder Visual Editor AI.\nGenerate great code.\nMap your components.\n\nFor a guide through the main workflow, see Get started with Develop.\n\nTo get going with Builder Publish:\n\nImport your design from Figma or from the web.\nIterate with the Builder Visual Editor AI.\nIntegrate Page building.\nIntegrate custom components.\n\nFor a guide through the main workflow, see Get started with Publish.\n\nBuild on a solid foundation\n\nFirst, make sure you understand the basics, such as:\n\nHow Organizations, Spaces, and Environments work together: get familiar with these fundamental concepts of working in Builder.\nImport from Figma: get your design into Builder.\nIntro to the Visual Editor: use AI and intuitive tools to help you get your design and interactivity just right.\n\nWhen you've imported and iterated on your design, get into some of the in-depth features such as:\n\nData Binding\nBest Practices and Accessibility"
},
{
"title": "Learn",
"url": "https://www.builder.io/c/docs/learning",
"html": "Learn Builder\n\nIf you're new to Builder and want to learn your way around, the Builder documentation has articles that cover the basics to get you started. The following categories are based on Builder roles and permissions.\n\nIf you're just starting out with Builder, read Key Concepts first for context on how Builder works and an intro to common terms.\n\nContributors and Editors\n\nBecause Contributors don't edit layouts, they can focus on content such as copy and images. To get familiar with Builder, get up and running with our recommended learning path:\n\n1\n\nTour the Builder UI\n\nRecommended docs:\n\nLeft Sidebar\nVisual Editor\nTopbar\n\n2\n\nLearn how to create and edit content\n\nRecommended docs:\n\nBlock Types in Builder\nWorking with Images\nCreating Links\nFor Editors: Using Layers\n\n3\n\nGet acquainted with Builder workflows\n\nRecommended docs:\n\nRequest to Publish\nEditing Your Site Using the Builder Chrome Extension\nAdding Comments to Your Content\nDesigner\n\nTo get off to a good start, Designers should get acquainted with the Builder UI, its features made just for Designers, and how to apply the principles of responsive design in the Visual Editor.\n\nTip: To import your designs from Figma and automatically create responsive designs in Builder, check out Import from Figma, Builder's workflow for going from a Figma file to Builder.\n\n1\n\nLearn about responsive design\n\nRecommended docs:\n\nIntro to Responsive Design\nThe Box Model\nHow Width Affects Layout\nMargin and Padding\nUsing Breakpoints to Build Responsively\n\n2\n\nGet to know the UI\n\nRecommended docs:\n\nMake a Landing Page\nImporting Figma Designs\nUsing Alignment for Layout\nBest Practices\nAdmin\n\nIf you're an Admin, you might have many varied responsibilities, while still maintaining access and permissions in Builder for your team.\n\n1\n\nLearn about managing your account and users\n\nRecommended docs:\n\nRoles and Permissions\nUnderstanding Organizations\nAccessing Your Invoices\nUnderstanding Visual Views\n\nTip: If you need to create web experiences, make sure to read the documents under Designer, in the previous section.\n\nDeveloper\n\nDevelopers have their own section of the documentation. To get started coding with Builder, visit Developing with Builder, which highlights some of the most frequently used documentation tailor-made for developers.\n\nWhat's next\n\nThis document laid out a roadmap to help you get the information you need to get up and running with Builder. The next step is to play with Builder and start creating with Builder's Popular Tutorials."
},
{
"title": "SDK Comparison",
"url": "https://www.builder.io/c/docs/sdk-comparison",
"html": "SDK Comparison\n\nExplore the key distinctions and functionalities between the first and second generations of Builder SDKs using the comprehensive comparison and feature tables below, tailored to help you select the most suitable SDK for your development needs.\n\nRecommended Gen to use per framework\n\nThe Builder SDKs are divided into two generations, Gen 1, and Gen 2. Use the table below to find the recommended SDK generation for your framework.\n\nFramework\tGen 1\tGen 2\n\nQwik\n\n\t\n\nn/a\n\n\t\n\nRecommended\n\n\n\n\nReact*\n\n\t\n\nRecommended\n\n\t\n\n\n\n\n\n\n\nRemix\n\n\t\n\n\n\n\n\t\n\nRecommended\n\n\n\n\nHydrogen\n\n\t\n\n\n\n\n\t\n\nRecommended\n\n\n\n\nVue**\n\n\t\n\n\n\n\n\t\n\nRecommended\n\n\n\n\nSvelte\n\n\t\n\nn/a\n\n\t\n\nRecommended\n\n\n\n\nSolid\n\n\t\n\nn/a\n\n\t\n\nRecommended\n\n\n\n\nReact Native\n\n\t\n\nn/a\n\n\t\n\nRecommended\n\n\n\n\nAngular\n\n\t\n\n\n\n\n\t\n\nRecommended\n\n\n\n\nAngular SSR\n\n\t\n\n\n\n\n\t\n\nRecommended\n\n*Includes React-based frameworks such as Gatsby, Next.js Pages Router, and Next.js App Router.\n\n**Includes Nuxt.\n\nTable of features supported\n\nThe table below outlines the features available for Builder's SDKs.\n\nFeature\tReact (Gen1)\tReact (Gen2)\tVue\tReact Native\tSvelte\tQwik\tAngular (Gen1)\tAngular (Gen2)\tHTML API\n\nSSR/SSG\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\nn/a\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n⚠️\n\t\n\n✅\n\n\t\n\n✅\n\n\n\n\nCustom Components\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n⚠️\n\t\n\n✅\n\n\t\n\n❌\n\n\n\n\nChildren for Custom Components\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n❌\n\n\t\n\n✅\n\n\t\n\n❌\n\n\n\n\nCustom Fonts\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\nn/a\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\n\n\nAnimations\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n🔵\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\n\n\nCustom data/context\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n❌\n\n\t\n\n✅\n\n\t\n\n❌\n\n\n\n\nBuilder's global state\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n⚠️\n\t\n\n✅\n\n\t\n⚠️\n\n\n\nWidgets\n\n\t\n\n✅\n\n\t\n🔵\n\n\t\n\n🔵\n\n\t\n\n🔵\n\n\t\n\n🔵\n\n\t\n\n🔵\n\n\t\n\n✅\n\n\t\n\n🔵\n\n\t\n\n✅\n\n\n\n\nCSS Nesting (& operator)\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\nn/a\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\n\n\nLocales\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n\n✅\n\n\t\n⚠️\n\t\n\n✅\n\n\t\n⚠️\n\nLegend\n\n\n✅ Full support\n\n\n🔵 In development\n\n\n⚠️ Partial support\n(hover for a tooltip with details)\n\n\n❌ Not supported\n\n\nRendering content\n\nRendering your Builder content differs between Gen 1 and Gen 2.\n\nFramework\nReact\n\nMeta-Framework\nNone\n\nSDK Generation\nGen 1\n\n\nIn Gen 1 SDKs the component is BuilderComponent.\n\nimport { BuilderComponent } from '@builder.io/react';\n\n<BuilderComponent model=\"page\" content={contentJSON} />\n\nFor recommended usage and a description of the props and methods of BuilderComponent, visit Using BuilderComponent.\n\nFetching data\n\nFetching data differs between Gen 1 and Gen 2.\n\nFramework\nReact\n\nMeta-Framework\nNone\n\nSDK Generation\nGen 1\n\n\nIn Gen 1, import builder and use the get() or getAll() helper:\n\nimport { builder } from '@builder.io/react';\n\nconst page = await builder.get('page', {\n fields: 'data.url, name',\n});\n\nconst pages = await builder.getAll('page', {\n fields: 'data.url,name',\n});\n\n\n\nFor more information, visit the Content API documentation.\n\nRegistering custom components\n\nRegistering custom components differs between Gen 1 and Gen 2.\n\nFramework\nReact\n\nMeta-Framework\nNone\n\nSDK Generation\nGen 1\n\n\nIn Gen 1, import the Builder object and use registerComponent():\n\nimport { Builder } from '@builder.io/react';\nimport { MyHero } from './MyHero';\n\nBuilder.registerComponent(MyHero, {\n name: 'Hero',\n inputs: [\n { name: 'title', type: 'string' },\n ],\n});\n\n\n\nWhen adding children, Builder's Gen 1 SDKs use withChildren(), while the Gen 2 SDKs require <Blocks>. For more information on the SDKs, visit SDK Comparision.\n\nFor more information on custom components, visit Registering Custom Components.\n\nConfiguring the Visual Editor\n\nConfiguring the Visual Editor differs between React Gen 1 and React Gen 2.\n\nFramework\nReact\n\nMeta-Framework\nNone\n\nSDK Generation\nGen 1\n\n\nIn Gen 1, import Builder and use the register() helper:\n\nimport { Builder } from '@builder.io/react';\n\nBuilder.register('insertMenu', {\n name: 'Our components',\n items: [\n { name: 'Hero', item: 'Hero' },\n { name: 'Double Columns', item: 'DoubleColumns' },\n { name: 'Triple Columns', item: 'TripleColumns' },\n { name: 'Dynamic Columns', item: 'DynamicColumns' },\n ],\n})\n\nGen 1 and Gen 2 package names\n\nThe table below lists the available package names by framework and generation. Use these names for installs and imports.\n\nFramework\tGen 1\tGen 2\n\nQwik\n\n\t\n\nn/a\n\n\t\n\n@builder.io/sdk-qwik\n\n\n\n\nReact*\n\n\t\n\n@builder.io/react\n\n\t\n\n@builder.io/sdk-react\n\n\n\n\nVue**\n\n\t\n\n@builder.io/vue\n\n\t\n\n@builder.io/sdk-vue\n\nThe Vue Gen 2 is the recommended SDK.\n\n\n\n\nSvelte\n\n\t\n\nn/a\n\n\t\n\n@builder.io/sdk-svelte\n\n\n\n\nSolid\n\n\t\n\nn/a\n\n\t\n\n@builder.io/sdk-solid\n\n\n\n\nReact Native\n\n\t\n\nn/a\n\n\t\n\n@builder.io/sdk-react-native\n\n\n\n\nAngular\n\n\t\n\n@builder.io/angular\n\n\t\n\n@builder.io/sdk-angular\n\n*Includes React-based frameworks such as Remix, Hydrogen, Gatsby, Next.js, and App Router.\n\n**Includes Nuxt.\n\nWhat's next\n\nFor fetching in advanced use cases, read Using Enrich to Fetch References and Symbols."
},
{
"title": "Passing Data to an Analytics Provider",
"url": "https://www.builder.io/c/docs/passing-analytics-data",
"html": "Passing Data to an Analytics Provider\n\nWith Builder, you can capture valuable data about user interactions with content and pass that data to an analytics provider, for example, a Customer Data Platform (CDP). In this way, you can gain insights, build targeted segments, and personalize future content based on user behavior.\n\nTracking content impressions and clicks\n\nTo track when a piece of Builder content loads and a user interacts with it, use the contentLoaded callback on the BuilderComponent:\n\nimport { BuilderComponent } from '@builder.io/react'\n\n<BuilderComponent \n model=\"page\"\n contentLoaded={(data, content) => {\n amplitude.track('builderImpression', {\n contentId: content.id,\n contentName: content.name,\n testVariationId: content.testVariationId,\n // Make sure to edit the variant name in Builder with a descriptive name\n testVariationName: content.testVariationName\n });\n }}\n/>\n\n\nHere's what's happening:\n\nThe BuilderComponent from the @builder.io/react package renders a piece of Builder content.\nThe model is specified as \"page\", but this could be any model type in the Builder Space.\nThe contentLoaded callback triggers when the Builder content finishes loading.\nInside the callback, Amplitude's track method is used to log an event called 'builderImpression'. Replace this with the tracking method from the CDP of choice.\nSeveral pieces of data about the content are passed as event properties:\ncontentId: the unique ID of the content.\ncontentName: the name given to the content in Builder.\ntestVariationId: if this content is part of an A/B test, the ID of the specific test variation.\ntestVariationName: a human-readable name for the test variation (make sure to set this in Builder).\n\nWith this in place, every time a piece of Builder content loads, it is logged to the CDP with metadata such as content ID, name, and test variation details. You can then use this data in the CDP to:\n\nAnalyze content performance by measuring metrics like impressions, clicks, and conversions.\nDefine user segments based on the specific content pieces they have viewed.\nPersonalize future content experiences based on user past viewing behavior.\n\nTip: You can use Builder's smart targeting in conjunction with a an analytics provider to automatically capture and target audiences based on their behavior. To learn more, visit Smart Targeting and Using Builder with Customer Data Platforms.\n\nThe exact capabilities will depend on the features and integrations offered by the chosen CDP.\n\nUsing data in your analytics provider\n\nOnce the data is sent to your analytics provider, you can use it for various purposes, such as:\n\nAnalyzing content performance by measuring engagement and conversion metrics.\nCreating user segments based on the content they have viewed for targeted campaigns.\nImplementing content recommendations based on user viewing history.\n\nThese are just a few examples but the specific use cases will depend on the capabilities of the chosen analytics provider and your business requirements.\n\nWhat's next\n\nFor more ways to leverage your analytics provider with Builder, read Smart Targeting."
},
{
"title": "Using Builder with Customer Data Platforms",
"url": "https://www.builder.io/c/docs/cdp-with-builder",
"html": "Using Builder with Customer Data Platforms\n\nCustomer Data Platforms (CDP) help you track and identify user characteristics and group them into Traits, Personas, and Audiences.\n\nWithin Builder, you can use these CDP groups as custom targeting attributes for robust personalization.\n\nStep 1: Add a custom targeting attribute to Builder\n\nYou can personalize Builder content based on various attributes. For example, to target content based on the current user audience type, define a custom targeting attribute for audience:\n\nGo to Account Settings.\nClick the Pencil icon next to Custom Targeting Attributes.\nClick +New Target Attribute\nEnter a name such as audience for Name.\nLeave String as the Type.\nClick Save.\nStep 2: Configure your code\n\nNext, from your codebase, fetch the current user audience type and set it using Builder's SDK:\n\nbuilder.get('your-model', {\n// Before the Builder content is fetched, set up segment\n// alternatively, Builder also accepts the targeting \n// attribute as a query param for direct API calls\n const audienceSegment = await myCustomCDP.identify({ user: currentUser.id })\n \n// fetch corresponding content to the targeted audience\n builder.setUserAttribute({ audience: audienceSegment.name })\n\n\n\nNow that you have set up your host to send the user's audience type, you can target content specifically to any of the audience types defined in your CDP.\n\nAdditionally, tracking events enables your CDP to automatically assign the audience type to your current users based on their interactions with your content:\n\n import { BuilderComponent } from '@builder.io/react'\n\n <BuilderComponent \n model=\"page\" \n contentLoaded={(data, content) => {\n amplitude.track('builderImpression', {\n contentId: content.id,\n contentName: content.name,\n testVariationId: content.testVariationId,\n // Make sure to edit the variant name in Builder with a descriptive name\n testVariationName: content.testVariationName\n })\n }\n />\n \n\nHow Builder and CDPs work together\n\nTraditionally, creating personalized content for specific audience types, such as VIPs, followers, or casual users required implementing numerous if-else statements in the code, leading to complex and difficult-to-maintain logic.\n\nCustomer Data Platforms (CDPs) help solve this issue by providing advanced machine learning algorithms or rule-based systems to categorize users into different traits, personas, or audiences based on their characteristics and interactions. For instance, CDPs can mark users as followers if they subscribe to a newsletter, or as VIPs if they have made significant purchases.\n\nTo use a CDP's audience categorization in Builder, developers need to consult the CDP by passing the current user ID (or anonymous ID) to the CDP's API endpoint for user categorizing. The CDP then provides information about the user's traits, behaviors, and interactions, which can help determine the appropriate audience type.\n\nOnce the audience type is identified by the CDP, it should be passed down as a user attribute to Builder, by using the setUserAttribute() function provided by Builder's SDK, as shown in the code snippet above. Then you can use the audience attribute for custom targeting in Builder, enabling content personalization based on the user's audience type.\n\nMoreover, CDPs offer flexibility in defining various attributes for targeting, such as \"big spender\" or other custom traits. This helps developers target content based on a wide range of user characteristics, which ensures more granular and effective personalization.\n\nWhat's next\n\nFor more information on targeting in Builder, refer to:\n\nTargeting and Scheduling Content\nCustom Targeting Attributes\n\nFor more detail on using Builder with an analytics provider, such as a CDP, visit Passing Data to an Analytics Provider."
},
{
"title": "Targeting Cheatsheet",
"url": "https://www.builder.io/c/docs/targeting-cheatsheet",
"html": "Targeting cheatsheet\n\nPro plans\n\nCreating your own custom targeting attributes can help you target specific segments of your site visitors. While you can create a wide variety of attributes, this document features a list of common attributes and shows how to create and use them.\n\nThe video below shows how to create a custom targeting attribute and use that attribute for targeting in a content entry.\n\nCreating and using custom targeting attributes\nStep 1: Creating the custom attribute\nIn Account Settings, click on the pencil next to Custom Targeting Attributes.\nClick the + New Target Attribute button.\nName your attribute and choose a Type.\nClick the Save button.\nStep 2: Using the new attribute in the content entry\nOpen a content entry.\nClick the targeting icon at the top of the UI.\nSelect your custom targeting attribute under Where and select the value.\nExamples of custom targeting attributes\n\nWhen you create custom targeting attributes, you can specify the attribute you need as well as specify the type. The following list includes some common examples.\n\nisLoggedIn\n\nIn Settings, create isLoggedIn with a type of Boolean:\n\nIn the content entry's Targeting dialogue, choose Is logged in and set the toggle on for true or off for false:\n\nIn your code, use:\n\nFramework\nREST API\n\nhttps://cdn.builder.io/api/v3/content/my-model?userAttributes.userLoggedIn=true\nisNewVisitor\n\nIn Settings, create isNewVisitor with a type of Boolean:\n\nIn the content entry's Targeting dialogue, choose Is new visitor and set the toggle on for true or off for false:\n\nIn your code, use:\n\nFramework\nREST API\n\nhttps://cdn.builder.io/api/v3/content/my-model?userAttributes.isNewVisitor=true\naudience\n\nIn Settings, create audience with a type of String, toggle on the enum switch, and add Enum Values:\n\nIn the content entry's Targeting dialogue, choose Audience and select the value(s):\n\nIn your code, use:\n\nFramework\nREST API\n\nhttps://cdn.builder.io/api/v3/content/my-model?userAttributes.audience='power-shopper'\nlocale\n\nIn Settings, create locale with a type of String, toggle on the enum switch, and add Enum Values:\n\nIn the content entry's Targeting dialogue, choose Locale and select the value(s):\n\nIn your code, use:\n\nFramework\nREST API\n\nhttps://cdn.builder.io/api/v3/content/my-model?userAttributes.locale='en-CA'\n\nThe above list features examples to show the potential of creating your own custom targeting attributes. You can create many types of attributes for targeting the right users for your content.\n\nWhat's next\n\nFor more information on targeting and custom attributes, see the following documentation:\n\nCustom Targeting Attributes: offers more detail on creating and using custom targeting attributes."
},
{
"title": "Introduction to Symbols",
"url": "https://www.builder.io/c/docs/symbols-intro",
"html": "Intro to Symbols\n\nWhen you want to create one element, reuse it throughout your site, and update all instances at once, use a Symbol. When you edit and Publish updates, the Symbol updates apply immediately to all occurrences of that Symbol throughout your app.\n\nYou can use Symbols for any content you want to reuse, such as a header, footer, or products. In fact, you can use it for repeated content that you want to use many places, such as a definition, an introductory paragraph or even a section of illustrated code.\n\nMake it once, reuse infinitely\n\nSave time by creating reusable elements such as headers, footers, navigation, and forms. Updates apply automatically to all instances of your Symbol.\n\nTo create your own Symbol, see How to create a Symbol.\n\nCustomizing your Symbols\n\nOccasionally, you might require an element like a product recommendation section or banner that needs to vary under specific conditions. In such cases, you can detach a Symbol from its source, Making a Symbol inline, which converts it into a standard Builder block. This way you can make inline changes for that particular instance.\n\nFor more on customizing Symbols, visit Adding Inputs to Symbols.\n\nTip: For a reusable component that you can edit individually, see Creating Templates. Templates are like Symbols, but when you edit a Template on a page, the other instances of that Template don't change.\n\nAdding a symbol to another account\n\nAt this time, you cannot transfer a symbol from one account to another. One workaround is to download your symbol and upload it to your other account.\n\nOpen the symbol you want to copy.\nRight click on the symbol and select Download content as JSON.\nCreate a new page in your other account, right click in the editor window, and select Upload builder.json file."
},
{
"title": "Conversion tracking with Builder.io",
"url": "https://www.builder.io/c/docs/conversion-tracking",
"html": "Tracking Conversions\n\nWith conversion tracking, you can measure and analyze important user actions or events, such as form submissions, purchases, or any other desired conversions.\n\nTracking conversions with Builder only requires adding a few lines of code to your app, as in the examples below:\n\nFramework\nReact\n\nMeta-Framework\nNone\n\nSDK Generation\nGen 1\n\n\nThere are two ways to track conversions:\n\nbuilder.trackConversion(): This function is used to track a conversion without specifying an amount. You can call this function whenever a user performs an action that you consider a conversion, such as submitting a form or completing a specific task.\nbuilder.trackConversion(amount): This function allows you to specify an amount associated with the conversion. The amount parameter represents the value of the conversion, typically a numeric value. For example, in an e-commerce application, you can pass the dollar value of an order as the amount to track the conversion along with its monetary value.\n\nTo use conversion tracking, call the appropriate builder.trackConversion() function at the point where the conversion occurs in your React application. Builder will then record and track the conversion event, so you can analyze and measure the effectiveness of your application or marketing efforts.\n\n// Requires @builder.io/sdk version >= 1.1.21\nimport { builder } from '@builder.io/react'\n\n// For conversions without a specified amount\nbuilder.trackConversion();\n\n// OR to specify an amount; for example, a dollar value for the conversion,\n// for an ecommerce order\nbuilder.trackConversion(99.99);\nCross-domain conversion tracking\n\nWhen you use cross-domain conversion tracking, such as when your checkout page is on a different domain than your store, you need to associate the session on the store with the conversion on the checkout page.\n\nPass the sessionId as a query param on the checkout URL as in the following example:\n\nimport { builder } from '@builder.io/react';\n\n/**\n* append the session to the URL to associate conversions\n*/\nconst Cart = () => {\n ...\n const checkoutUrl = useCheckoutUrl() +\n `&builder.overrideSessionId=${builder.sessionId}`\n ...\n}\n\n\nBuilder tracks these interactions using impression data. Ensure that this function is invoked in the same browser environment as the impressions and click events are dispatched. Since this API is designed for browser usage, it may not function as intended if used server-side.\n\nNote that if you are a Shopify store and have installed Builder's Shopify app, the above code is not needed, as it is installed automatically."
},
{
"title": "Custom Targeting Attributes",
"url": "https://www.builder.io/c/docs/custom-targeting-attributes",
"html": "Custom targeting attributes\n\nenterprise plans\n\nLearn how to create custom targeting attributes in Builder to go beyond built-in targeting options.\n\nDefine custom attributes to tailor content delivery based on user roles, preferences, or other unique conditions for a more dynamic and personalized user experience.\n\nPrerequisites\nMake sure you're familiar with the basics of Targeting Content.\nYou make custom targeting attributes in the Settings and apply them in the Visual Editor.\nIn your code, pass custom targeting attributes to Builder’s API or set them globally using setUserAttributes().\nCreate custom targeting attributes in the Settings\nGo to Space Settings.\nUnder the Targeting section, click Edit button for Custom Targeting.\nClick + New Target Attribute button.\nDefine targeting properties, such as Name, Type, and Enum in the Custom targeting attributes dialogue.\nClick Save.\n\nThe targeting properties:\n\nName specifies the name of the custom targeting attribute.\nType determines how values are entered. A String type provides a text box as an input, while a boolean type includes a toggle switch to select true or false.\nEnum is available only for String types. This option replaces the text box with a dropdown menu, requiring users to select from predefined options when targeting content.\n\nThis video below shows how to create custom targeting attributes in Settings.\n\nSet up custom targeting attributes in the Visual Editor\n\nTarget content using custom targeting attributes by setting conditions with the defined attributes.\n\nThe process is similar to targeting with built-in attributes, with custom targeting attributes included in the list of options for creating targeting conditions.\n\nOpen the content entry you want to target.\nClick the Targeting icon at the top of the Visual Editor.\nClick + Add Target.\nChoose a targeting attribute from the dropdown and set its value based on the attribute type.\n\nThe video below covers setting up custom targeting attributes in the Visual Editor.\n\nRender targeted content with custom targeting attributes\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nTargeting matches the values provided in a content API request through userAttributes with the targeting conditions set for your content in the Visual Editor. For built-in attributes like device or urlPath, Builder automatically extracts the necessary targeting data from your request.\n\nFor custom targeting attributes, include the required data in your request using the builder.get() or builder.getAll() methods.\n\nconst content = await builder.get('myModelName', {\n userAttributes: { \n //user defined attribute\n user: [\"admin\", \"designer\"],\n paidUser: true,\n\n // Built in\n urlPath,\n device: ['mobile']\n }\n}).promise();\n\n\nYou can alternatively use setUserAttributes to set the targeting attributes once across multiple content requests:\n\nbuilder.setUserAttributes({\n user: [\"admin\", \"designer\"],\n});\n\nconst model1Content = await builder.get('Model1').promise();\nconst model2Content = await builder.get('Model2').promise();\n\nAlternatively, you can pass the attributes as query string parameters when making requests through the Content or GraphQL APIs.\n\nconst response = await fetch(`https://cdn.builder.io/api/v3/content/my-model?apiKey=YOUR_API_KEY&userAttributes.user=admin,designer`)\n\nThe following example explains how to define custom targeting attributes in a Page model and send them as query parameters to target content based on conditions set in the visual editor. You can also use a Section model.\n\nFor example, create two versions of the page: one that displays the premium version when isProUser is true and another that displays the basic version for non-paid users.\n\nYou can define as many custom targeting attributes as needed to suit your use case.\n\nimport { builder } from \"@builder.io/sdk\";\nimport { RenderBuilderContent } from \"@/components/builder\";\n\nbuilder.init(/* ADD YOUR PUBLIC API KEY */);\n\nexport default async function Page({ params }: { params: { page: string[] } }) {\n const { page } = await params;\n const builderModelName = \"YOUR_MODEL_NAME\";\n\n const collectionHeroContent = await builder\n .get(builderModelName, {\n userAttributes: {\n\n // built in targeting attribute\n urlPath: \"/\" + (page?.join(\"/\") || \"\"),\n\n // custom targeting attribute\n isProUser: true,\n userType: [\"admin\", \"designer\"]\n },\n prerender: false,\n })\n .toPromise();\n\n return (\n <>\n {/* Render the Builder page */}\n <BuilderContent\n model={builderModelName}\n content={collectionHeroContent}\n />\n </>\n );\n}\n\n\nFor more examples, see Targeting Cheatsheet.\n\nMatch custom targeting attributes to their types\n\nTargeting attributes store user input based on their type and determine how values are defined in content API requests. The API request must include the exact value to properly display the targeted content.\n\nFor example, userType with the value premium is passed to the Content API request.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nIn the Settings\n\nIn the Targeting section, the userType attribute is defined as a String type.\n\nIn the code\n\nWhen making a request to the Content API, a String value is passed to userType, ensuring it aligns with the type declaration from Settings.\n\nconst content = await builder.get('myModelName', {\n userAttributes: {\n userType: \"premium\" // userType is defined as \"String\" type\n }\n}).promise();\n\nIn the Visual Editor\n\nThe targeting condition is set using the custom defined userType attribute, with premium as the expected value of type String.\n\nUse custom types with plugins\n\nYou can create and use custom types with plugins like Shopify, Cloudinary, BigCommerce, Magento, and others. These plugins provide rich interfaces for inputs such as colors, forms, or products. The stored values depend on the editor and may not always be immediately clear.\n\nFor more details on stored values, see Extending the UI with custom types in the Making a Plugin."
},
{
"title": "Managing Content Size",
"url": "https://www.builder.io/c/docs/managing-content-size",
"html": "Manage Content Size\n\nKeeping your content as small as possible is a best practice throughout web development. With less to deliver, your content can load faster and improve your app's UX.\n\nWhile minimizing how much data your users have to download, you can still deliver graphics, video, and beautiful content with a few pointers and techniques in mind.\n\nUse Symbols\n\nIf you have content that is potentially reusable, consider using a Symbol to help mitigate size issue on a Page.\n\nFor instance, selecting larger sections of your page and converting it to a symbol is one of the best ways to reduce the size of the page.\n\nThe benefits of using Symbols include:\n\nSymbols don't contribute to the file size.\nA symbol turns any component into reusable content that you can drag and drop onto any Page.\n\nFor more information on Symbols, read Intro to Symbols and Making a Symbol.\n\nReduce Top Level A/B Test Groups\n\nIf your content has a lot of A/B Test groups, each group is a unique copy of the content, so each a/b test group creates a copy and increases the total content size significantly.\n\nIf its important to maintain a large list of a/b test groups, consider choosing more specific areas of the content you want to test, creating a symbol from that, and making a/b test groups of just that area (image, text, etc).\n\nThat way the entire content entry is not copied, but rather just the portion you want to test.\n\nReducing file size\n\nWhen a content entry is too big, saving returns an error. This section covers the error and suggests additional measures you can take to reduce the size of your content entry:\n\nRecommendations\n\nIf you have optimized images, used the Image and Video blocks, and—if applicable—used Symbols, but are still getting the above error, check the following table for common pitfalls and suggestions for improvement.\n\nIssue\tSuggestion\n\nToo many A/B test variations on a Page\n\n\t\n\nRemove unnecessary or unused tests or variations, so they don’t count toward the file size limit, or convert the contents of each a/b test to a symbol.\n\n\n\n\nToo many elements on the page or big chunks of code in custom code blocks; for example, large SVG in custom code blocks.\n\n\t\n\nIn most cases, converting large sections of your page to symbols is the best fix, as the contents of symbols don't contribute to page size.\n\nAlso, avoid using large Custom Code blocks. For instance, if you are putting SVG code in a custom code block, instead use a jpg or png in an Image block.\n\nFor more accuracy, a developer can check file size in the browser's developer tools Network tab.\n\nChecking content size\n\nIn the Visual Editor:\n\nRight-click in the work area of your content entry.\nSelect Download Content as JSON.\n\nAfter you download the content, right click on the downloaded file and check file size. On a Mac, choose Get Info and on Windows choose Properties.\n\nWhat's next\n\nIn addition to managing content size, always use Best Practices to help you build great experiences."
},
{
"title": "Variant Containers",
"url": "https://www.builder.io/c/docs/variant-containers",
"html": "Variant containers\n\nin beta\n\nUse variant containers for personalization and scheduling features for content. You can serve different content variants to specific audiences or at scheduled times without requiring duplication of the entire Page or Section, giving you a single source of truth.\n\nUse cases include:\n\nTargeted content: Show different promotional messages to various customer segments, such as new visitors, returning customers, or users from different geographic locations.\nDate-specific or scheduled content: Instead of creating and scheduling multiple Page copies, users can schedule variants to appear at designated times.\nLocalize content for different locales: Display localized content based on the user’s country or language preference, such as currency or language settings.\nUser journey-based personalization: Adapt based on where a user is in their journey, like first-time visitors, repeat customers, or users who have made it further through the funnel.\nPrerequisites\n\nTo use variant containers, you need the React Gen 1 SDK version ≥ 5.0.2 or React Gen 2 >= 3.0.6. For more information on the available SDKs, read SDK Comparison.\n\nPersonalize a block\n\nPersonalize a block to enable features such as targeting and scheduling just for that block. For example, if you have a Section that you'd like the content to change for depending on the user or date, you'd personalize the block and then create a variant to your specifications.\n\nTo personalize a block:\n\nSelect the block you want to personalize.\nClick the down arrow next to the Edit button to open the flyout menu.\nTo make this block dynamic, select Personalize. The Options tab displays a Variants section.\nClick the + Variant button to specify Variant 1. When a Variant section within the Options tab is open, that is the variant that you are editing. To display the default variant, close all variant sections.\nSelect any targeting for the variant. For example, if you only want this particular variant to show when there's another item in already in the visitor's cart, you might configure the query to be Item in cart is and choose the product.\nSelect dates and times to start and end if needed.\n\nWhen editing a variant, you can bind and choose data depending on the requirements of each variant.\n\nNotice that when a block has been personalized, in addition to having Variants as an option in the Options tab, the Layers tab also marks the block as personalized.\n\nSet attributes in the browser\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nSet global attributes before React renders the component to display the correct personalization container. These attributes persist in cookies across page refreshes and are independent of server-side API calls, which return content entries based on user attributes provided in the request.\n\nCall builder.setUserAttributes() in the global context to store attributes in cookies on the first load so the right personalization containers load on subsequent renders.\n\nThis example sets the audience attribute to vip in the browser context before rendering the <Homepage> component.\n\n\"use client\"\nimport { builder } from \"@builder.io/sdk\";\n// other imports\n\n// Set user attributes before React initializes to avoid layout shifts.\nbuilder.setUserAttributes({\n audience: \"vip\"\n});\n\nexport default function Homepage() {\n //other logic\n return <BuilderComponent content={content} model={model} />\n \n}\n\n\nTo simplify targeting logic, send the same attributes to both the API and the client. Use targeting data from your CDP or user segmentation logic to set attributes accurately.\n\nServer versus client attributes\nLegacy implementation\n\nServer-side attributes in API requests filter content at the API level and determine which content entry is returned. This is a traditional approach and is not recommended for variant containers because it can negatively impact caching and performance.\n\n// Avoid this approach – it prevents efficient caching and can lead to inconsistent content.\n\nexport async function getStaticProps() {\n return {\n props: {\n content: await fetchOneEntry({\n model: \"page\",\n userAttributes: {\n // Filters content at the API level, \n // Use client-side userAttributes \n // for better caching and obtaining single pre-rendered page\n }\n })\n },\n };\n}\n\nModern implementation\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nThis approach sets user attributes on the client using a variant container, serves a single cached page to all users, and dynamically updates specific content blocks based on user attributes. This improves performance and provides personalization capabilities.\n\nTo prevent layout shifts and flickering effects on the initial page load, call builder.setUserAttributes() in the browser context to store user attributes in cookies. This approach helps load the correct variant without displaying a non-matching default variant.\n\nFor subsequent renders, call builder.setUserAttributes() inside the component to update the variant dynamically based on new attributes.\n\nIn this example, a variant container initially loads with audience set to vip. On subsequent renders, the variant changes when audience is set to normal.\n\n\"use client\"\n\nimport { builder } from \"@builder.io/sdk\";\n//other imports\n\n// Set user attributes before React initializes to avoid layout shifts.\nbuilder.setUserAttributes({\n audience: \"vip\"\n});\n\nexport default function Homepage() {\n // other logic to set attributes \n // and dynamically updates variant container in subsequent renders.\n useEffect(() => {\n builder.setUserAttributes({\n audience: \"normal\"\n });\n },[])\n\n return <BuilderComponent content={content} model={model} />\n \n}\n\n\nThe recommended approach uses client-side attributes with variant containers instead of server-side filtering. This improves performance for several reasons:\n\nThe server renders all content variations.\nThe client filters the content using user attributes.\nA single cached page serves multiple personalized variations.\nUsers see personalized content instantly, even before JavaScript loads.\nBest practices\nUse variant containers for content with minor variations across multiple targets.\nPrefer duplicate entries for content with significant variations.\nKeep the number of variants manageable — fewer than 100.\nGet targeting attributes from your CDP or user segmentation system.\nUse client-side attributes for variant containers instead of server-side filtering when possible.\nVariant containers versus duplicate entries\n\nUse the following guidelines to help decide between using variant containers or duplicating content entries. Consider variant containers for streamlined updates with minimal variation but for substantial changes across multiple targets, prefer duplicates.\n\nUse variant containers\tUse duplicates instead\n\nConsistent content: You’re delivering similar content across multiple targets, with minor variations for different audiences.\n\n\t\n\nSignificant content variation: Extensive content changes based on scheduling or targeting.\n\n\n\n\nScheduled updates: Scheduled updates to specific content blocks at different times without changing the entire Page.\n\n\t\n\nLarge-scale updates: Major updates, such as a full homepage, site, or app redesign.\n\n\n\n\nA few variations: A finite number of variants, which don't significantly impact the size of the content entry.\n\n\t\n\nLots of variants: 100 or more variants, which may exceed the content entry size limit.\n\nAdvanced personalization\n\nfor developers\n\nVariant containers enable personalization and scheduling within Builder’s UI. However, for content that requires dynamic adaptation at the server or edge level, the trimHtml() function processes HTML to deliver only the relevant variant based on audience segments, timing, or other criteria.\n\nIf using SSR or SSG, store user attributes in cookies before rendering the page to ensure the correct variant loads immediately. The trimHtml() function can be used at the edge or server level to filter the correct variant before sending the HTML to the client.\n\nThe trimHTML() function offers several key benefits:\n\nEdge caching and SSR-friendly: The trimHtml() function means you can serve personalized content without sacrificing performance. By processing the content on the edge or during SSR, you can still use caching effectively while ensuring users get the appropriate variant.\nEfficiency: By trimming the HTML before sending it to the client, the resulting HTML is optimized in size, supporting faster load times. This also reduces unnecessary duplication of content.\nDynamic Personalization: You can create multiple content variants and dynamically choose which one to display based on user attributes, date, or other rules, all while using a single HTML file.\nWhen to use trimHtml()\n\nThe trimHtml() function is useful when a project involves edge processing or server-side rendering (SSR). For example, if you need to personalize content based on the user’s location or schedule without sacrificing performance, trimHtml() makes sure the correct variant is selected and served immediately, without unnecessary data being sent to the client.\n\nIt’s most helpful when using Next.js, static site generation (SSG), or SSR frameworks that benefit from pre-processed, variant-specific HTML at runtime.\n\nThe trimHtml function’s job is to process the personalized content at the edge or server level, based on specific user attributes; for example, audience segmentation, date-based scheduling. The function evaluates the dynamic containers within the HTML and returns a modified HTML string containing the appropriate personalized variant for the user.\n\nThe example below uses trimHTML() to select the correct variant at the server level, based on user attributes and A/B test conditions:\n\nimport { trimHtml } from '@builder.io/personalization-utils';\n\n// Full HTML with all possible variants\nconst fullHTML = '... your HTML with variant containers ...';\n\n// Example user attributes, typically parsed from cookies\n// for audience segment and date for scheduling\nconst userAttributes = {\n audience: 'segment-a',\n date: '2025-06-15T12:00:00Z'\n};\n\n// Example A/B test data (parsed similarly from cookies or user data)\nconst abTests = {\n 'content-id-1': 'variant-a', // Specific A/B test variant for content-id-1\n 'content-id-2': 'variant-b' // A/B variant for content-id-2\n};\n\n// Trim the full HTML to show only the relevant \n// variant based on attributes and tests\nconst { html } = trimHtml(fullHTML, { userAttributes, abTests });\nParse user attributes from cookies\n\nTo make sure personalized content is delivered correctly, retrieve user attributes stored in the builder.userAttributes cookie, which stores audience and segmentation data.\n\nimport { parse } from 'cookie';\r\n\r\nfunction getUserAttributes(req) {\r\n const cookies = parse(req.headers.cookie || '');\r\n const builderAttributes = cookies['builder.userAttributes'];\r\n return builderAttributes ? JSON.parse(builderAttributes) : {};\r\n}\n\n\nIn your request handler, fetch these attributes and pass them to the trimHtml() function to get the appropriate HTML for the user:\n\nconst userAttributes = getUserAttributes(req);\r\nconst trimmedHTML = trimHtml(fullHTML, userAttributes);\nWhat's next\n\nTo leverage more with variant containers, read A/B Testing, Targeting, and Scheduling Content."
},
{
"title": "Using the Scheduler",
"url": "https://www.builder.io/c/docs/scheduler",
"html": "Scheduler and Calendar View\n\nPro plans\n\nWhen you schedule content in the Visual Editor, you can view and edit those scheduled content entries in Builder Scheduler. The Scheduler displays your scheduled content in a familiar calendar view, which shows all scheduled entries for a given time frame.\n\nYou can display your scheduled content entries in a month calendar view, by week, by day, or by agenda.\n\nPrerequisites\nTo access the Scheduler, you must have a Growth or Enterprise plan.\nTo use the Scheduler's features, make sure you have content entries that are already scheduled. For more details on scheduling content, visit Scheduling Content.\nUsing the Scheduler calendar view\nMake sure you have some scheduled content.\nGo to Scheduler. If you have any scheduled content for the time frame on display, that content entry shows on the calendar.\nClick a scheduled content entry to view or edit its dates.\nTo save your changes, click the Update Schedule button.\n\nThe following video demonstrates these steps.\n\nRemoving a scheduled date from an entry\n\nWhile you can remove or edit scheduling in the Visual Editor, you can also edit dates from within the Scheduler. To remove a date:\n\nGo to Scheduler.\nClick a scheduled content entry.\nClick on the date you'd like to remove.\nPress Delete.\nTo save your changes, click the Update Schedule button.\n\nThe following video demonstrates these steps.\n\nIf you remove both dates for an entry in the Scheduler and click Update Schedule, that entry is no longer scheduled. To schedule a content entry, follow the steps in Scheduling content.\n\nWhat's next\n\nYou can use scheduling to publish content entries at the right time and combine it with targeting to ensure your content reaches the right audience at the right time. For more information on using these features together, see Targeting with Builder."
},
{
"title": "Getting started with the visual editor in Builder.io",
"url": "https://www.builder.io/c/docs/guides/page-building",
"html": "Popular Tutorials\n\n>\n\nGet Up and Running in the Visual Editor\nGet Up and Running in the Visual Editor\n\nThis video walks through all the features of the Visual Editor and demonstrates how to perform common tasks.\n\nSkill set: Basic\n\nArea: UI only\n\nLength: 29 minutes\n\nPrerequisites\nYouʻll need a Builder account.\nAn evergreen browser; that is, a modern, up-to-date browser such as Google Chrome.\n\nCreate a page\n\nColumns\n\nImage Sizing\n\nInsert tab\n\nOptions tab\n\nStyle tab\n\nStyling\n\nAlignment\n\nMargin & Padding\n\nLayers tab\n\nCopy & paste\n\nX-Ray Mode\n\nBox block\n\nCustom CSS properties\n\nCopy & paste style\n\nMulti selection\n\nGrouping\n\nDuplicate layers\n\nResponsive Mobile Styling\n\nChild layout options\n\nHiding layers per device"
},
{
"title": "Targeting with e-commerce plugins",
"url": "https://www.builder.io/c/docs/plugins-ecom-targeting",
"html": "Targeting with e-commerce plugins\n\nYou can target your content using custom types provided by e-commerce plugins after your developer has set one up. For example, you can:\n\nDisplay an announcement bar with a coupon code when customers have a specific item in their cart.\nSet up calls-to-action that display when viewing products from certain collections.\nMake recommendations based on the item your customer is currently viewing.\nTargeting your content with e-commerce targeting condition types\n\nYou can start by selecting Targeting from Visual Editor's top toolbar.\n\nIn the Targeting window, select +TARGET to add a new target.\n\nSelect the drop-down box next to WHERE to add a new targeting condition.\n\nNotice that in addition to the default Device and Url path, the e-commerce plugin also adds three new targeting condition types: Item in cart, Collection handle, and Product handle.\n\nThe example below displays targeting condition types specific to the Shopify plugin. The types that you see may differ based on which plugin you use.\n\nLet's select Item in cart for our example.\n\nAfter selecting a condition type, you can select a resource to match your new targeting condition.\n\nSelecting Choose product in the example below displays a searchable list of products from our connected Shopify store, where we can choose a product to target.\n\nIn this example, we select Short sleeve t-shirt from the example list below to target the product handle associated with the product.\n\nHaving set up the targeting condition, the content now appears whenever a Short sleeve t-shirt is in the user's cart.\n\nfor developers\n\nAfter creating targeting conditions for your content, you must configure your site to pass the appropriate data to Builder.\n\nYour targeting won't work until completing this step because Builder can't automatically infer when an e-commerce targeting condition—for instance, when a user has added a particular item to their cart—has been met.\n\nThis step involves your developer. See Set up e-commerce targeting for more information."
},
{
"title": "Schedule Content",
"url": "https://www.builder.io/c/docs/scheduling",
"html": "Schedule Content\n\nPro plans\n\nYou can specify a date and time to publish a Page or Section so that your content goes live when you want it to.\n\nThis document covers concepts about scheduling individual content entries. For scheduling in bulk, visit the Scheduling Multiple Content Entries section of Bulk Actions.\n\nTo schedule a Page or Section:\n\nOpen the Page or Section you want to schedule.\nIn the Visual Editor, click the Schedule Entry icon in the upper right of the screen. The icon resembles a calendar with a small clock.\nSelect the Start Date and End Date.\nSelect a Timezone.\n\nIf you do not choose an end date, the entry will remain in a published state. If you choose an end date, make sure to have a fallback entry. For more details, read Working with schedules that end later in this document.\n\nIn addition, you can use the Scheduler to view and edit scheduled content entries.\n\nCreating a new version\n\nWith versions, you can iterate freely to schedule variations of your content.\n\nTo make a new version of a content entry:\n\nGo to the Versions tab.\nClick the New Version button.\n\nAlternatively, click the three dots in the upper right corner of the page and select Duplicate. Duplicating or creating a new version has identical results.\n\nFor more information on using scheduling with targeting, visit Targeting Content.\n\nHow Builder determines priority\n\nWhen you have multiple versions of a content entry, Builder uses specific criteria to determine which content entry to deliver.\n\nThe criteria that Builder uses to choose the content entry to deliver are:\n\nThe content entries must be published; if they are scheduled, their scheduled publication must include the current date and time.\nAny targeting attributes must be met.\nBuilder starts evaluating from the top of the content list. If two published content entries both meet the first two criteria, Builder chooses the one that comes first in the list.\nExample\n\nConsider the following example of three versions of an about page; about, about 2, and about 3. All content entries have the same URL, with one currently published and two other versions scheduled one after the other.\n\nThe screenshot below shows the example about page versions in Builder. The one on the bottom of the list will always be fetched as long as it's published unless about 2 or about 3 are published, which is during the time between the start and end dates for those schedules.\n\nThe following table notes each content entry, its schedule (if any), and notes on how Builder prioritizes that content entry.\n\nVersion of page\tSchedule\tNotes\n\nabout 3\n\n\t\n\nNov 12 – Nov 20\n\n\t\n\nGoes live only between the scheduled start and end dates\n\n\n\n\nabout 2\n\n\t\n\nNov 6 – Nov 12\n\n\t\n\nGoes live only between the scheduled start and end dates\n\n\n\n\nabout\n\n\t\n\nnone, currently published\n\n\t\n\nLive, unless about 2 or about 3 are published. When the schedule for about 3 has ended, this page (about) is delivered.\n\nAlways have a fallback\n\nNotice the order of the entries in Builder. The two scheduled versions are higher in the list than the default version and the default version remains published, even during the timeframe when about 2 and about 3 are scheduled.\n\nThis way, if for any reason about 2 or about 3 doesn't publish when expected (such as with an unintended gap in the schedule), the original about page acts as a fallback and renders.\n\nTip: To reprioritize content entries, reorder them by dragging and dropping them in the list with the drag handle.\n\nWorking with schedules that end\n\nThough an end date for a content entry is optional, be aware that if you do have an end date scheduled, that Builder unpublishes that entry at the specified date and time.\n\nTo make sure that you still have content available, always have a fallback content entry.\n\nExample: a temporary version of a Page\n\nConsider an example of a homepage that you'd like to change for a week, but then after that week is over, you'd like to automatically revert back to your usual homepage.\n\nThe workflow would be:\n\nMake a new version of the original homepage and make your changes in the new copy.\nSchedule the copy of the homepage to go live for the week you'd like it to replace the usual homepage.\nLeave the original homepage published. In this way, when the temporary homepage goes offline, the original homepage will be served instead.\n\nTwo important points to remember are:\n\nKeep the URLs the same.\nThe temporary page should be higher in the content list than the fallback (usually the original).\nWhat's next\n\nIn addition to scheduling within a content entry, you can manage schedules in other ways and use Targeting to deliver the right content to the right customers at the right time.\n\nWork with your schedules Using the Scheduler and Calendar View.\nFor more on targeting, refer to Targeting with E-commerce Plugins.\nFor custom targeting for developers, refer to Custom Targeting Attributes."
},
{
"title": "Smart Targeting",
"url": "https://www.builder.io/c/docs/smart-targeting",
"html": "Smart Targeting\n\nenterprise plans\n\nBuilder Smart Targeting uses historical API logs to suggest targeting attribute values, which in turn saves time, reduces errors, and provides customer data platform (CDP) insights.\n\nIdentifying diverse attribute values helps Builder to offer suggestions and autocomplete options when targeting new content to improve UX.\n\nPrerequisites\n\nTo get the most out of this document, make sure you're familiar with Targeting Content.\n\nActivate Smart Targeting\n\nTo activate Smart Targeting:\n\nGo to Settings.\nClick the Edit button for Advanced Settings.\nClick Advanced.\nChoose Predefined Attributes only or Full.\n\nAlong with the option to disable Smart Targeting — only applicable if it's already on and you want to turn it off — there are two settings for configuring Smart Targeting:\n\nPre-defined Attributes Only: Enrich the possible values with defined targeting attributes only.\nFull: Enrich both targeting attribute keys and values with historical values.\n\nThe video below shows activating Smart Targeting by choosing the Full option.\n\nIf you choose to use Predefined Attributes only, make sure to set up Using Custom Targeting Attributes to define attributes.\n\nTargeting content with smart targeting attributes\n\nTo use your smart targeting attributes, follow the instructions for targeting in Targeting Content. With your smart targeting attributes in the list of attributes, you can choose them when creating a targeting condition.\n\nFor example, in the image below, the most frequently used attributes are automatically in the list as options when setting up targeting:\n\nWhat's next\n\nFor more about CDPs and Builder, read Using Builder with Customer Data Platforms."
},
{
"title": "Targeting Content",
"url": "https://www.builder.io/c/docs/targeting",
"html": "Targeting Content\n\nenterprise plans\n\nTargeting content for specific audiences can help you drive customer acquisition and retention.\n\nYou can target content based on attributes such as whether customers have purchased from a specific collection, their current product page, or if they have a product with a specific tag in their cart. These are just a few examples—there are endless possibilities for targeting.\n\nPrerequisites\n\nTo get the most out of this article, you should be familiar with Scheduling Content.\n\nTargeting options by plan\n\nTargeting options in Builder depend on your plan.\n\nAll plans come with the URL Path targeting attribute.\nPro and Enterprise plans offer both URL Path and Device targeting capabilities.\nWith Pro plans and above, can use your own Custom Targeting Attributes.\nBuilder provides e-commerce plugins for various platforms, each equipped with custom targeting attributes.\nAccessing targeting attributes\n\nTo use targeting:\n\nOpen the content entry for which you'd like to configure targeting.\nClick the Targeting icon at the top of the Visual Editor.\nIn the Targeting dialog, click +Target, and choose a property from the dropdown menu.\n\nAs an example, the following video shows targeting where the URL is /demo and the Device is mobile. This means this page is to be delivered when the device the visitor is using is a mobile device.\n\nTargeting by device with SSR? When using SSR or SSG, and targeting by device—such as mobile, tablet, or desktop—you must reference the targeted device in userAttributes as in the following example:\n\nuserAttributes: {\n ...\n device: \"mobile\"\n}\n\n\nFor more details on userAttributes, visit the userAttributes entry in the Content API documentation.\n\nFor a Next.js-specific example, refer to this example on GitHub for retrieving userAgent and device type server side.\n\nUsing order with targeting\n\nThe order of content entries in Builder determines how Builder evaluates and determines which content entry to deliver. Builder starts at the top of the list of entries at the specified URL and works its way down to find the entry to render.\n\nFor example, when you have multiple pages set up as alternatives for a specific targeting condition, they all share the same URL. When a user requests that URL, Builder checks each page in the list associated with that URL, starting at the top. The first page that meets the specified targeting condition is the version that is displayed to the user.\n\nExample\n\nConsider three versions of a homepage; home, home 2, and home 3. Each has different content, but they are all at the same URL, as in the following:\n\nhome 3, targeting mobile\nhome 2, targeting desktop\nhome (fallback), with no targeting\n\nHere's how Builder determines which Page to deliver:\n\nFirst, Builder considers all published Pages at the requested URL, /.\nIf home 3 has the Device targeting attribute set to Mobile, and your user visits yoursite.com from their phone, they get the content from home 3.\nIf home 2 targets Tablet, Builder delivers that Page to tablet users.\nThis example also has a fallback, home (fallback), just in case. It's a best practice to be sure all your conditions have a fallback Page in case none of the conditions are met.\n\nWhen you configure targeting, you establish a condition about a user and then deliver the appropriate content to that user. For example, you might want a user on a mobile device to have a different UI from a user on a laptop. Targeting statements follow the below pattern:\n\nWhere condition + operator + value\n\nBuilt-in conditions are:\n\nDevice\nURL Path\n\nSome examples of targeting statements are:\n\nWhere URL is /shoes\nWhere device is tablet\n\nThe operators available are:\n\nis means equal to the value\nis not means not the value. Available for conditions with one possible value; for example, a Boolean.\ncontains means the condition includes in it the string you specify for the value\nstarts with means the condition begins with the string you specify for the value\nends with means the condition ends with the string you specify for the value\n\nAdditionally, if you're on a Pro or Enterprise plan, you can customize targeting to meet your specific needs. For more information, read Custom Targeting Attributes.\n\nTargeting in-depth\n\nThe following video provides an in-depth introduction to targeting in Builder:\n\nFor more information targeting based on query parameters, visit this Builder Forum discussion.\n\nShopify custom attributes\n\nWith Shopify, Builder offers several ways to target content. For example, you can leverage your Shopify customer tags or if a user has specific items in their cart, you can display and even A/B test your content.\n\nDepending on the type of theme page you're working on, such as a homepage, a collection page, or a product page, Builder populates additional targeting parameters specific to the theme page."
},
{
"title": "Publish with Builder",
"url": "https://www.builder.io/c/docs/developers",
"html": "Publish with Builder\n\nGet started with Builder's Visual Development Platform\n\nPublish Quickstart\n\nINTEGRATE WITH YOUR CODE\n\nIntegrate Page Building\n\nIntegrate Section Building\n\nIntegrate Structured Data\n\nWhich should I use?\n\nDIVE DEEPER\n\nGenerating Code with Visual Copilot\n\nLearn About Content Models\n\nIntegrate Design Tokens\n\n\nIntegrate Custom Components\n\nPOPULAR DEVELOPER DOCS\n\nHow Builder Works\n\nAPI Documentation\n\nExtend Builder with Plugins\n\nIntegrate Symbols"
},
{
"title": "Intro to Plugins",
"url": "https://www.builder.io/c/docs/plugins-intro",
"html": "Intro to Plugins\n\nPlugins for Builder help you integrate a third-party service and customize nearly every part of Builder's Visual Editor and models.\n\nPlugins are a powerful tool for customizing the Visual Editor to make it easier for users to manage and create content.\n\nPlugins help you:\n\nCreate custom types.\nExtend the Visual Editor's user interface.\nTypes of Plugins\n\nThere are three types of plugins in Builder:\n\nBuilt-in plugins: On the Integrations page in Builder, use these ready-made plugins to help you integrate with e-commerce platforms and external data providers with minimal configuration. All plans can use the built-in plugins.\nPublic plugins: You code these and then submit a PR to add to the built-in integrations. Public plugins become part of the Builder ecosystem and when they're merged, Builder.io's engineers help maintain them. All plans can submit public plugins.\nPrivate plugins: You code these but they do not become part of the Builder ecosystem because you maintain them privately. Private plugins are available on all Enterprise plans while plugins with your own branding are available as an add-on for Enterprise customers.\n\nThe diagram below shows these points in a table form:\n\nUse cases for plugins\nBuilt-in Plugins\n\nUse built-in plugins for integrating your Builder account space with with e-commerce platforms and external data providers.\n\nBuilt-in plugins include everything in Integrations, such as:\n\nBigCommerce\nCommercetools\nFigma\nPartytown + Shopify\nSmartling\n\nFor a full list, see Integrations and for further documentation, refer to Overview of Built-in Plugins.\n\nPublic Plugins\n\nUse public plugins when you want to customize the Builder Visual Editor UI and you are willing to share your plugin with others. Common use cases for public plugins are:\n\nAdding your own custom types for a model, such as a rich text editor\nCustomizing the Builder Visual Editor\nTargeting content based on what users have in their cart\nCustomizing Symbol inputs\nCreating an action plugin to trigger events in Google Analytics\nAdding an image management plugin\nIntegrating with Shopify\n\nFor more details and instructions on creating plugins, see Extending the Builder UI with Plugins and Making a Plugin.\n\nPrivate Plugins\n\nCreate private plugins when you have needs specific to your company that you need to keep accessible only within your organization. Examples include:\n\nCustomizing the look and feel of Builder with your own branding\nAdding custom flows for creating e-mail campaigns\nWhat's next\n\nUsing and creating plugins opens up countless possibilities. For more info on plugins, check out the following documents:\n\nOverview of Built-in Plugins—an introduction to the plugins already available in Builder.\nMaking a Plugin—a tutorial on how to create your own plugin.\nBuilder.io plugin examples on GitHub"
},
{
"title": "Builder.io developer docs",
"url": "https://www.builder.io/c/docs/api-intro",
"html": "Builder API Documentation\n\nBuilder's APIs offer a wide variety of ways to leverage content and data quickly and efficiently.\n\nContent API\n\nMake requests to retrieve data about any of your Builder models.\n\nHTML API\n\nUse Builder to pre-render your components server-side.\n\nWrite API\n\nCreate, delete, and update content in Builder.\n\nGraphQL API\n\nQuery your data by targeting attributes and custom fields.\n\nUpload API\n\nUpload files, such as images and videos, programmatically.\n\nAdmin API\n\nA GraphQL API for back-end servers or trusted partners.\n\nImage API\n\nAccess and download optimized versions of your uploaded images.\n\nWebhooks\n\nListen for content changes that should trigger workflows."
},
{
"title": "How Builder Works: A Technical Overview",
"url": "https://www.builder.io/c/docs/how-builder-works-technical",
"html": "How Builder works: a technical overview\n\nBuilder is a Visual Development Platform that integrates with your existing sites and apps.\n\nAny content in Builder can be turned into code, including designs imported from Figma, imported from the web, or created manually with Builder's Visual Editor.\n\nBuilder supports two output methods — generated code and Builder's APIs (including SDKs). This way, you can choose whether to merge content directly into your codebase or deliver it dynamically using the Visual Editor Publish button — ideal for marketing content and pages.\n\nComparing to a headless CMS\n\nIn many ways, Builder works the same as any headless CMS, and Builder's CMS data models work identically.\n\nLike a typical headless CMS, you create entries with structured custom fields or targeting. You can then query these fields with our content API and display the content you want, where you want.\n\nIn many cases with Builder, the main difference is instead of hard coding a page layout, you have a Builder renderer component render the content dynamically, optionally using components from your codebase.\n\nOptionally, you can also restrict Builder editing to only these components—with or without allowing custom styling—using components-only mode and/or roles and permissions.\n\nThe next image shows how integrating your app can remove hard-coded content best maintained by other roles on your team, such as marketers, and copywriters.\n\nIn addition to visual editing, Builder also adds additional features that are less common in traditional headless CMSes, such as content targeting and analytics.\n\nStructured CMS data has its purposes, and while it often isn't the best for things like pages and layouts, it can be great for a number of other use cases that structured data can be more ideal than pure visual editing.\n\nHow the data is structured\n\nUnder the hood, Builder is a headless CMS like any other. You can create documents with structured data fields and consume these via our SDKs and APIs and render the data as you choose.\n\nOn top of this, Builder adds even more power by letting you register components that can render dynamically, saving you from having to write all of this logic manually. Instead, you can pass the data to a render Builder provides, such as in the following snippet:\n\nFor pages and sections, Builder automatically populates a field called blocks that is a list of components to render and their options, as in the following snippet:"
},
{
"title": "Intro to Integrating Custom Components",
"url": "https://www.builder.io/c/docs/custom-components-intro",
"html": "Integrate custom components\n\nYou can expand on Builder's selection of built-in blocks by registering components from your codebase with Builder. Then, teammates can drag and drop your components within Builder's Visual Editor just like any other block.\n\nYou can use components you code yourself or third-party components with Builder.\n\nGet started\n\nUsing your custom components in Builder's Visual Editor is a minimal process:\n\nStep 1: Register Custom Components with Builder, which requires minimal code setup.\nLearn to register your components\nStep 2: Use your component in the Visual Editor by dragging and dropping your component like any other block and customizing it in the Visual Editor.\nUse cases for integrating custom components\n\nCustom components are ideal when you want to accomplish goals such as:\n\nAdding unique functionality to your site for special use cases\nSystematizing design and content patterns\nStandardizing your design system with custom components-only mode, which makes only your custom components available for use in the Visual Editor\nCustomizing blocks\nOverriding built-in blocks\nFurthering your customized experience\n\nAfter you've set up custom components in Builder you can customize your team's experience even further by:\n\nUsing Builder Blocks in Custom Components\nOverriding Built-in Components\nVersioning Custom Components\n\nWhat's next\n\nTo get started using your custom components in Builder, head over to Registering Custom Components with Builder."
},
{
"title": "Generate Code",
"url": "https://www.builder.io/c/docs/generate-code",
"html": "Generate Code\n\nfor developers\n\nWhen generating code with Builder, you can generate code for any content entry.\n\nPrerequisites\n\nBefore generating code in Builder, make sure:\n\nYou have a Builder Page or Section with content\nOverview\n\nWhen generating code, you specify your framework, styling, and select Fast or Quality for code output type.\n\nThe image below gives an overview of where to select the main settings. The rest of this document goes into the available options in detail.\n\nSupported frameworks include:\n\nSwiftUI (Beta)\nCompose (Beta)\nFlutter (Beta)\nReact\nReact Native\nQwik\nVue\nAngular\nHTML\nSolid.js\nSvelte\nMarko\nMitosis\n\nFor CSS, you can choose:\n\nTailwind\nCSS\nEmotion (React)\nStyled Components (React)\nStyled JSX (React)\n\nBuilder-generated styles include clean, contextual class names, CSS variable names that align to your design system, and styled components with contextual names.\n\nCode quality\nThere are two types of generated code available, Fast code generation and Quality code generation.\nFast code generations\n\nFast code generations leverage Builder’s proprietary AI model and open-source compiler to nearly instantly turn any Figma design file into high-performing, responsive code for any framework.\n\nFree for all plans, Builder generates Fast code for the selected layers immediately, which is nearly instantly available. This code is best for rapid prototyping and working out quick concepts.\n\nQuality code generations\n\nQuality code generations further enhance fast code generations to support your framework and styling requirements by adding an additional AI model that has been fine-tuned to generate clean, semantic code just as developers would write themselves.\n\nQuality code generates at a more deliberate speed as AI considers the design as a whole and thoughtfully creates corresponding code.This bespoke option is more specific to your needs in that you can tell Builder's AI precisely what you want with custom instructions and prompts.\n\nFor more detail on using Quality code, read Prompting AI for customization.\n\nGenerating code for your Builder entry\n\nTo generate the code from your imported design:\n\nIn the Visual Editor, go to Develop.\nIn the pane that opens, select your Framework, Styling, Language, and other settings.\nClick the Generate Code button.\n\nThe video below shows this workflow:\n\nAfter generating the code, you can do one of the following to get your code into your codebase:\n\nCopy the code by clicking on the copy icon and paste it manually into your project.\nSync the code automatically, which the next section covers.\nSyncing the code automatically with your codebase\n\nTo automatically sync the generated code with your local project, it helps to have Devtools installed and the dev server running.\n\nTo install Devtools and start the dev server, if needed:\n\nExpand the Sync code section on the right.\nClick the Sync to Your Codebase button.\nCopy the npm command and run it in the terminal at the root of your project.\nStart the dev server.\n\nIf Devtools is installed and the dev server is running:\n\nWhen the dev server is running and detected*, the Sync to Your Codebase button turns blue. Now, when you click it, you'll receive a prompt for the location where you'd like to sync your code.\nEnter the path and file name or accept the default suggestion.\nClick Sync.\n\n*Detecting the dev server should only take about 2 seconds at a maximum.\n\nThe following video shows the entire process:\n\nFor more information on Devtools, visit Using Builder Devtools for Automated Integration.\n\nSyncing the code from the command line\n\nAs an alternative to using Devtools, you can run the generated npx command at the command line; for example, npx builder.io add ####, where #### is a hash that identifies the generated code.\n\nThe next video shows running this command and opening the synced code.\n\nPrompting AI for customization\n\nTo further customize your generated code with AI:\n\nBe sure you've selected Quality for the type of code.\nAt the bottom of the screen, select a suggestion or type in your own request.\n\nAs an example, the following video shows this process to break the content into separate components by selecting the multiple components suggestion:\n\nThe following image and example code show how AI worked to break the code up into separate components in the previous video:\n\nExpand for example code excerpts:\n\nCustomizableHeroLayout()\n\nHeroSection()\n\nFeatureSection()\n\nSuggested prompts for code generation include the following list. By selecting any of them, Builder regenerates the code while incorporating these features:\n\nUse Next.js Image: adds Next.js Image to your code.\nMake interactive: adds interactivity such as code that supports click events.\nBreak into multiple components: refactors code into separate components.\nUse props: adds props, making your code easier to maintain and use.\nUse MUI: uses the Material UI design system.\n\nFor other features, type your request into the input and press Enter.\n\nAdding persistent custom instructions\n\nIn addition to using the default prompts, you can give Builder your own instructions so that any time you generate code Builder will create it to your specifications.\n\nSaved custom instructions persist through logging out and apply across your Organization and Space per user. That means that if you add custom instructions, they only apply to your account, whereas a teammate's custom instructions would only apply to their own account.\n\nTo add your own custom instructions:\n\nIn the Generated Code panel, click the Settings wheel on the bottom left, next to the input.\nList your instructions by typing them in. You may also click on the suggestions to add them.\nWhen you're done, click the Save button.\n\nThe next video shows adding custom instructions:\n\nEditing or removing custom instructions\n\nTo remove or edit your custom instructions:\n\nClick the Get Code icon to open the Generated Code panel.\nIn the Generated Code panel, click the Settings wheel on the bottom left, next to the input.\nEdit or remove your instructions.\nWhen you're done, click the Save button.\n\nThe next video shows editing custom instructions:\n\nWhat's next\n\nIn addition to the process outlined above, you can fully integrate Pages, Sections, and Data and take advantage of Builder's features. Visit Integrating Pages for more information."
},
{
"title": "Integration Tips",
"url": "https://www.builder.io/c/docs/integration-tips",
"html": "Integration Tips\n\nThis document provides a collection of tips and solutions to help you integrate with Builder effectively. It covers common scenarios such as resolving API key mismatches, fixing model name discrepancies, handling common errors and enabling data-bindings in Node environments.\n\nFix an API Key mismatch\n\nIf you get a message in the Visual Editor that there's an API Key mismatch, it means that Builder and your codebase are using different API keys.\n\nCheck the API Key: Since each Space has its own Public API Key, if you have more than one Space in your Organization, make sure you are using the Public API Key for the intended Space.\nVerify the API Key in Builder: To confirm that you're using the correct Public API Key, check that the API Key in your codebase and the Public API Key in Builder for the intended Space are the same.\nFix a model name mismatch\n\nIf you get a message in the Visual Editor that there's a model name mismatch, it means that the Builder model name and the code component name in your codebase aren't the same.\n\nTo confirm that you're using the correct model name:\n\nIn Builder, go to Models.\nOpen the model in question and go to Advanced.\nMake sure the Unique Identifier is the same as the model name of the component in your codebase.\nCorrect a 404\n\nIf you're getting a 404 but aren't sure why, check these things:\n\nMake sure you've published your Page: In Builder, click the Publish button in the upper right corner of the Visual Editor.\nCheck the URL: If you name the page test2 for example, Builder adds a hyphen, so that the URL segment is test-2.\nSet the Preview URL: Make sure that you've set the preview URL on the Page Model.\nRestart the dev server: For some frameworks, you might have to restart the dev server.\nModify caching behavior in Next.js\n\nIf using Next.js, you may notice that your content changes do not show up on your website as quickly as you might like after publishing in Builder. This is due to the caching strategies Next.js uses by default. If you are experiencing this issue, consider modifying your Next.js cache settings.\n\nSee the Next.js documentation, particularly Caching in Next.js, to learn how to modify those settings. There you will find information on Opting Out from caching fetch request responses and Opting Out of Full Route Cache.\n\nEnable data-bindings in Node environments\n\nIn certain Node server environments, the builder SDK may require additional initialization steps, namely the initialization of a package called isolated-vm (used to safely evaluate your data bindings).\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nIf you're using Builder's Gen 1 SDKs and data binding on a provider with edge workers, such as Cloudflare, Netlify, or Vercel, you might encounter a situation where certain dependencies are automatically removed in their ISR (Incremental Static Regeneration) functions.\n\nTwo indicators can help identify this issue:\n\nHydration errors—where the SSR and the client side version are different—because the data binding did not execute on the server side.\nMissing data that populates on the client side; that is, the data binding is not executing on the server side.\n\nThis can lead to a failure with the function safeDynamicRequire. In such cases, consider applying the following workaround.\n\nIn the pages/_document.jsx file or any server-only execution location, add the following code:\n\nimport ivm from 'isolated-vm'\nimport { Builder } from '@builder.io/react'\n\nconst isolate = new ivm.Isolate({ memoryLimit: 128 });\nconst context = isolate.createContextSync();\nBuilder.setServerContext(context);\n\n\nIf there's no _document.tsx file in the project, you can add the code anywhere but wrap it with this condition:\n\nif (Builder.isServer) {\n // Add the provided code here\n}\n\n\nThis workaround should prove helpful when using Builder's Gen 1 React SDK on the server side with Vercel or similar platforms where automatic dependency removal might cause issues."
},
{
"title": "Intro to Models",
"url": "https://www.builder.io/c/docs/models-intro",
"html": "Intro to Models\n\nA model is a paradigm—a pattern for something else. Builder offers three kinds of models that define content types:\n\nA Page model: the basis for a full Page built in Builder\nA Section model: the basis for a part of a Page\nA Data model: gives structure to a collection of data that you render as you choose\n\nYou use these models as the defining source for content entries. Like a rubber stamp, the model provides a basic foundation. Each time you use a rubber stamp, the fundamental characteristics are the same but you might use the resulting image differently by varying other factors such as color and surface.\n\nSimilarly, with models in Builder you can define what a Page, Section, or collection of Data is and use those models over and over to build your site and populate it with content. And you can create as many models as you like.\n\nThe following graphic compares Builder models. Follow the Try it out link to play with a demo of each.\n\nVisual Pages\n\nTry out Pages\n\nUse Pages to manage entire pages, such as:\n\nMarketing and content pages\nLanding pages\n\nVisual Sections\n\nTry out Sections\n\nenterprise plans\n\nUse Sections to maintain parts of your site or app, such as:\n\nAnnouncement bars\nProduct editorial\nCollection heroes\nCart upsells\n\nStructured Data\n\nTry out Data\n\nUse Structured Data to manage structured data, such as:\n\nNavigation links\nProduct details\nBlog post authors\n\nAll models in Builder support:\n\nA/B Testing: Test different versions of your content.\nTargeting: Deliver specific content to the right people.\nScheduling: Publish your content at the right time.\nRoles and Permissions in a Space: Admins and Developers can edit models by default, but you can also specify permissions by content model using Custom Roles.\n\nThis means that you can granularly grant permissions, test, and precisely deliver content.\n\nExplore common integration patterns:\nLanding pages\nBlog Article\nHero Section\nNavigation Links\nAnnouncement Bar\nProduct Details\nProduct Editorial\nHomepage\nUse models to build your app\n\nWhen you use models to build your app, you can create exactly the Pages, Sections, and Data specific to your use case. With your integrated app, you can, for example, use your Sections in the Pages you choose as well as reuse Data wherever you need it.\n\nExamples of models include:\n\nA seasonal announcement banner placed on a page between certain dates.\nMarketing tile targeting a specific persona on certain pages.\nBlog authors whose profiles you want to link to from different parts of your site.\n\nBy creating models for each type of content you need, you can ensure consistency while making the process of iterating more efficient. The developer creates and integrates a model and non-developer teammates can use that model to create as many content entries as they need.\n\nThe following diagram shows a typical Builder documentation page. The left side navigation is a Section, the body of the document is a Page, and the font colors are stored in a Data content entry.\n\nComparing models\n\nWhen deciding which model to use, consider your use case.\n\nUse a Page model if you're creating Pages that use URLs and you want your teammates to edit them in the Visual Editor.\nUse a Section Model if you're creating parts of a page — with or without a URL — and you want your teammates to edit them in the Visual Editor.\nUse a Data Model if you want to bring your data into Pages or Sections and bind your data.\n\nAll models support structured data fields. The table below compares models in Builder to help you decide which to use when:\n\nModel Type\tPurpose\tRequires URL\tEditable in Drag-and-Drop Visual Editor\tSupports Structured Data Fields\n\nPage Model\n\n\t\n\nUse to create Pages\n\n\t\n\nYes\n\n\t\n\nYes\n\n\t\n\nYes\n\n\n\n\nSection Model\n\n\t\n\nUse to create Sections\n\n\t\n\nOptional, but most use cases don't need a URL.\n\n\t\n\nYes\n\n\t\n\nYes\n\n\n\n\nData Model\n\n\t\n\nUse to manage data\n\n\t\n\nN/A\n\n\t\n\nWhile you can use your Data in the Visual Editor, you must edit the data in the Data entry.\n\n\t\n\nYes\n\nWhat's next\n\nTo get the most out of Builder Models, be sure to integrate and learn about each type of model:\n\nPage Model: Learn what a Page model is and how to use one.\nIntegrating Pages: Integrate Page building with your code base so non-dev team members can create as many pages as they need and developers can focus on code.\nSection Models: Learn about Section use cases and how to use Sections in your app.\nIntegrating Sections: Integrate Builder Sections with your codebase so teammates can create and use Sections wherever they need them.\nData Models: Give shape to data and learn how to query that data.\nIntegrating CMS Data: Integrate data to create reusable data across your site.\nCustom Fields: Learn about the wide array of options available for shaping your models."
},
{
"title": "Using the Builder API Key",
"url": "https://www.builder.io/c/docs/using-your-api-key",
"html": "Using Builder API Keys\n\nAn API key is an alphanumeric string that you can use to connect your code base with Builder. Use the Builder Public API Key to integrate with Builder.\n\nAn example of a Builder API Key is bb209db71e62412dbe0114bdae18fd15.\n\nPrerequisites\n\nTo get the most our of this document, you should have the following:\n\nA Builder account\nAn app in your framework of choice\n\nTip: The Builder Public API Key is public, meaning that you don't have to keep it private. Because of this, there are no inherent security risks in it being publicly viewable, for example, on GitHub.\n\nFinding your Public API Key\n\nYou can find and copy your Public API Key with the following steps:\n\nWithin your Builder Space, press Cmd/Ctrl + k to open the Command Palette.\nStart to type the letters API into the search field to filter results.\nClick your API key to copy to your clipboard.\n\nAlternatively, you can also find your Public API Key in Account Settings for the Space:\n\nWithin your Builder Space, go to the Account Settings section.\nClick the copy icon to the right of the Public API Key field.\n\nThe video below shows both ways to find the Public API Key.\n\nUsing your Public API Key in your framework\n\nMost JavaScript apps use builder.init() to pass in the Public API Key. Replace YOUR_API_KEY with the Public API Key you copied from Account Settings.\n\n// Replace with your Public API Key\nbuilder.init('YOUR_API_KEY')\n\nThe following example shows what an actual Public API Key looks like when passed into builder.init().\n\n// an example of an actual API key passed into init()\nbuilder.init('bb209fb71eh2412dbe0114bdae18fd15')\nUsing your Public API Key in Angular\n\nIn Angular, pass your API Key into BuilderModule.forRoot(), by replacing YOUR_API_KEY with the Public API Key you copied in Account Settings. Place the forRoot() method in the @NgModule() imports array.\n\n@NgModule({\n declarations: [\n ...\n ],\n imports: [\n ...\n BuilderModule.forRoot(YOUR_API_KEY), // <-- Paste your API Key here.\n ...\n ],\n ...\n})\nexport class AppModule {}\n\nWhen you replace the YOUR_API_KEY placeholder, it looks similar to the following example.\n\n// An example API Key in use\nBuilderModule.forRoot('bb209fb71eh2412dbe0114bdae18fd15')\nManaging Private Keys\n\nUse Private Keys when you want to create a server-side only key for writing to your Builder account or to pull content that you want to keep private.\n\nTo view or use Private API Keys, you must have Admin or Developer permissions.\n\nTip: Keep your Private API Key secret. It allows anyone to have write access to your content in Builder. Only use it in API calls from your server, not calls from public client applications.\n\nRemember to ensure your Private API Keys are kept out of any version control system that you may be using.\n\nManaging an Organization's Private Key\n\nWith Organization Admin permissions, you can view, copy, or revoke the single, default Organization Private API Key. If you revoke the key, the dialogue gives you the option to create another key.\n\nTo manage the Private Key for your Organization:\n\nGo to the Organization Account Settings.\nTo the right of Private Keys, click the Edit button.\n\nFor more information on Admin permissions at the Organization level, see Managing Your Organization.\n\nManaging multiple Private API Keys in a Space\n\nIf you need to manage or create multiple Private API Keys, go to the Space Account Settings, rather than the Organization settings.\n\nTo manage the Private Key for your Organization:\n\nGo to the Organization Settings.\nTo the right of Private Keys, click the Edit button.\nCreate or revoke as many keys as you need.\n\nTo use Private Keys in a Space, make sure the Public readable toggle in the model is turned off. Then use the Content API to request private content using a Private API Key.\n\nFor more information, see Creating a Private Page.\n\nWhat's next\n\nWith your API Key in place, you can integrate powerful Builder features. To get started, check out the following tutorials:\n\nIntegrating Pages: set up your app so teammates can build Pages on their own.\nIntegrating Sections: integrate Section building for reusable content\nIntegrating CMS Data: create structured reusable data across your site\nIntegrating Symbols: elegantly reuse data across your app\nIntegrating Custom Components: use your custom components in Builder's drag-and-drop UI"
},
{
"title": "Design Tokens",
"url": "https://www.builder.io/c/docs/design-tokens",
"html": "Design Tokens\n\nin beta\n\nBy providing your own design tokens, you can define a consistent set of design values that are available to your users in the Builder Visual Editor.\n\nIn this way you can:\n\nMaintain brand consistency. By providing predefined design tokens, you ensure that your app's design stays consistent and adheres to your brand guidelines.\nStreamline content creation. Users can quickly select from a curated set of design options, rather than having to manually input values or make design decisions.\nCentralize design updates. When you update your design tokens in code via CSS variables, those changes are reflected across your app, making it easy to manage and evolve your design system.\n\nThe image below compares the default Style tab in the Visual Editor (on the left) with a customized Style tab using design tokens (right).\n\nYou have flexibility in how you configure and use design tokens:\n\nCustomizable values. You can define design tokens for various CSS properties, such as colors, spacing, typography, and other CSS properties. Choose which properties are most important to standardize for your app.\nIntegration with CSS variables. Use CSS variables to define your token values, allowing for efficient updates and theming across your application.\nGranular control. Decide which CSS properties users can edit and whether they can input custom values or only select from your predefined tokens.\n\nThis document explores how to register design tokens in your code and the various options available for fine-tuning behavior in the Visual Editor.\n\nRegistering design tokens\n\nTo register design tokens with Builder, use the register() function from the Builder SDK and provide your designTokens definition in the editor.settings object.\n\nHere's an example of specifying design tokens in code for use in the Builder Visual Editor:\n\nFor maintainability, we recommend using CSS variables as token values whenever possible.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n styleStrictMode: true, // optional\n designTokens: {\n colors: [\n { name: \"Brand Red\", value: \"var(--red, #ff0000)\" },\n { name: \"Brand Blue\", value: \"rgba(93, 150, 255, 1)\" },\n ],\n spacing: [\n { name: \"Large\", value: \"var(--space-large, 20px)\" },\n { name: \"Small\", value: \"var(--space-small, 10px)\" },\n { name: \"Tiny\", value: \"5px\" },\n ],\n fontFamily: [\n { name: 'Serif Font', value: 'var(--serif-font, Times, serif)' },\n { name: 'Primary Font', value: 'Roboto, sans-serif' },\n ]\n },\n});\n\n\nThe image below shows how the above example code renders in the Visual Editor. Notice that the colors, spacing, and font family specified in the code are now available in the Style tab.\n\nProperties\n\nThe most commonly used properties you can assign tokens to are colors, and spacing but you can also define tokens for any other CSS properties such as backgroundImage, borderRadius, and boxShadow, to name a few.\n\nDesign tokens are defined as an array of objects, where each object has two properties:\n\nname: the display name in the Visual Editor\nvalue: the CSS value, such as a CSS variable (recommended)\n\nChanges to design token values are not retroactive unless you use CSS variables\n\nIf you update the value property in your code to a new value, existing usages of the token will keep the old value.\n\nTo set values that can be updated retroactively, read the CSS variables for dynamic design tokens section later in this document.\n\nProperty: colors\n\nAffects all color-related properties in the Visual Editor, such as font color, background color, and border color.\n\nExample:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n designTokens: {\n colors: [\n { name: \"Brand Blue\", value: \"var(--brand-primary, #0000ff)\" },\n { name: \"Brand Red\", value: \"var(--red, red)\" },\n ],\n // other design tokens\n },\n});\n\n\nColor properties\n\nname: the display name of the color token in the Visual Editor.\nvalue: the CSS color value, which can be a hex code, RGB, RGBA, or a CSS variable.\nProperty: spacing\n\nAffects all spacing-related properties in the Visual Editor, such as margin, padding, and sizing.\n\nExample:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n designTokens: {\n spacing: [\n { name: \"Tiny\", value: \"5px\" },\n { name: \"Small\", value: \"10px\" },\n { name: \"Large\", value: \"var(--space-large, 20px)\" },\n ],\n // other design tokens\n },\n});\n\n\nSpacing properties\n\nname: the display name of the spacing token in the Visual Editor.\nvalue: the CSS spacing value, which can be in pixels, ems, rems, or percentages.\nCSS variables for dynamic design tokens\n\nWhen defining design tokens, considering how you want to update and maintain those tokens in the future is key. By using CSS variables to define your design tokens, you can update the token values in your code and have those changes automatically reflect across all content using those tokens.\n\nHow CSS variables work with design tokens\n\nWhen you select a token in the Visual Editor, the value comes from the CSS variable defined in your CSS. Fallback values in the designTokens configuration are used only when the CSS variable is undefined. These are not the primary source of truth.\n\nWhy defining variables in CSS is important\n\nUsing CSS variables as the source of truth means:\n\nCentralized updates: A single change in your CSS file updates all instances of the variable across your app.\nConsistency: Ensures the fallback value is only used as a safety net for edge cases.\nMaintainability: Reduces the need to update individual design tokens in the Builder configuration.\nBest practices for defining CSS variables\n\nWhen working with CSS variables and design tokens, use these guiding principles:\n\nDefine CSS variables in a global CSS file. Use a file like global.css to define your variables.\nReference defined CSS variables in your design tokens. In your design tokens configuration, use the var() function to reference these CSS variables. Provide a fallback value only for edge cases where the variable might not be defined.\nUpdate CSS variables directly in CSS. When you want to change the value of a token, update it in your CSS file — such as global.css. This way the change propagates everywhere you use the variable.\nDefine global CSS variables\n\nTo use CSS variables for your design tokens, first define the variables in your CSS code. For example, in your global.css:\n\n:root {\n --primary-color: rgb(12, 34, 56);\n --spacing-large: 20px;\n}\n\n\nBest practice: always set default values\n\nWhen using CSS variables, always set a default value as the second argument in (var(--name, default-value)), so Builder's Visual Editor can pick up a value, such as the color preview swatch.\n\nNext, reference your defined variables in designTokens and then, when needed, update the variable directly in your CSS as in the next sections.\n\nReference CSS variables with designTokens\n\nTo use CSS variables in the designTokens object, reference the CSS variables using the var() function.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n designTokens: {\n colors: [\n { name: \"Primary\", value: \"var(--primary-color, #ff0000)\" },\n // ...\n ],\n spacing: [\n { name: \"Large\", value: \"var(--spacing-large, 20px)\" },\n // ...\n ],\n // ...\n }\n})\n\n\nIn this example, the Primary color token is defined using the --primary-color CSS variable, and the Large spacing token is defined using the --spacing-large CSS variable.\n\nUpdate design tokens with CSS variables\n\nTo update the values of your design tokens, that are using CSS variables, update the corresponding CSS variables in your code. For example, if you want to change the primary color from red to pink, update the --primary-color variable in your CSS:\n\n:root {\n --primary-color: pink;\n /* ... */\n}\n\n\nBy updating the CSS variable value, all content using the Primary color token automatically update to pink without requiring any manual changes in Builder.\n\nUsing CSS variables for your design tokens provides flexibility and maintainability, so you can update and theme your design system across your application.\n\nKey takeaways\nAlways define CSS variables in your CSS files, not just as fallback values in the designTokens configuration.\nUse fallback values only as a backup, not as the primary source of truth.\nTo change a token’s value, update the corresponding CSS variable in your CSS file.\nHiding CSS properties\n\nTo prevent a CSS property from displaying in the Visual Editor, supply false for that CSS property. The code snippet below hides the font family select:\n\ndesignTokens: {\n fontFamily: false\n}\n\n\nThe above setting would cause Builder to hide the font family select. In the left screenshot below, the font family select is hidden because fontFamily is set to false. On the right, fontFamily has properties configured in the designTokens object so they display in the Visual Editor.\n\nOverriding CSS properties\n\nYou can override any CSS property by specifying that CSS property in camel case. This section covers a number of examples, but this technique is applicable to a wide range of CSS properties.\n\nYou can use this same technique with any of the CSS options in the Style tab.\n\nExamples include:\n\nborder\nboxShadow\nfontSize\nfontFamily\nletterSpacing\nmaxWidth\nfontWeight\ntextShadow\n\nWhen configuring any CSS properties, provide a name and value, just as with any design token. Some examples follow.\n\nExample: border\n\nAffects the box shadow selection in the Visual Editor's style settings.\n\nExample:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n designTokens: {\n border: [\n { name: 'Success', value: 'var(--border-error, 1px solid red)' },\n { name: 'Error', value: '1px solid var(--red, #ff0000)' }\n ]\n // other design tokens\n },\n});\n\n\nProperties\n\nname: the display name of the border token in the editor.\nvalue: the CSS border value, which can include the border width, style, and color. It can also use CSS variables.\n\nIn this example, one border token is defined:\n\nSuccess with a value of 1px solid var(--green), representing a 1px solid border with a color defined by the CSS variable --green.\n\nExample: boxShadow\n\nAffects the box shadow selection in the Visual Editor's style settings.\n\nExample:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n designTokens: {\n boxShadow: [\n { name: 'Small', value: 'var(--shadow-small)' },\n { name: 'Medium', value: '0 0 var(--shadow-medium, 10px) var(--black-medium, black)' },\n { name: 'Large', value: '0 0 20px rgba(0, 0, 0, 0.5)' }\n ]\n // other design tokens\n },\n});\n\n\nProperties\n\nname: The display name of the box shadow token in the editor.\nvalue: The CSS box shadow value, which can include the horizontal offset, vertical offset, blur radius, spread radius, and color. It can also use CSS variables.\n\nIn this example, two box shadow tokens are defined:\n\nSmall with a value of 0 0 5px rgba(0, 0, 0, 0.1), representing a small shadow with a 5px blur radius and a semi-transparent black color.\n\nMedium with a value of 0 0 var(--shadow-medium) var(--black-medium), using CSS variables for the blur radius and color.\n\nExample: fontFamily\n\nAffects the font family selection in the Visual Editor's text settings.\n\nExample:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n designTokens: {\n fontFamily: [\n { name: 'Serif', value: 'var(--font-serif, Times, serif)' },\n { name: 'Sans serif', value: 'Roboto, sans-serif' }\n ]\n // other design tokens\n },\n});\n\nDesign tokens by space, model, role, or permissions\n\nYou can register different design tokens based on a number of different attributes, such as the currently editing model, space, user role name, or permissions.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nconst url = new URL(window.location.href);\n\nconst spaceId = url.searchParams.get('builder.space'); // the Public API Key of this space\nconst modelName = url.searchParams.get('builder.preview'); // for example, 'page'\nconst userRoleName = url.searchParams.get('builder.role.name'); // for example, 'Admin'\nconst userPermissions = url.searchParams.get('builder.role.permissions'); // for example, 'editDesigns,editCode,admin'\n// See a full list of permissions names here: https://www.builder.io/c/docs/register-components-options#required-permissions\nconst permissionsList = userPermissions.split(',')\n\n// Based on the model name, register different design tokens \nif (modelName === 'page') {\n Builder.register('editor.settings', {\n // Enable strict mode based on specific permissions\n styleStrictMode: !permissionsList.includes('editCode'),\n designTokens: {\n // your design tokens\n }\n })\n// if it's another Space, apply these design tokens instead\n} else {\n Builder.register('editor.settings', {\n designTokens: {\n // your other design tokens\n }\n })\n}\n\nAllowing custom values with allowOverridingTokens\n\nBy default, when you define design tokens for a specific CSS property, the Visual Editor limits users to selecting only from the predefined token values for that property. However, you may want to give users the flexibility to enter custom values in addition to the predefined tokens.\n\nallowOverridingTokens is a boolean that you can use to specify that users can override registered design tokens. This encourages use of the registered values, while still providing the option for users to specify other values.\n\nIn the video below, users can add values to a CSS property because allowOverridingTokens is set to true. In this example, the user expands the font select to find only the registered design tokens of a serif font and a sans serif. However, with allowOverridingTokens to true, the user can type in their font.\n\nTo enable this behavior, set the allowOverridingTokens option to true when registering design tokens:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n // let users use your design tokens\n // while still having access to built-in settings\n allowOverridingTokens: true, \n designTokens: {\n // ...\n },\n});\n\n\nWhen allowOverridingTokens is set to true, users can select from the predefined design tokens or enter custom values for the corresponding CSS properties just as they would when there are no design tokens provided in the codebase. However, in order to override the values, users need to manually enter their desired value.\n\nThis provides a balance between maintaining consistency through predefined tokens and providing flexibility for custom values when needed.\n\nStrict mode\n\nWhen strict mode is off or false, which is the default, and you supply design tokens for a specific CSS property, the Visual Editor only allows selecting from the predefined tokens for that property. Custom values cannot be entered for properties that have design tokens defined.\n\nStrict mode takes this a step further. When strict mode is on, any styles that don't have corresponding design tokens are removed from the Visual Editor and users won't be able to edit those styles at all.\n\nThe snippet below shows styleStrictMode set to true in the the register() function:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n styleStrictMode: true, // strict mode on, users limited to your design tokens\n designTokens: {\n // ...\n },\n});\n\n\nIf strict mode is set to true and no design tokens are supplied, almost all styling options are removed. Users will only be able to adjust basic settings like text alignment and layout alignment.\n\nWhen strict mode is on, and you have design tokens supplied for specific CSS properties, users can edit those properties but are limited to the predefined token values. All other properties without design tokens are hidden and not editable.\n\nMaking design tokens optional\n\nWith designTokensOptional, you can provide your design tokens while keeping the built-in Builder options available to your users.\n\nFor example, when registering your editor settings, add designTokensOptional set to true:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\nimport { Builder } from \"@builder.io/react\";\n\nBuilder.register(\"editor.settings\", {\n designTokensOptional: true, // <-- make your design tokens optional\n designTokens: {\n // ...your design tokens here that show up\n // along with the Builder settings\n },\n});\n\n\nAs an example, the image below shows brand colors that are specified in the designTokens object. Because designTokensOptional is set to true, they show up in the Builder Visual Editor anywhere there's a color selection available. Here, they display in the list of colors while the color picker remains available:"
},
{
"title": "Integrating Symbols",
"url": "https://www.builder.io/c/docs/integrate-symbols",
"html": "Integrate Symbols\n\nSymbols are a type of Section model you can integrate for editing on your site or app. They help you elegantly reuse content across many Builder Pages and Sections. For more information, see Intro to Symbols.\n\nPrerequisites\n\nTo get the most out of this document, you should have:\n\nintegrated Pages or integrated Sections\na Symbol model that you've already created\nAdd Symbol editing to your app\n\nCreate a special page on your site specifically for Symbol editing. This is what the Builder preview opens when you create and edit symbols. It's important this be on a URL directly on your site, so all previewing and editing are accurate.\n\nIn this example, this page is named /edit-symbol.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nCreate a page with the following contents. Make sure to replace YOUR_API_KEY with your Public API Key:\n\n// pages/edit-symbol.jsx\n\nimport { BuilderComponent, builder } from '@builder.io/react';\n\n// Replace with your Public API Key.\nbuilder.init(YOUR_API_KEY);\n\nexport default function Page() {\n return <BuilderComponent model=\"symbol\" />\n}\n\n\nBuilderComponent gives the drag and drop Visual Editor a region to work in in your site.\n\nNote that if you have registered custom components, you must import them on this page so that they are available in the Visual Editor.\n\nFor instructions on getting your Public API Key, see Finding Your Public API Key in Using Builder API Keys.\n\nUpdate your Symbol Preview URL\nGo to Models and choose the Symbol model. If you don't have Symbol here, make sure that you've met the prerequisite of having created a Symbol. For step-by-step instructions, read Making a Symbol.\nEnter your site domain at a specifc path, such as/edit-symbol, for example https://my-site.com/edit-symbol.\nClick Save.\n\nYou can use localhost when testing locally, then change to a hosted URL like your QA or production URL once your code updates have been deployed.\n\nFor more examples of what you can do with Builder, check out the Blueprints, which cover varied use cases at a high-level with code examples."
},
{
"title": "Integrate Structured Data",
"url": "https://www.builder.io/c/docs/integrate-cms-data",
"html": "Integrate Structured Data\n\nYou can use Builder CMS Data to create structured reusable data across your site. You can manage the data schema, add, and remove fields within the UI and teammates can create and remove data items in auto-generated structured forms.\n\nExamples include:\n\nHeader navigation links\nProduct Details\nBlog authors\nStructured rich content such as user profiles\n\nThis tutorial shows you how to add editable navigation links to your site header.\n\nPrerequisites\n\nTo follow along with this tutorial, you should have the following:\n\na Builder account\nan app in the framework of your choice with the appropriate SDK installed\nAdd header navigation link data to your app\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nCreate a page with the following contents, replacing YOUR_API_KEY with your account's Public API Key:\n\n// pages/your-page.jsx\n\nimport { builder } from \"@builder.io/react\";\nimport { GetStaticProps, GetStaticPaths } from \"next\";\n\n// TO DO: Replace with your Public API Key.\nbuilder.init(YOUR_API_KEY);\n\nexport async function getStaticProps() {\n const links = await builder.getAll(\"nav-link\", {\n // Add options for queries, sorting, and targeting here\n });\n\n return {\n props: {\n links: links || null,\n },\n };\n}\n\nexport default function Home({ links }) {\n return (\n <>\n <header>\n <nav>\n {links.map((link, index) => (\n <a key={index} href={link.data.url}>\n {link.data.label}\n </a>\n ))}\n </nav>\n </header>\n {/* <RestOfYourPage /> */}\n </>\n );\n}\n\n\nCreating a Data model\n\nIn the Builder UI, create a Data model so you can create navigation links.\n\nIn the Models section of Builder, Click +Create Model.\nSelect Data.\nEnter Nav link as the name for your new Data model.\nClick +New Field.\nName the first field label and give it a type of Text.\nRepeat steps 3 and 4 to make a second label named Url with type url.\nClick Save.\nCreating nav link content entries\n\nUse the new Data model to create Nav Link content entries.\n\nGo to the Content section of Builder.\nClick +New.\nSelect Nav Link.\nGive it a label, url, and name.\nClick Publish.\n\nTo make more links so that you can iterate through the links in your nav list, click the three dots and select Duplicate. Repeat steps 2-4 for each link you create.\n\nThe video below shows how to make three Nav Link entries.\n\nGo back to your website and refresh the page to see your nav links. After your links are rendering, try adding new content entries in Builder. For each new entry, the new link populates the nav.\n\nLive previewing structured data\n\nWhen working with structured data, it's important to set up live previewing to see real-time updates in the Visual Editor without publishing. This is especially useful for dynamic content like navigation links.\n\nFor detailed information and examples, read Live Previewing Data Models and Custom Fields.\n\nWhat's next\n\nFor more information on how to work with Models in Builder, refer to Understanding Content Models."
},
{
"title": "Integrating Sections",
"url": "https://www.builder.io/c/docs/integrate-section-building",
"html": "Integrate Sections\n\nenterprise plans\n\nYou can use Builder Sections to create reusable content across multiple pages. You can manage the code within your codebase, and teammates in the UI can iterate in the Visual Editor.\n\nExamples include:\n\nBlog Article\nHero Section\nAnnouncement Bar\nProduct Editorial\nHomepage\n\nThis tutorial shows you how to create and add an announcement bar section to a page.\n\nFor more conceptual information Section Models, refer to the Section Models documentation.\n\nPrerequisites\n\nTo follow along with this tutorial, you should have the following:\n\na Builder account\nan app in the framework of your choice with the appropriate Builder SDK installed\nAdd an announcement bar section to your app\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nCreate a page with the following contents. Make sure to replace YOUR_API_KEY with your Public API Key:\n\n// pages/[...page].tsx\nimport React from \"react\";\nimport { useRouter } from \"next/router\";\nimport { BuilderComponent, builder, useIsPreviewing } from \"@builder.io/react\";\nimport { BuilderContent } from \"@builder.io/sdk\";\nimport { GetStaticProps } from \"next\";\n\n// Replace with your Public API Key\nbuilder.init(YOUR_API_KEY);\n\n// Define a function that fetches the Builder\n// content for a given page\nexport const getStaticProps: GetStaticProps = async ({ params }) => {\n // Fetch the builder content for the given model\n const announcementBar = await builder\n .get(\"announcement-bar\", {\n userAttributes: {\n urlPath: \"/\" + ((params?.page as string[])?.join(\"/\") || \"\"),\n },\n })\n .toPromise();\n\n // Return the announcement bar content as props\n return {\n props: {\n announcementBar: announcementBar || null,\n },\n // Revalidate the content every 5 seconds\n revalidate: 5,\n };\n};\n\n// Define the announcement bar component\nexport default function announcementBar({ announcementBar }: { page: BuilderContent | null }) {\n const router = useRouter();\n const isPreviewing = useIsPreviewing();\n\n // If the announcement bar is available, render\n // the BuilderComponent with the content\n\n return (\n <>\n {/* Render the announcement bar */}\n <BuilderComponent model=\"announcement-bar\" content={announcementBar || undefined} />\n </>\n );\n}\n\n\n\nThe BuilderComponent accepts several props for customization. One important prop for client-side routing is renderLink, which means you can implement custom routing. For more information on renderLink and other props, visit the renderLink entry in Using BuilderComponent.\n\nHere's an example of how you might use the renderLink prop:\n\n<BuilderComponent \n model=\"page\" \n content={content} \n renderLink={(props) => <CustomLink {...props} />}\n/>\n\n\nSections are typically targeted using some information about the user's state.\n\nFor instance, you can display an announcement bar when the user visits particular URLs. With custom targeting attributes, you can even display content based on complex conditions, such as when a user adds a particular item to their cart.\n\nAside from targeting, you can also query sections by custom fields.\n\nconst urlPath = '/' + (params?.page?.join('/') || '');\n\nconst announce = await builder\n .get('announcement-bar', { userAttributes: { urlPath } })\n .toPromise();\n\n\nThe announcement bar section in the example above is targeted with the current URL using the urlPath targeting attribute. When Builder finds an announcement bar with a matching URL, it responds with that announcement bar's content.\n\nThe snippet below demonstrates how the announcement bar is rendered in the context of the page.\n\nreturn (\n <>\n <!-- Put your header here -->\n <YourHeader />\n <BuilderComponent model=\"announcement-bar\" content={announce} />\n <!-- The rest of your page -->\n <TheRestOfYourPage />`\n </>\n);\n\n\nBuilderComponent receives the content for the announcement bar through the content prop and renders it next to your page's content.\n\nYou can also render a Builder-managed page next to your announcement bar or any other section by placing multiple BuilderComponent instances next to each other.\n\nCheck out How to Create a Page for a step-by-step tutorial on how to create a page in Builder and Integrating Pages on how to render your page content within your template.\n\nCreating a Section model\n\nCreate a Section model so you can make an announcement bar content entry.\n\nGo to Models.\nClick +Create Model.\nSelect Section.\nEnter Announcement bar as the name for your new Section model.\nFor all frameworks except Swift: change the Preview URL on the Model Options page to the URL of the page that you added code to display your section. This example uses http://localhost:####/announcements, but yours might be different.\nClick Save.\n\nThe video below demonstrates this process:\n\nWhen you create or edit an announcement bar section, the Visual Editor displays your content embedded within your Preview URL page, providing visual context and importing styles from your site. It's a live view of your section, as it will look on one of your pages when you publish.\n\nPublished Sections typically appear across multiple pages with different URLs depending on how they're targeted. When previewing in the editor, however, they only appear within the Preview URL's page. For more information, refer to Editing and Previewing Your Site.\n\nFor more information what Section Models are and how to use them, refer to the Section Models documentation.\n\nCreating an announcement bar content entry\n\nNow that your Section model is set up, you can create an announcement bar content entry to add an announcement bar to your site.\n\nGo to Content.\nClick the + New Entry button and select Announcement bar.\nBuild and style your announcement bar.\nName the content entry.\nClick Publish.\n\nThe video below demonstrates this process:\n\nTargeting by URL path\n\nTo make your announcement bar display based on targeting, in the section content entry; for example, in the announcement bar:\n\nClick on the Targeting icon.\nFor Where, select URL path.\nAdd the URL path you'd like to target.\nClick the Publish button.\n\nThe video below shows this process in an integrated Remix app where the targeted URL path is /builder so that the announcement bar doesn't show up on any other URLs. This process is the same, regardless of the framework you use. The URL path you target, however, might differ.\n\nIf you're using Gatsby, you might need to restart your app to render the announcement bar.\n\nLive previewing custom fields and Data models\n\nWhen working with sections that use custom fields or data models, it's helpful to set up live previewing. In this way you get real-time updates in the Visual Editor without having to publish your changes.\n\nFor detailed instructions on setting up live previewing for your custom fields and data models, visit Live Previewing Data Models and Custom Fields.\n\nWhat's next\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nWith your app and Builder working together, the next step is the fun part–add some more Sections in Builder and drag in some elements. Play with styles and explore the UI.\n\nDeploy your updated app to a preview environment\n\nIntegrate Custom Components\n\nIntegrate Design Tokens\n"
},
{
"title": "Integrate Pages",
"url": "https://www.builder.io/c/docs/integrating-builder-pages",
"html": "Integrate Pages\n\nAs a developer, you can integrate Builder into your codebase and give other team members, such as content editors, marketers, and designers, the ability to build and manage pages without ever having to ping you.\n\nThis guide is detailed. If you're using React, Next.js, Remix, Angular with standalone components, or Qwik and you'd prefer a more automated process, visit Developer Quickstart, which uses Devtools to integrate for you.\n\nAdd Builder as a dependency\n\nWe highly recommend that you integrate Builder into an existing app, and these instructions assume you already have one. However, if you need to create an app, and would like instructions, visit Creating an App.\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nWant a shortcut? Get going right away with Builder and Next.js; use Builder's Devtools for Automatic Integration. Devtools fully automates your integration, so you don't have to take the steps in the rest of this document.\n\nIf you choose not to use the built-in Builder integration with Next.js with Devtools, continue with the instructions below.\n\nAt the command line, at the root of your project, use npm to install the Builder SDK:\n\nnpm install @builder.io/react\n\nIf you're using Windows, be sure to use quotes when you install dependencies that use the @ operator; for example, npm install \"@builder.io/react\".\n\nStart the development server:\n\nnpm run dev\nAdd a Builder component to your app\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nPaste the following code into a new file within the pages directory called [...page].tsx (you must include the brackets and dots), making sure to replace YOUR_API_KEY with your Public API Key.\n\nIf you don't have a pages directory, be sure to create one.\n\nThis code gets your Page from Builder and displays the page between the header and footer. As a best practice, the header and footer reside in the codebase, as in this example.\n\n// pages/[...page].tsx\nimport React from \"react\";\nimport { useRouter } from \"next/router\";\nimport { BuilderComponent, builder, useIsPreviewing } from \"@builder.io/react\";\nimport { BuilderContent } from \"@builder.io/sdk\";\nimport DefaultErrorPage from \"next/error\";\nimport Head from \"next/head\";\nimport { GetStaticProps } from \"next\";\n\n// Replace with your Public API Key\nbuilder.init(YOUR_API_KEY);\n\n// Define a function that fetches the Builder\n// content for a given page\nexport const getStaticProps: GetStaticProps = async ({ params }) => {\n // Fetch the builder content for the given page\n const page = await builder\n .get(\"page\", {\n userAttributes: {\n urlPath: \"/\" + ((params?.page as string[])?.join(\"/\") || \"\"),\n },\n })\n .toPromise();\n\n // Return the page content as props\n return {\n props: {\n page: page || null,\n },\n // Revalidate the content every 5 seconds\n revalidate: 5,\n };\n};\n\n// Define a function that generates the\n// static paths for all pages in Builder\nexport async function getStaticPaths() {\n // Get a list of all pages in Builder\n const pages = await builder.getAll(\"page\", {\n // We only need the URL field\n fields: \"data.url\",\n options: { noTargeting: true },\n });\n\n // Generate the static paths for all pages in Builder\n return {\n paths: pages.map((page) => `${page.data?.url}`).filter(url => url !== '/'),\n fallback: 'blocking',\n };\n}\n\n// Define the Page component\nexport default function Page({ page }: { page: BuilderContent | null }) {\n const router = useRouter();\n const isPreviewing = useIsPreviewing();\n\n // If the page content is not available\n // and not in preview mode, show a 404 error page\n if (!page && !isPreviewing) {\n return <DefaultErrorPage statusCode={404} />;\n }\n\n // If the page content is available, render\n // the BuilderComponent with the page content\n return (\n <>\n <Head>\n <title>{page?.data?.title}</title>\n </Head>\n {/* Render the Builder page */}\n <BuilderComponent model=\"page\" content={page || undefined} />\n </>\n );\n}\n\n\n\nA later section in this tutorial guides you through getting your Public API Key from the Account section of Builder. When you have your Public API Key be sure to add it to the builder.init() method in this code snippet. The API Key is required for connecting your app to Builder.\n\nIf you don't have an index route, such as pages/index.tsx , use pages/[[...page.tsx]] with two sets of square brackets. The two square brackets means that Builder handles the app's home page.\n\nThe single set of square brackets, in this tutorial, assumes that you are keeping your home page.\n\nThe BuilderComponent accepts several props for customization. One important prop for client-side routing is renderLink, which means you can implement custom routing. For more information on renderLink and other props, visit the renderLink entry in Using BuilderComponent.\n\nHere's an example of how you might use the renderLink prop:\n\n<BuilderComponent \n model=\"page\" \n content={content} \n renderLink={(props) => <CustomLink {...props} />}\n/>\n\nUnderstanding the code\n\nAfter the imports, you specify the Builder Public API Key and, with builder.init(), connect your app to Builder.\n\nThough it's not the syntax this example uses, if you're using the process.env syntax with Next.js for API keys and SDK initialization, be sure to prefix it with NEXT_PUBLIC_, as described in the Next.js documentation for Exposing Environment Variables to the Browser.\n\nBuilding paths with getStaticProps()\n\nThe getStaticProps() function tells you what paths the app is building. Here, Builder gets the page and creates the URL, otherwise, if there's no page, you'll get null and a 404.\n\nexport async function getStaticProps({ params }) {\n const page = await builder\n .get('page', {\n userAttributes: {\n urlPath: '/' + (params?.page?.join('/') || ''),\n },\n })\n .toPromise();\n\n return {\n props: {\n page: page || null,\n },\n revalidate: 5\n };\n}\n\n\nrevalidate: 5 means that Next.js attempts to re-generate the page under these conditions:\n\nWhen a request comes in\nAt most once every 5 seconds\nTo check if Builder has updates to the page\nGetting a list of pages with getStaticPaths()\n\nThe getStaticPaths() function returns a list of page URLs, omits unnecessary data for creating the list, and with fallback: true, checks Builder for any new pages you might have added.\n\nexport async function getStaticPaths() {\n const pages = await builder.getAll('page', {\n options: { noTargeting: true },\n });\n\n return {\n paths: pages.map(page => `${page.data?.url}`),\n fallback: true,\n };\n}\n\nThe React component\n\nThe last section is a React component called Page(). It gets the page data and checks that Builder is present. If there's no page and no Builder, you get a 404. Otherwise, you get your Builder page.\n\nNext, this snippet renders the title field to be the page title. You can also add your own custom fields to render other information; for example, for SEO metadata.\n\nexport default function Page({ page }) {\n const router = useRouter();\n const isPreviewing = useIsPreviewing();\n\n if (router.isFallback) {\n return <h1>Loading...</h1>\n }\n\n if (!page && !isPreviewing) {\n return <DefaultErrorPage statusCode={404} />\n }\n\n return (\n <>\n <Head>\n <title>{page?.data.title}</title>\n </Head>\n\n <BuilderComponent model=\"page\" content={page} />\n </>\n );\n}\n\n\nUsing your app with Builder\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nBuilder adds the ability for your team members–even those who don't code–to create and iterate on ideas with a drag-and-drop interface.\n\nHead over to Builder.io to sign up for an account if you don't already have one. Come back when you're logged in.\n\nThis next video covers the steps in this section of the tutorial all in one place to give you an idea of how it all works and the end result. This example uses Next.js but all frameworks use the same process:\n\nGetting your API Key\n\nTo connect your Builder.io space to your application, add the Public API key to your code.\n\nFind your Public API Key within Builder.io in one of two ways:\n\nPress Cmd/Ctrl+k in Builder to bring up the command palette and search for API Key. Clicking the Public API Key copies it to your clipboard.\nGo to Settings and copy your Public API Key.\n\nFor more detail about the Public API Key, see Using Builder API Keys.\n\nPaste the Public API Key into your app by replacing the YOUR_API_KEY placeholder in your code. This location varies depending on your framework and is covered in the earlier sections of this tutorial. Make sure to wrap your Public API Key in quotes.\n\nThe following video shows copying the Public API Key and pasting it into a Next.js app.\n\nSetting the model preview URL\n\nTo enable Builder to open your site in the Visual Editor, provide a URL that Builder can open which has the Builder rendering component in it.\n\nGo to Models and choose the Page model.\nSet the Preview URL to http://localhost:<your-port>, where <your-port> is the port your app is using. Be sure to include the http://.\nClick Save.\n\nThe following video shows these steps:\n\nCreating a Builder Page\n\nCreate a Builder Page to use with your integrated app.\n\nGo to Content.\nClick the +New button near the top right of the screen.\nCreate a new Page in Builder and name it Test Page. Notice that Builder automatically generates the path as /test-page.\nThe Editor for your new Page loads automatically.\nIn your new Page, drag in a Text block.\nClick Edit and add something like, \"I did it!!\".\nClick the Publish button in the upper right of the browser.\n\nThe next video shows creating a Page in a Builder-integrated app and dragging in a text block:\n\nAfter you deploy your updates, be sure to update this to a public URL, such as your live site or your staging site; for example, https://your-site.com, so anyone on your team can connect to your site for visual editing.\n\nGo to http://localhost:<your-port>/test-page and check out your work. Well done!\n\nIf you're getting a 404 but aren't sure why, check these things:\n\nMake sure you've published your page in Builder by clicking the Publish button on the upper right corner.\nCheck the URL. If you name the page test2 for example, Builder adds a hyphen, so that the URL segment is test-2.\nMake sure that you've set the preview URL on the Page Model.\nFor some frameworks, you might have to restart the dev server.\n\nFor more information regarding special use cases, visit Integration Tips.\n\nBuilder Pages best practice\n\nWe recommend that you place your Builder pages between your header and footer. A common use case is developers keeping headers and footers in their codebase while integrating page building. In this way, non-developer team members can iterate on pages, without having to rely on developers.\n\nTo use Builder pages between your header and footer, follow the guidance below for your framework:\n\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nImport your header and footer along with the other JavaScript imports at the top of [...page].jsx.\n\nAdd the header and footer components before and after BuilderComponent.\n\n+ import MyHeader from '../components/my-header'\n+ import MyFooter from '../components/my-footer'\n\n export default function Page({ page }) {\n ...\n return (\n <>\n <Head>\n <title>{page?.data.title}</title>\n </Head>\n\n+ <MyHeader />\n <BuilderComponent model=\"page\" content={page} />\n+ <MyFooter />\n </>\n );\n }\n\n\nWhat's next\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nWith your app and Builder working together, the next step is the fun part–add some pages in Builder and drag in some elements. Play with styles and explore the UI.\n\nDeploy your updated app to a preview environment\n\nIntegrate Custom Components\n\nIntegrate Design Tokens\n"
},
{
"title": "Builder Develop",
"url": "https://www.builder.io/c/docs/develop",
"html": "Builder Develop\n\nGenerate code and map your components\n\nGenerate Code\n\nMap Figma Components\n\nIntegrate Design Tokens\n\n\nIntegrate Custom Components"
},
{
"title": "Builder.io docs",
"url": "https://www.builder.io/c/docs/intro",
"html": "Builder Knowledge Base\n⌘K\n\n\nGet Started With the Visual Editor\n\nLearn your way around Builder. Perfect for Designers, Marketers, Editors, and Admins\n\nGo to the Developer Docs\n\nIntegrate Builder with your code base and unlock your team's potential\n\nVisual Editor Tutorials\n\nFor tutorials and guides on creating Pages, Sections, and using data in Builder's Visual Editor, check out Start Building."
},
{
"title": "Publish Quickstart",
"url": "https://www.builder.io/c/docs/devtools",
"html": "Publish Quickstart\n\nYou can skip manual integration and let Builder's Devtools handle the details for you.\n\nBuilder Devtools automatically integrates your app with Builder and provides an intuitive UI for registering components and managing content.\n\nInstall Builder Devtools\nFramework\nReact\n\nMeta-Framework\nNext.js (Pages Router)\n\nSDK Generation\nGen 1\n\n\nIn the root of your project, run the following command to install Builder Devtools:\n\nnpm init builder.io@latest\n\nWhen prompted, respond Yes to integrating with Builder.io:\n\nAccess the Builder Devtools UI\n\nTip: If you're using React Webpack and Vite, you can skip this part as you've already covered it above. React Webpack and Vite require adding a route, so the UI is slightly different.\n\nWith the development server running, access the Builder Devtools UI:\n\nOpen your web browser and navigate to your project's local development URL; for example, http://localhost:3000/ or http://localhost:5173/. (The port might be different for you.) Builder's Devtools are displayed in the browser instead of your app's landing page.\nClick the Let's get started button.\nChoose a Space to authorize for integration and click Authorize.\nClick the Go to your app button.\nOn the bottom right, click on the Builder logo to get to your components, settings, and to add a Builder Page.\n\nIf you're using Windows, you might need to restart your dev server.\n\nThe video below shows authorizing and connecting to a Builder Space.\n\nRegister components\n\nThe Devtools drawer displays all of your components, both registered and unregistered. From here, you can:\n\nRegister components: toggle components on to register them with Builder.\nView and edit registered components: Interact with your registered components directly from the Devtools UI. You can rename, register, and edit inputs.\nVisualize content: Display content that's in Builder and click on an overlay to jump into any Builder element directly in the Visual Editor.\n\nTo register your components with Builder:\n\nOpen the Devtools drawer by clicking on the Builder logo on the bottom right.\nClick Components to display all of the components, registered or not, in your code base.\nSelect a component.\nToggle on to register the component. The code to register the component is added automatically to your code.\n\nThe next video shows this process by registering a Counter component:\n\nThe next video shows registering a component and editing its name in Devtools. At the end of the video, notice that the Devtools edit that changes the component's name from Footer to MyFooter, updates in the code editor.\n\nWhen registering components, Devtools can recognize most input types; however, more complex types require manual coding. If you want to add lists and objects, read about them in Input Types in Builder.\n\nShare your feedback\n\nDevtools is under active development, and we'd love to know what you think. Your feedback helps us meet the real-world needs of Builder's community and we couldn't do it without you!\n\nWhat's next\n\nWith your app and Builder working together, the next step is the fun part — add some pages in Builder and drag in some elements. Play with styles and explore the UI.\n\nDeploy your updated app to a preview environment\n\nIntegrate Custom Components\n\nIntegrate Design Tokens\n"
},
{
"title": "A/B Testing",
"url": "https://www.builder.io/c/docs/abtesting",
"html": "A/B Testing\n\nenterprise plans\n\nA/B testing is a data-driven approach to testing and measuring different content and experiences to help you make impactful improvements to your site or app. \n\nPrerequisites\n\nTo use A/B testing on a content entry, that content must be created and managed in Builder. Content created elsewhere cannot use Builder's A/B Testing feature.\n\nBuilder's A/B testing advantages\n\nThe advantages of doing A/B testing with Builder include:\n\nSeamless conversion tracking: Monitor conversions right within the intuitive UI alongside your Builder content.\nLimitless comparisons: Execute numerous comparisons, tailoring your tests to your specific needs.\nSEO friendly: Use search engine optimization efforts while conducting A/B tests.\nUninterrupted user experience: No DOM/UI blocking and unwanted content flashes.\nStraightforward operation: No coding required—you don't have to be a developer to engage in effective A/B testing.\nEfficient Compression: Leverage gzip compression for optimized performance, minimizing added weight even with multiple test groups.\n\nDespite multiple content pieces being initially sent with the HTML, gzip deflation efficiently eliminates redundancy, resulting in a mere 5-10% size increase. This ensures your page remains fast. Builder extends A/B testing support to all frameworks, including static ones such as Gatsby and Nuxt.\n\nCreating variations\n\nBegin A/B testing by crafting distinct variations of a page or piece of content so Builder can collect metrics for each version.\n\nDepending on whether a content entry has already been published, the Builder UI workflow might prompt you to make a duplicate content entry.\n\nIf the content entry that you'd like to test isn't published yet, you don't need to create a duplicate entry and you might notice just one entry in the content list when you're done.\n\nBoth workflows are correct and serve to maintain insight integrity.\n\nTo create an A/B test variation:\n\nIn the content entry, click the A/B Tests tab.\nClick the Add A/B Test Variation button.\nRename your new variation—initially labeled Variation 0 by default—and fine-tune the test ratio. For more variants to perform multi-variate testing, repeat this process.\nGo back to the Edit tab to toggle between variations and make adjustments.\nWhen you're ready, click the Publish button to initiate the test. If you'd rather schedule it for a future launch, visit Scheduling Content.\n\nThe video below goes through this process in a previously unpublished entry. If your content entry is already published, the Builder UI will guide you.\n\nImportant points to remember\n\nWhen A/B Testing, keep these things in mind:\n\nThe default variation, known as the control, serves as the baseline exposed to search engines, users with JavaScript disabled, and those with tracking deactivated.\nOnce a test is live and receiving traffic, refrain from introducing new variants or removing existing ones. This maintains the integrity of your test results and safeguards them from the influence of previous tests or outdated content versions.\nAllocation follows a random pattern based on the test ratio, tracked with cookies. However, users with tracking disabled remain unassigned to a test group.\n\nFor A/B testing with Symbols, visit Symbols.\n\nInterpreting A/B test metrics\n\nLeverage the data from your A/B test to determine the winning variation. Scrutinize conversion statistics across variations, focusing on metrics like conversion rate, total conversions, or conversion value, tailored to your priorities. Allow the test sufficient time to accumulate data and visitors for accurate conclusions.\n\nFor conversion metrics on custom tech stacks you'll need to integrate conversion tracking. Shopify-hosted stores benefit from automatic integration.\n\nTo evaluate the performance of your A/B test:\n\nIn the Visual Editor, go to the A/B Tests tab.\nClick View Results beneath the sliders. This directs you to the Insights tab, where you can access comprehensive test results. Initial stages may show limited visitor data, but with time, you'll gain substantial insights into your test's progress.\n\nThe following is a screenshot of the Insights tab that shows data such as Impressions, Clicks, and Clickthrough rate:\n\nBuilder calculates conversions based on impressions; in this way, an impression of Builder content is all that's necessary to lead to a trackable conversion.\n\nConcluding an A/B Test\n\nOnce you've determined the winning variation, it's time to implement the improvements. You have a couple of options that you manage from the A/B Tests tab.\n\nKeeping all variations but delivering the winner\n\nUse this option if you think you might want the test variations later.\n\nThis option retains all variations but delivers only the winning variation to new visitors.\n\nAdjust the ratios within the A/B Tests tab to exclusively display the winning variation to new visitors. This ensures that your audience immediately experiences the best UI, and you can keep the other variations for future use.\n\nNote that users who visited the site while the test was active and were assigned a losing variation's cookie will continue to get the losing variation until their cookie expires or is cleared.\n\nEnding an A/B Test while removing variations\n\nThis option conclusively ends the test.\n\nIf you don't duplicate this entry before picking a winner, the other variations are not copied. However, if you duplicate this entry first and then come back to choose the winner, the variations are ported to the duplicate.\n\nThe following table outlines what happens to variations depending on whether you choose the winner before or after duplicating:\n\nWhen you choose winner\tWhat happens to variations\n\nChoose Winner before duplicating\n\n\t\n\nTest ends. Test variations are not ported to duplicate entry. You'll have to create new variations if you need more A/B tests.\n\n\n\n\nChoose Winner after duplicating\n\n\t\n\nDuplicate is created before ending test. This means variations are copied to duplicate entry.\n\nTo end an A/B test completely:\n\nSelect the Choose Winning Variation option within the A/B Tests tab.\nIn the dialogue that opens, read the details so your choice is informed.\nClick the End Test button.\n\nAfter ending the test, Builder designates the winner with a checkmark icon. The following video demonstrates choosing the winner.\n\nStatistical significance\n\nAs your test accumulates data, Builder computes statistical significance. A checkmark next to a variant's name in the table indicates its impact on conversion, with a gray checkmark representing a p-value within a 90% confidence interval and a green checkmark exceeding 95%.\n\nNote that to use this feature, you must integrate conversion tracking.\n\nExamples of A/B tests\n\nThe following are some examples of features you can A/B test:\n\nGeneral Area\tSpecific area\tConcept\tExample\n\nContent\n\n\t\n\nHeaders\n\n\t\n\nVary headers to find out what visitors respond to most\n\n\t\n\n\"New Swimwear is Here!\" or \"Bathing Suits Galore\"\n\n\n\n\nContent\n\n\t\n\nCopy and designs\n\n\t\n\nTry different copy styles according to your ideal customer persona\n\n\t\n\n\"We're digging summer!\" or \"Luxuriate in Paradise\"\n\n\n\n\nDesign\n\n\t\n\nColors, design features, fonts\n\n\t\n\nExperiment with button size, shape, style to find out what encourages clicks\n\n\t\n\nRed button with all caps copy or a branded color using a minimal lowercase font\n\n\n\n\nDesign\n\n\t\n\nCTA position\n\n\t\n\nDifferent button locations in a content entry\n\n\t\n\nBottom right or bottom left placement.\n\n\n\n\nDesign\n\n\t\n\nHero image\n\n\t\n\nDifferent hero images to find out which gets more clicks\n\n\t\n\nA hero with a person leaping into a blue sea or a hero of just the sea, without the person\n\n\n\n\nFunctionality\n\n\t\n\nForm\n\n\t\n\nExperiment different form formats\n\n\t\n\nA form with multiple choice questions or free-form text boxes for written answers\n\n\n\n\nFunctionality\n\n\t\n\nResponsiveness\n\n\t\n\nHiding or showing a feature based on device-type to find out if users can use the feature as effectively\n\n\t\n\nPlacing search in the hamburger menu or placing it at the top of the page on mobile devices\n\nWhat's next\n\nIn addition to running A/B tests in Builder, you can also display content based on a schedule. For more information, visit Scheduling Content."
},
{
"title": "Publish with Builder",
"url": "https://www.builder.io/c/docs/developers",
"html": "Publish with Builder\n\nGet started with Builder's Visual Development Platform\n\nPublish Quickstart\n\nINTEGRATE WITH YOUR CODE\n\nIntegrate Page Building\n\nIntegrate Section Building\n\nIntegrate Structured Data\n\nWhich should I use?\n\nDIVE DEEPER\n\nGenerating Code with Visual Copilot\n\nLearn About Content Models\n\nIntegrate Design Tokens\n\n\nIntegrate Custom Components\n\nPOPULAR DEVELOPER DOCS\n\nHow Builder Works\n\nAPI Documentation\n\nExtend Builder with Plugins\n\nIntegrate Symbols"
}
]
结论:
符合预期
参考
GitHub 重磅开源!GPT-Crawler:一键爬取网站知识库,打造专属AI大脑!