@lowdefy/docs-content 0.0.0-experimental-20260710073520

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +20 -0
  3. package/content/actions/callapi.md +66 -0
  4. package/content/actions/callmethod.md +41 -0
  5. package/content/actions/copytoclipboard.md +32 -0
  6. package/content/actions/displaymessage.md +53 -0
  7. package/content/actions/downloadcsv.md +89 -0
  8. package/content/actions/fetch.md +50 -0
  9. package/content/actions/geolocationcurrentposition.md +56 -0
  10. package/content/actions/link.md +104 -0
  11. package/content/actions/login.md +85 -0
  12. package/content/actions/logout.md +56 -0
  13. package/content/actions/pdfmake.md +304 -0
  14. package/content/actions/request.md +67 -0
  15. package/content/actions/reset.md +27 -0
  16. package/content/actions/resetvalidation.md +85 -0
  17. package/content/actions/scrollto.md +85 -0
  18. package/content/actions/setdarkmode.md +62 -0
  19. package/content/actions/setfocus.md +33 -0
  20. package/content/actions/setglobal.md +63 -0
  21. package/content/actions/setlocale.md +69 -0
  22. package/content/actions/setstate.md +70 -0
  23. package/content/actions/throw.md +72 -0
  24. package/content/actions/validate.md +87 -0
  25. package/content/actions/wait.md +24 -0
  26. package/content/agents/agent-endpoint-tools.md +190 -0
  27. package/content/agents/agent-mcp-tools.md +124 -0
  28. package/content/agents/agent-multi-agent.md +136 -0
  29. package/content/agents/agent-properties.md +174 -0
  30. package/content/agents/agent-server-hooks.md +336 -0
  31. package/content/agents/agentchat.md +515 -0
  32. package/content/agents/agentconversations.md +148 -0
  33. package/content/concepts/ai-agent-docs.md +190 -0
  34. package/content/concepts/cli.md +213 -0
  35. package/content/concepts/connections-and-requests.md +7 -0
  36. package/content/concepts/custom-html.md +3 -0
  37. package/content/concepts/custom-styling.md +161 -0
  38. package/content/concepts/events-and-actions.md +271 -0
  39. package/content/concepts/hosting-files.md +18 -0
  40. package/content/concepts/i18n.md +320 -0
  41. package/content/concepts/keyboard-shortcuts.md +218 -0
  42. package/content/concepts/layout-overview.md +478 -0
  43. package/content/concepts/lists.md +144 -0
  44. package/content/concepts/logger.md +43 -0
  45. package/content/concepts/lowdefy-schema.md +365 -0
  46. package/content/concepts/menus.md +144 -0
  47. package/content/concepts/module-authoring.md +564 -0
  48. package/content/concepts/modules.md +338 -0
  49. package/content/concepts/operators.md +45 -0
  50. package/content/concepts/overview.md +19 -0
  51. package/content/concepts/references-and-templates.md +207 -0
  52. package/content/concepts/secrets.md +24 -0
  53. package/content/concepts/selectors.md +143 -0
  54. package/content/connections/amazonredshift.md +176 -0
  55. package/content/connections/anthropic.md +232 -0
  56. package/content/connections/awss3.md +313 -0
  57. package/content/connections/azureblobstorage.md +133 -0
  58. package/content/connections/elasticsearch.md +371 -0
  59. package/content/connections/google.md +228 -0
  60. package/content/connections/googlecloudstorage.md +139 -0
  61. package/content/connections/googlesheet.md +313 -0
  62. package/content/connections/knex.md +206 -0
  63. package/content/connections/mariadb.md +177 -0
  64. package/content/connections/mcp.md +134 -0
  65. package/content/connections/mongodb.md +739 -0
  66. package/content/connections/mssql.md +191 -0
  67. package/content/connections/mysql.md +192 -0
  68. package/content/connections/openai-connection.md +228 -0
  69. package/content/connections/postgresql.md +200 -0
  70. package/content/connections/redis.md +116 -0
  71. package/content/connections/sendgridmail.md +94 -0
  72. package/content/connections/smtp.md +149 -0
  73. package/content/connections/sqlite.md +187 -0
  74. package/content/connections/stripe.md +115 -0
  75. package/content/container-blocks/affix.md +413 -0
  76. package/content/container-blocks/alert.md +937 -0
  77. package/content/container-blocks/badge.md +1222 -0
  78. package/content/container-blocks/box.md +1453 -0
  79. package/content/container-blocks/card.md +1200 -0
  80. package/content/container-blocks/carousel.md +2247 -0
  81. package/content/container-blocks/collapse.md +1335 -0
  82. package/content/container-blocks/configprovider.md +1070 -0
  83. package/content/container-blocks/confirmmodal.md +1159 -0
  84. package/content/container-blocks/content.md +597 -0
  85. package/content/container-blocks/descriptions.md +870 -0
  86. package/content/container-blocks/drawer.md +1379 -0
  87. package/content/container-blocks/dropdownmenu.md +643 -0
  88. package/content/container-blocks/flex.md +1510 -0
  89. package/content/container-blocks/footer.md +380 -0
  90. package/content/container-blocks/googlemaps.md +546 -0
  91. package/content/container-blocks/googlemapsheatmap.md +607 -0
  92. package/content/container-blocks/googlemapsscript.md +61 -0
  93. package/content/container-blocks/header.md +302 -0
  94. package/content/container-blocks/label.md +739 -0
  95. package/content/container-blocks/layout.md +604 -0
  96. package/content/container-blocks/masonry.md +1090 -0
  97. package/content/container-blocks/mobilemenu.md +1244 -0
  98. package/content/container-blocks/modal.md +1180 -0
  99. package/content/container-blocks/pageheadermenu.md +614 -0
  100. package/content/container-blocks/pagesidebarlayout.md +438 -0
  101. package/content/container-blocks/pagesidermenu.md +651 -0
  102. package/content/container-blocks/popover.md +1421 -0
  103. package/content/container-blocks/result.md +972 -0
  104. package/content/container-blocks/sider.md +1064 -0
  105. package/content/container-blocks/span.md +747 -0
  106. package/content/container-blocks/spinner.md +267 -0
  107. package/content/container-blocks/splitter.md +1735 -0
  108. package/content/container-blocks/tabs.md +1718 -0
  109. package/content/container-blocks/tooltip.md +1274 -0
  110. package/content/container-blocks/watermark.md +515 -0
  111. package/content/controls/for.md +103 -0
  112. package/content/controls/if.md +107 -0
  113. package/content/controls/log.md +50 -0
  114. package/content/controls/parallel.md +71 -0
  115. package/content/controls/parallel_for.md +36 -0
  116. package/content/controls/reject.md +56 -0
  117. package/content/controls/return.md +66 -0
  118. package/content/controls/set_state.md +98 -0
  119. package/content/controls/switch.md +90 -0
  120. package/content/controls/throw.md +79 -0
  121. package/content/controls/try.md +88 -0
  122. package/content/deployment/docker.md +149 -0
  123. package/content/deployment/node-server.md +27 -0
  124. package/content/deployment/vercel.md +101 -0
  125. package/content/display-blocks/aggrid.md +1459 -0
  126. package/content/display-blocks/anchor.md +336 -0
  127. package/content/display-blocks/avatar.md +1154 -0
  128. package/content/display-blocks/breadcrumb.md +517 -0
  129. package/content/display-blocks/button.md +758 -0
  130. package/content/display-blocks/calendar.md +156 -0
  131. package/content/display-blocks/dangeroushtml.md +314 -0
  132. package/content/display-blocks/dangerousmarkdown.md +423 -0
  133. package/content/display-blocks/diffgit.md +44 -0
  134. package/content/display-blocks/difflist.md +225 -0
  135. package/content/display-blocks/diffsidebyside.md +56 -0
  136. package/content/display-blocks/difftimeline.md +94 -0
  137. package/content/display-blocks/divider.md +406 -0
  138. package/content/display-blocks/download.md +60 -0
  139. package/content/display-blocks/dropdownbutton.md +661 -0
  140. package/content/display-blocks/echart.md +418 -0
  141. package/content/display-blocks/floatbutton.md +545 -0
  142. package/content/display-blocks/html.md +311 -0
  143. package/content/display-blocks/icon.md +717 -0
  144. package/content/display-blocks/img.md +479 -0
  145. package/content/display-blocks/markdown.md +520 -0
  146. package/content/display-blocks/markdownwithcode.md +730 -0
  147. package/content/display-blocks/menu.md +1123 -0
  148. package/content/display-blocks/message.md +941 -0
  149. package/content/display-blocks/notification.md +1410 -0
  150. package/content/display-blocks/paragraph.md +643 -0
  151. package/content/display-blocks/progress.md +818 -0
  152. package/content/display-blocks/qrcode.md +519 -0
  153. package/content/display-blocks/s3download.md +240 -0
  154. package/content/display-blocks/search.md +360 -0
  155. package/content/display-blocks/skeleton.md +272 -0
  156. package/content/display-blocks/skeletonavatar.md +222 -0
  157. package/content/display-blocks/skeletonbutton.md +245 -0
  158. package/content/display-blocks/skeletoninput.md +223 -0
  159. package/content/display-blocks/skeletonparagraph.md +201 -0
  160. package/content/display-blocks/statistic.md +485 -0
  161. package/content/display-blocks/steps.md +585 -0
  162. package/content/display-blocks/tag.md +620 -0
  163. package/content/display-blocks/title.md +654 -0
  164. package/content/display-blocks/tour.md +2359 -0
  165. package/content/input-blocks/autocomplete.md +786 -0
  166. package/content/input-blocks/buttonselector.md +964 -0
  167. package/content/input-blocks/checkboxselector.md +765 -0
  168. package/content/input-blocks/checkboxswitch.md +497 -0
  169. package/content/input-blocks/colorselector.md +884 -0
  170. package/content/input-blocks/daterangeselector.md +777 -0
  171. package/content/input-blocks/dateselector.md +693 -0
  172. package/content/input-blocks/datetimeselector.md +791 -0
  173. package/content/input-blocks/inputgallery.md +528 -0
  174. package/content/input-blocks/monthselector.md +717 -0
  175. package/content/input-blocks/multipleselector.md +1337 -0
  176. package/content/input-blocks/numberinput.md +855 -0
  177. package/content/input-blocks/pagination.md +679 -0
  178. package/content/input-blocks/paragraphinput.md +1664 -0
  179. package/content/input-blocks/passwordinput.md +480 -0
  180. package/content/input-blocks/phonenumberinput.md +688 -0
  181. package/content/input-blocks/radioselector.md +820 -0
  182. package/content/input-blocks/ratingslider.md +684 -0
  183. package/content/input-blocks/s3uploadbutton.md +384 -0
  184. package/content/input-blocks/s3uploaddragger.md +305 -0
  185. package/content/input-blocks/s3uploadphoto.md +288 -0
  186. package/content/input-blocks/segmentedselector.md +782 -0
  187. package/content/input-blocks/selector.md +1162 -0
  188. package/content/input-blocks/switch.md +552 -0
  189. package/content/input-blocks/textarea.md +714 -0
  190. package/content/input-blocks/textinput.md +639 -0
  191. package/content/input-blocks/tiptapinput.md +226 -0
  192. package/content/input-blocks/tiptapmentioninput.md +471 -0
  193. package/content/input-blocks/titleinput.md +1094 -0
  194. package/content/input-blocks/treeinput.md +144 -0
  195. package/content/input-blocks/treemultipleselector.md +162 -0
  196. package/content/input-blocks/treeselector.md +185 -0
  197. package/content/input-blocks/upload.md +149 -0
  198. package/content/input-blocks/uploaddragger.md +85 -0
  199. package/content/input-blocks/uploadphoto.md +84 -0
  200. package/content/input-blocks/weekselector.md +630 -0
  201. package/content/list-blocks/controlledlist.md +498 -0
  202. package/content/list-blocks/list.md +529 -0
  203. package/content/list-blocks/listselector.md +301 -0
  204. package/content/list-blocks/masonrylist.md +230 -0
  205. package/content/migration/upgrade-guide.md +106 -0
  206. package/content/migration/v4-to-v5.md +589 -0
  207. package/content/migration/v5-to-v6.md +36 -0
  208. package/content/operators/_actions.md +58 -0
  209. package/content/operators/_and.md +76 -0
  210. package/content/operators/_api.md +254 -0
  211. package/content/operators/_app.md +114 -0
  212. package/content/operators/_args.md +65 -0
  213. package/content/operators/_array.md +331 -0
  214. package/content/operators/_base64.md +49 -0
  215. package/content/operators/_boolean.md +33 -0
  216. package/content/operators/_build.md +166 -0
  217. package/content/operators/_change_case.md +357 -0
  218. package/content/operators/_date.md +415 -0
  219. package/content/operators/_dayjs.md +128 -0
  220. package/content/operators/_diff.md +61 -0
  221. package/content/operators/_divide.md +32 -0
  222. package/content/operators/_eq.md +52 -0
  223. package/content/operators/_event.md +86 -0
  224. package/content/operators/_function.md +52 -0
  225. package/content/operators/_get.md +92 -0
  226. package/content/operators/_global.md +86 -0
  227. package/content/operators/_gt.md +50 -0
  228. package/content/operators/_gte.md +50 -0
  229. package/content/operators/_hash.md +112 -0
  230. package/content/operators/_if.md +30 -0
  231. package/content/operators/_if_none.md +47 -0
  232. package/content/operators/_index.md +48 -0
  233. package/content/operators/_input.md +86 -0
  234. package/content/operators/_intl.md +135 -0
  235. package/content/operators/_item.md +166 -0
  236. package/content/operators/_js.md +113 -0
  237. package/content/operators/_json.md +120 -0
  238. package/content/operators/_jsonata.md +152 -0
  239. package/content/operators/_locale.md +65 -0
  240. package/content/operators/_location.md +40 -0
  241. package/content/operators/_log.md +22 -0
  242. package/content/operators/_lt.md +50 -0
  243. package/content/operators/_lte.md +50 -0
  244. package/content/operators/_math.md +407 -0
  245. package/content/operators/_media.md +83 -0
  246. package/content/operators/_menu.md +62 -0
  247. package/content/operators/_module.md +340 -0
  248. package/content/operators/_mql.md +95 -0
  249. package/content/operators/_ne.md +62 -0
  250. package/content/operators/_not.md +33 -0
  251. package/content/operators/_number.md +159 -0
  252. package/content/operators/_nunjucks.md +117 -0
  253. package/content/operators/_object.md +253 -0
  254. package/content/operators/_operator.md +33 -0
  255. package/content/operators/_or.md +67 -0
  256. package/content/operators/_product.md +45 -0
  257. package/content/operators/_random.md +90 -0
  258. package/content/operators/_ref.md +80 -0
  259. package/content/operators/_regex.md +69 -0
  260. package/content/operators/_request.md +35 -0
  261. package/content/operators/_request_details.md +29 -0
  262. package/content/operators/_secret.md +56 -0
  263. package/content/operators/_state.md +134 -0
  264. package/content/operators/_step.md +98 -0
  265. package/content/operators/_string.md +327 -0
  266. package/content/operators/_subtract.md +24 -0
  267. package/content/operators/_sum.md +45 -0
  268. package/content/operators/_switch.md +37 -0
  269. package/content/operators/_t.md +96 -0
  270. package/content/operators/_theme.md +65 -0
  271. package/content/operators/_type.md +78 -0
  272. package/content/operators/_uri.md +49 -0
  273. package/content/operators/_url_query.md +92 -0
  274. package/content/operators/_user.md +154 -0
  275. package/content/operators/_uuid.md +118 -0
  276. package/content/operators/_var.md +88 -0
  277. package/content/operators/_yaml.md +96 -0
  278. package/content/other/introduction.md +39 -0
  279. package/content/other/next-auth-providers.md +3 -0
  280. package/content/other/updatesession.md +26 -0
  281. package/content/plugins/plugins-actions.md +80 -0
  282. package/content/plugins/plugins-connections.md +98 -0
  283. package/content/plugins/plugins-dev.md +138 -0
  284. package/content/plugins/plugins-introduction.md +29 -0
  285. package/content/plugins/plugins-operators.md +71 -0
  286. package/content/testing/e2e-auth.md +108 -0
  287. package/content/testing/e2e-configuration.md +107 -0
  288. package/content/testing/e2e-getting-started.md +96 -0
  289. package/content/testing/e2e-introduction.md +53 -0
  290. package/content/testing/e2e-mocking.md +155 -0
  291. package/content/testing/e2e-writing-tests.md +214 -0
  292. package/content/tutorial/tutorial-actions-operators.md +222 -0
  293. package/content/tutorial/tutorial-add-blocks.md +86 -0
  294. package/content/tutorial/tutorial-create-page.md +57 -0
  295. package/content/tutorial/tutorial-display-data-page.md +181 -0
  296. package/content/tutorial/tutorial-next-steps.md +53 -0
  297. package/content/tutorial/tutorial-requests-sql.md +22 -0
  298. package/content/tutorial/tutorial-start.md +71 -0
  299. package/content/user-authentication/auth-providers.md +15 -0
  300. package/content/user-authentication/login-and-logout.md +122 -0
  301. package/content/user-authentication/users-introduction.md +31 -0
  302. package/index.json +2281 -0
  303. package/package.json +34 -0
  304. package/scripts/extractAgentDocs.js +130 -0
@@ -0,0 +1,144 @@
1
+ # Lists
2
+
3
+ List category blocks render multiple [`content areas`](/layout), based on data in the [`state`](/page-and-app-state) object.
4
+
5
+ Since the content area might contain input blocks, the block has an array value in state, with it's `block id` as key. For each item in the array, an content area (or set of content areas is rendered). Multiple list blocks can be nested.
6
+
7
+ ### List indices and block ids
8
+
9
+ If a block is to be rendered in an list's content area, the block id should contain a list index placeholder (specified with the `$` symbol) for each list it is a part of. These placeholders will be populated with the blocks `list indices`. The `list indices` are a array of integers, indicating at which position in the list the block is, for each level of list blocks (zero indexed). The block id should be in valid dot-notation once the placeholders have been substituted.
10
+
11
+ This can be made more clear with a example. Suppose we have a list block with id `contacts`. Inside this list we have a text input block for the contact name. We would like our state to look like:
12
+ ```yaml
13
+ contacts:
14
+ - name: Name 1
15
+ - name: Name 2
16
+ ```
17
+
18
+ The id for the text input block should be `contacts.$.name`. Each text input block will be given an indexed id based on it's position in the contacts list (`contacts.0.name`, `contacts.1.name`, etc.).
19
+
20
+ Suppose we also want to add a emails array for each contact. To do this, we can add another list block in the `contacts` array, and add a text input inside the emails array. If we want the emails to be a array of strings, i.e. our `state` should look like:
21
+
22
+ ```yaml
23
+ contacts:
24
+ - name: Name 1
25
+ emails:
26
+ - email1@example.com
27
+ - email2@example.com
28
+ - name: Name 2
29
+ emails: []
30
+ ```
31
+
32
+ our config should look like:
33
+ ```yaml
34
+ id: contacts
35
+ type: ControlledList
36
+ properties:
37
+ # ...
38
+ blocks:
39
+ - id: contacts.$.name
40
+ type: TextInput
41
+ properties:
42
+ # ...
43
+ - id: contacts.$.emails
44
+ type: ControlledList
45
+ properties:
46
+ # ...
47
+ blocks:
48
+ - id: contacts.$.emails.$
49
+ type: TextInput
50
+ properties:
51
+ # ...
52
+ ```
53
+
54
+ Note that the id of the emails list block is `contacts.$.emails` and that it has one `$` placeholder since it is inside the `contacts` list, and the id of the email text input is `contacts.$.emails.$`, which has two `$` placeholders since it is in both the `contacts` and `contacts.$.emails` lists.
55
+
56
+ The ids of the `contacts.$.emails.$` text input blocks will look like `contacts.0.emails.3` or `contacts.2.emails.1`, and this will result in the `state` where the emails on a contact are an array of strings.
57
+
58
+ ### List indices in operators
59
+
60
+ List indices are also supported in "getter" operators like `_state`. If the operator is given a key that contains `$` placeholders, and the operator is called from a block with list indices, the placeholders will be populated with the blocks list indices. These indices are populated on `actions` called by the block, and are even populated in `connections` and `requests` if the block that triggered the `Request` action has list indices. This can be used to get values from the `state` array the block is a part of, or even values from another array at the same index.
61
+
62
+ ### List block methods
63
+
64
+ List blocks can provide methods to change their values. These are
65
+
66
+ #### `pushItem`
67
+ Add an item at the end of the list.
68
+
69
+ #### `unshiftItem`
70
+ Add an item at the start of the list.
71
+
72
+ #### `removeItem`
73
+ Remove an item at the specified index.
74
+
75
+ #### `moveItemDown`
76
+ Move the item at the specified index one position to the start of the list. If the item is at the start if the list, the item remains at position `0`.
77
+
78
+ #### `moveItemUp`
79
+ Move the item at the specified index one position to the end of the list. If the item is at the end if the list, the item remains at it's position.
80
+
81
+ #### Example
82
+ ```yaml
83
+ id: page
84
+ type: PageHeaderMenu
85
+ blocks:
86
+ - id: add_item_at_start
87
+ type: Button
88
+ events:
89
+ onClick:
90
+ - id: add_item_at_start
91
+ type: CallMethod
92
+ params:
93
+ blockId: list
94
+ method: unshiftItem
95
+ - id: add_item_at_end
96
+ type: Button
97
+ events:
98
+ onClick:
99
+ - id: add_item_at_end
100
+ type: CallMethod
101
+ params:
102
+ blockId: list
103
+ method: pushItem
104
+ - id: list
105
+ type: List
106
+ blocks:
107
+ - id: list.$.move_item_down
108
+ type: Button
109
+ events:
110
+ onClick:
111
+ - id: move_item_down
112
+ type: CallMethod
113
+ params:
114
+ blockId: list
115
+ method: moveItemDown
116
+ args:
117
+ - _index: 0 # Get the first index in the indices array
118
+ - id: list.$.move_item_up
119
+ type: Button
120
+ events:
121
+ onClick:
122
+ - id: move_item_up
123
+ type: CallMethod
124
+ params:
125
+ blockId: list
126
+ method: moveItemUp
127
+ args:
128
+ - _index: 0
129
+ - id: list.$.remove_item
130
+ type: Button
131
+ events:
132
+ onClick:
133
+ - id: remove_item
134
+ type: CallMethod
135
+ params:
136
+ blockId: list
137
+ method: removeItem
138
+ args:
139
+ - _index: 0
140
+ ```
141
+
142
+ ### Lists and state
143
+
144
+ List blocks create a content area for each item in `state`. If `state` is updated, the list block will also update, creating or destroying content areas as necessary. Thus list blocks can also be manipulated by setting `state` directly using the [`SetState`](/SetState) operator.
@@ -0,0 +1,43 @@
1
+ # Logger
2
+
3
+ ### Source Maps
4
+
5
+ To enable readable stack traces in Sentry, set the `SENTRY_AUTH_TOKEN` environment variable during build:
6
+
7
+ ```
8
+ SENTRY_AUTH_TOKEN=your-auth-token
9
+ ```
10
+
11
+ This will upload source maps to Sentry during the client build.
12
+
13
+ ### Environment Variables
14
+
15
+ | Variable | Description |
16
+ |----------|-------------|
17
+ | `SENTRY_DSN` | Sentry Data Source Name (DSN) for server-side error capture |
18
+ | `SENTRY_AUTH_TOKEN` | (Optional) Auth token for source map uploads during build |
19
+
20
+ Example `.env` file:
21
+
22
+ ```
23
+ # .env
24
+ SENTRY_DSN=https://abc123@o123456.ingest.sentry.io/1234567
25
+ SENTRY_AUTH_TOKEN=your-auth-token
26
+ ```
27
+
28
+ ### Disabling Sentry
29
+
30
+ To disable Sentry for specific environments:
31
+
32
+ - **Disable client only:** Set `logger.sentry.client: false`
33
+ - **Disable server only:** Set `logger.sentry.server: false`
34
+ - **Disable completely:** Remove the `SENTRY_DSN` environment variable
35
+
36
+ ### Error Context
37
+
38
+ When errors are captured, Lowdefy automatically includes:
39
+
40
+ - **Page ID:** The current page where the error occurred
41
+ - **Block ID:** The block that triggered the error (if applicable)
42
+ - **Config Location:** The source file and line number in your YAML config
43
+ - **User Context:** Configured user fields for authenticated sessions
@@ -0,0 +1,365 @@
1
+ # Lowdefy App Schema
2
+
3
+ A Lowdefy app is written as YAML or JSON files, which are combined together using the [`_ref`](/_ref) operator when the app is built into a configuration object that describes the app. This object has different sections that describe different parts of the Lowdefy app.
4
+
5
+ > A good understanding of YAML is needed before starting with Lowdefy. If you don't have any experience using YAML, you can find a good introduction video <a href = "https://www.youtube.com/watch?v=cdLNKUoMc6c">here</a>.
6
+
7
+ The root schema for a Lowdefy app is:
8
+ - `lowdefy: string`: __Required__ - The Lowdefy version number that the app uses. This is required and cannot be a reference to another file.
9
+ - `name: string`: A name for the application.
10
+ - `version: string`: The version number of the app that you are building. This is optional and allows you indicate the version of your app.
11
+ - `slug: string`: A kebab-case identifier for the app, available via the [`_app`](/_app) operator. Must match the pattern `^[a-z][a-z0-9]*(-[a-z0-9]+)*$` (lowercase letters and digits, hyphen-separated, must start with a letter).
12
+ - `description: string`: A free-form description of the app.
13
+ - `license: string`: A [SPDX license ID](https://spdx.org/licenses/). You can use this to indicate the project's license if you are licensing your project under a specific software license. If you wish to indicate to others that you do not grant the right to use your project, you can use `UNLICENSED` for this field. How you share your Lowdefy config is up to you.
14
+ - `cli: object`: An object with configuration for the CLI.
15
+ - `config: object`: An object with app configuration like the home page pageId.
16
+ - `auth: object` An object with authentication and authorization configuration.
17
+ - `global: object`: A data object that can be accessed anywhere in the app using the [`_global`](/_global) operator.
18
+ - `connections: object[]`: An array of [`connection`](/connections-and-requests) objects.
19
+ - `plugins: object[]`: An array of `plugin` objects to customize and add block types.
20
+ - `modules: object[]`: An array of module entries. Each module references a reusable configuration package distributed via GitHub or local file paths. See [Modules](/modules) for details.
21
+ - `menus: object[]`: An array of menu objects.
22
+ - `pages: object[]`: An array of page objects.
23
+
24
+ All of the above fields (along with the framework version and the build git SHA) are also available at runtime via the [`_app`](/_app) operator.
25
+
26
+ Pages are made up of blocks. Blocks have the following basic schema:
27
+ - `id: string`: An identifier for a block.
28
+ - `type: string`: __Required__ - This is the block type identifier and defines which block will render.
29
+ - `properties: object`: The settings passed to a block component.
30
+ - `layout`: Control how the block will be rendered in the page flow, or in other words, how the block is placed in relation to other blocks. See [layout](/layout-overview) for more details.
31
+ - `blocks: array`: An array of blocks to render within this block.
32
+
33
+ Find the more detailed block schema [here](/blocks).
34
+
35
+ > <h3> YAML file extensions </h3>
36
+ <p> Both files with the <code>.yaml</code> and <code>.yml</code> file extensions are supported as YAML files. </p>
37
+ <h3> JSON instead of YAML </h3>
38
+ <p> Since you can reference JSON files, you can build your app using JSON instead of YAML files. The <code>lowdefy.yaml</code> file needs to be a YAML file, but all other configuration can be in referenced JSON files. It also makes sense to use JSON instead of YAML if you are generating configuration using code. </p>
39
+
40
+ ## Config
41
+
42
+ The config object has the following properties:
43
+
44
+ - `basePath: string`: Set the base path to serve the Lowdefy application from. This will route all pages under `https://example.com/<base-path>/<page-id>` instead of the default `https://example.com/<page-id>`. The basePath value must start with "/".
45
+ - `homePageId: string`: The id of the page that will load when a visitor navigates to the home route, in other words, when the visitor navigates to `yourdomain.com` or `yourdomain.com/`.
46
+ - `requestTimeout: number`: Maximum time in milliseconds a request may run before the server returns a timeout. This protects against requests that hang on an upstream call (database, SMTP, an external API) running all the way to the host's function limit — important on serverless platforms that bill by execution duration. Defaults to `30000` (30 seconds). Set to `0` to disable. Agent streaming routes are exempt, since they are long-lived by design.
47
+
48
+ ## Auth
49
+
50
+ The auth object is used to configure user authentication, and has the following properties:
51
+
52
+ - `adapter: object`: Configure a database adapter.
53
+ - `api: object`: Configure which APIs should be protected.
54
+ - `authPages: object`: Configure pages like the sign in page used by authentication flows.
55
+ - `callbacks: object[]`: Configure callback functions.
56
+ - `debug: boolean`: Can be set to false to disable auth debugging if the log level is set to debug.
57
+ - `events: object[]`: Configure event functions.
58
+ - `pages: object`: Configure which pages should be protected.
59
+ - `providers: object[]`: Configure authentication providers.
60
+ - `session: object`: Configure session.
61
+ - `theme: object`: Configure theme for default authentication pages.
62
+ - `userFields: object`: Map data from the provider to the user object.
63
+ - `advanced: object`: Set advanced authentication options.
64
+
65
+ See more about how user authentication and authorization [here](/users-introduction).
66
+
67
+ ## Global
68
+
69
+ In a Lowdefy app, you can define global variables in the __global__ object, which can be accessed using the [`_global`](/_global) operator, and modified using the [`SetGlobal`](/SetGlobal) action. This is a good place to store data or configuration that is used over various pages throughout the app, for example, user preferences that can be modified using `SetGlobal` on one page and easily referenced on all others.
70
+
71
+ ## Connections
72
+
73
+ In a Lowdefy app you can integrate with other services like API's or databases using `connections` and `requests`. Use connections to configure the settings to a service, for example, settings such as urls or [`secrets`](/secrets) like passwords or API keys. Requests use connections to interact with external services, for example, inserting a data record or executing a query on a database, or simply calling an API end-point.
74
+
75
+ See more about how `connections` and `requests` are used together [here](/connections-and-requests).
76
+
77
+ ## Plugins
78
+
79
+ The plugins section is used to configure which plugin packages should be used in the app. It contains an array of plugin definitions, which have the following properties:
80
+
81
+ - `name: string`: The name of the package. If published to npm, this is the name under which the package is published on npm.
82
+ - `version: string`: An npm or pnpm version specifier of the package to use.
83
+ - `typePrefix: string`: A prefix to append to all types exported by the package to prevent type name clashes.
84
+
85
+ ## Menus
86
+
87
+ Menu objects describe links to pages, within the app or external. Menu lists are filtered to only show pages that the user is authorized to see as a result of public, private or [role based access controlled (RBAC)](/roles) pages. Blocks such as [PageSiderMenu](/PageSiderMenu) render menu links. If no menu defined, a default menu is created, containing links to all pages defined in the app.
88
+
89
+ See more about how menu objects are used and defined [here](/menus).
90
+
91
+ ## APIs
92
+
93
+ API objects define server-side endpoints that execute routines i.e. sequences of steps and control structures that run on the server with access to connections, secrets, and server-side operators.
94
+
95
+ Each API should have an `id` that is unique among all APIs in the app. Each API is called from the client using the [`CallAPI`](/CallAPI) action with the `endpointId` parameter matching the API's id.
96
+
97
+ APIs must have a `routine` that defines the execution logic. The routine executes sequentially by default and returns a response to the client through [`:return`](/:return) or [`:reject`](/:reject) control statements.
98
+
99
+ By default, APIs are public and can be accessed without authentication, just like pages. To require authentication or restrict access to specific roles, APIs must be configured in the `auth` section of your `lowdefy.yaml` file.
100
+
101
+ See the [APIs documentation](/lowdefy-api) for more information on how to use and define them.
102
+
103
+ ## Pages
104
+
105
+ Pages in a Lowdefy app are actually just blocks, the building blocks of a Lowdefy app, with a few extra restrictions and features.
106
+
107
+ Each page should have an `id` that is unique among all pages in the app. Each page is served with the `pageId` as the url route. That is, if a page is created with id `page1`, it will be served at `domain.com/page1`. Module pages use the path `/{entryId}/{pageId}` — for example, a page `users-list` in a module entry `team-users` is served at `domain.com/team-users/users-list`.
108
+
109
+ If `properties.title` is set on a page block, the title will be set as the page title (This is the title displayed on the tabs in your browser).
110
+
111
+ Let's have a look at how to define a page and it's blocks. We can start with a simple page a card block on it. We can add a title to our card, by making use of the card block's title property. We can also add a paragraph block to our card so that it won't be so empty.
112
+
113
+ ###### lowdefy.yaml
114
+ ```yaml
115
+ lowdefy: LOWDEFY_VERSION
116
+
117
+ pages:
118
+ - id: page1
119
+ type: PageHeaderMenu
120
+ properties:
121
+ title: Page 1
122
+ blocks:
123
+ - id: content_card
124
+ type: Card
125
+ properties:
126
+ title: Title
127
+ blocks:
128
+ - id: paragraph
129
+ type: Paragraph
130
+ properties:
131
+ content: This is a paragraph on Page 1.
132
+ ```
133
+
134
+ Let's add another card to our page and give it some blocks which will allow us to get input from the user.
135
+
136
+ ###### lowdefy.yaml
137
+ ```yaml
138
+ lowdefy: LOWDEFY_VERSION
139
+
140
+ pages:
141
+ - id: page1
142
+ type: PageHeaderMenu
143
+ properties:
144
+ title: Page 1
145
+ blocks:
146
+ - id: content_card
147
+ type: Card
148
+ properties:
149
+ title: Title
150
+ blocks:
151
+ - id: paragraph
152
+ type: Paragraph
153
+ properties:
154
+ content: This is a paragraph on Page 1.
155
+ - id: input_card
156
+ type: Card
157
+ blocks:
158
+ - id: text_input
159
+ type: TextInput
160
+ properties:
161
+ label:
162
+ title: Please Enter Your Name
163
+ - id: radio_selector
164
+ type: RadioSelector
165
+ properties:
166
+ label:
167
+ title: How Are You Feeling?
168
+ colon: false
169
+ options:
170
+ - label: Meh
171
+ value: 1
172
+ disabled: false
173
+ - label: Okay
174
+ value: 2
175
+ disabled: false
176
+ - label: Good
177
+ value: 3
178
+ disabled: false
179
+ - label: Great
180
+ value: 4
181
+ disabled: false
182
+ - label: Amazing Now That I'm Using Lowdefy
183
+ value: 5
184
+ disabled: false
185
+ ```
186
+
187
+ In order to build our page further, we will need to add more blocks. Let's leave this page as is and add another page, with it's own card block containing a title block and a paragraph block.
188
+
189
+ ###### lowdefy.yaml
190
+ ```yaml
191
+ lowdefy: LOWDEFY_VERSION
192
+
193
+ pages:
194
+ - id: page1
195
+ type: PageHeaderMenu
196
+ properties:
197
+ title: Page 1
198
+ blocks:
199
+ - id: content_card
200
+ type: Card
201
+ properties:
202
+ title: Title
203
+ blocks:
204
+ - id: paragraph
205
+ type: Paragraph
206
+ properties:
207
+ content: This is a paragraph on Page 1.
208
+ - id: input_card
209
+ type: Card
210
+ blocks:
211
+ - id: text_input
212
+ type: TextInput
213
+ properties:
214
+ label:
215
+ title: Please Enter Your Name
216
+ - id: radio_selector
217
+ type: RadioSelector
218
+ properties:
219
+ label:
220
+ title: How Are You Feeling?
221
+ colon: false
222
+ options:
223
+ - label: Meh
224
+ value: 1
225
+ disabled: false
226
+ - label: Okay
227
+ value: 2
228
+ disabled: false
229
+ - label: Good
230
+ value: 3
231
+ disabled: false
232
+ - label: Great
233
+ value: 4
234
+ disabled: false
235
+ - label: Amazing Now That I'm Using Lowdefy
236
+ value: 5
237
+ disabled: false
238
+ - id: page2
239
+ type: PageHeaderMenu
240
+ properties:
241
+ title: Page 2
242
+ blocks:
243
+ - id: content_card
244
+ type: Card
245
+ properties:
246
+ title: Title
247
+ blocks:
248
+ - id: paragraph
249
+ type: Paragraph
250
+ properties:
251
+ content: This is a paragraph on Page 2.
252
+ ```
253
+
254
+ In order to keep files neat and generally easier to read and understand, we suggest making use of references and templating.
255
+
256
+ ## References and templates
257
+
258
+ References and templates have the following use cases:
259
+
260
+ - Splitting out the config for readability and code navigation.
261
+ - Splitting out a piece of config in order to use the exact same config in multiple places.
262
+ - Using a reference with variables to make use of a shared piece of config with dynamic variables.
263
+ - Using a `.njk` file to create config files using the Nunjucks templating language.
264
+ - Using resolver and transformer functions to create Lowdefy config using Javascript functions.
265
+
266
+ References can be used anywhere in the configuration, as long as the configuration resolves to comply with the Lowdefy app schema. Templating can be taken further by referencing [Nunjucks](https://mozilla.github.io/nunjucks/) template files by simply adding .njk to the file extensions, for example, .yaml.njk. Nunjucks templates hydrate variables at build time, before the yaml is parsed, enabling Nunjucks features like for-loops and if-statements.
267
+
268
+ See more about references and templates [here](/references-and-templates).
269
+
270
+ ## Suppressing Build Validation with ~ignoreBuildChecks
271
+
272
+ The `~ignoreBuildChecks` property suppresses build-time validation errors and warnings. Suppression cascades down to all descendant config objects.
273
+
274
+ ### Syntax
275
+
276
+ ```yaml
277
+ # Suppress all checks for this object and descendants
278
+ ~ignoreBuildChecks: true
279
+
280
+ # Suppress only specific check types
281
+ ~ignoreBuildChecks:
282
+ - state-refs
283
+ - types
284
+ ```
285
+
286
+ ### Available Check Slugs
287
+
288
+ | Slug | What it suppresses |
289
+ |------|-------------------|
290
+ | `state-refs` | Undefined `_state` reference warnings |
291
+ | `payload-refs` | Undefined `_payload` reference warnings |
292
+ | `step-refs` | Undefined `_step` reference warnings |
293
+ | `link-refs` | Invalid Link action page reference warnings |
294
+ | `request-refs` | Invalid Request action reference warnings |
295
+ | `connection-refs` | Nonexistent connection ID references |
296
+ | `types` | All type validation (blocks, operators, actions, requests, connections) |
297
+ | `schema` | JSON schema validation errors |
298
+
299
+ ### Example: Dynamic State
300
+
301
+ Custom blocks can register state at runtime using `methods.registerEvent`. Since this state doesn't exist during build, you can suppress the validation warning:
302
+
303
+ ###### pages/custom-feature.yaml
304
+ ```yaml
305
+ blocks:
306
+ - id: custom_block
307
+ type: CustomBlock
308
+ properties:
309
+ onClick:
310
+ _state: dynamicState # Created by block at runtime
311
+ ~ignoreBuildChecks: true # Suppress all build checks
312
+ ```
313
+
314
+ Without `~ignoreBuildChecks`, the build would warn:
315
+ ```
316
+ [Config Warning] _state references "dynamicState" but no block with id "dynamicState" exists
317
+ ```
318
+
319
+ ### Example: Page-Level Suppression
320
+
321
+ Suppression cascades to all children, so you can set it on a page to affect all blocks:
322
+
323
+ ```yaml
324
+ pages:
325
+ - id: dynamic-page
326
+ type: Box
327
+ ~ignoreBuildChecks:
328
+ - state-refs # Only suppress state reference warnings
329
+ blocks:
330
+ - id: block1
331
+ type: TextInput
332
+ properties:
333
+ value:
334
+ _state: dynamicField # No warning (inherited from page)
335
+ ```
336
+
337
+ ### Example: Custom Plugin Types
338
+
339
+ When using custom plugin types that aren't registered, you can suppress type validation:
340
+
341
+ ```yaml
342
+ blocks:
343
+ - id: custom_block
344
+ type: MyCustomBlock # Custom type not in registry
345
+ ~ignoreBuildChecks:
346
+ - types
347
+ properties:
348
+ title: Hello
349
+ ```
350
+
351
+ > **Note:** `~ignoreBuildChecks` only affects build-time validation. Runtime errors still occur if references don't exist. Only use this for references you know will be valid at runtime.
352
+
353
+ ## Lowdefy versions and version updates
354
+
355
+ Lowdefy is versioned using semantic versioning, with a three part version number, with the form `major.minor.patch`. Lowdefy is under active development and is widely used in enterprise projects. New features and fixes are published on a regular basis, see our [changelog](https://github.com/lowdefy/lowdefy/blob/main/CHANGELOG.md) for the latest release notes.
356
+
357
+ [TODO]: <> (# TODO: Add roadmap, for whats to expect next.)
358
+
359
+ To update the version of your app, change the `lowdefy` version field in the `lowdefy.yaml` file, and redeploy the app. You might also need to make some changes to your app configuration to be compatible with the new version.
360
+
361
+ Patch updates only contain fixes, and you should be safe to update to a patched version without any changes to your app. Since we are actively developing new features, most releases will be minor version updates, and patches won't be made to older versions.
362
+
363
+ Minor version changes include new features. At this stage, since the project is still in early development, they might also have minor breaking changes to individual blocks, actions, operators or connections. Please check the [changelog](https://github.com/lowdefy/lowdefy/blob/main/CHANGELOG.md) to see if any configuration changes are needed before updating.
364
+
365
+ Major version updates may include major breaking changes or architecture changes. You might need to make more changes to your configuration to be compatible with the new version. We don't intend to release major versions regularly, and try to minimize breaking changes.