@lowdefy/docs-content 0.0.0-experimental-20260928120643 → 6.1.0
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.
- package/README.md +0 -1
- package/content/actions/link.md +0 -17
- package/content/actions/login.md +5 -23
- package/content/actions/logout.md +5 -5
- package/content/actions/pdfmake.md +2 -2
- package/content/actions/setdarkmode.md +2 -2
- package/content/agents/agent-properties.md +2 -4
- package/content/agents/agentchat.md +6 -21
- package/content/agents/agentconversations.md +2 -2
- package/content/concepts/ai-agent-docs.md +101 -313
- package/content/concepts/cli.md +3 -34
- package/content/concepts/connections-and-requests.md +0 -402
- package/content/concepts/custom-html.md +0 -40
- package/content/concepts/custom-styling.md +5 -50
- package/content/concepts/events-and-actions.md +2 -64
- package/content/concepts/i18n.md +2 -7
- package/content/concepts/keyboard-shortcuts.md +2 -2
- package/content/concepts/layout-overview.md +1 -1
- package/content/concepts/logger.md +0 -81
- package/content/concepts/lowdefy-schema.md +1 -4
- package/content/concepts/menus.md +7 -7
- package/content/concepts/module-authoring.md +2 -2
- package/content/connections/anthropic.md +2 -162
- package/content/connections/awss3.md +0 -54
- package/content/connections/google.md +2 -162
- package/content/connections/mongodb.md +3 -121
- package/content/connections/openai-connection.md +2 -162
- package/content/container-blocks/affix.md +7 -47
- package/content/container-blocks/alert.md +24 -76
- package/content/container-blocks/badge.md +24 -100
- package/content/container-blocks/box.md +9 -9
- package/content/container-blocks/card.md +25 -80
- package/content/container-blocks/carousel.md +7 -60
- package/content/container-blocks/collapse.md +9 -87
- package/content/container-blocks/configprovider.md +13 -35
- package/content/container-blocks/confirmmodal.md +23 -69
- package/content/container-blocks/content.md +98 -62
- package/content/container-blocks/descriptions.md +4 -45
- package/content/container-blocks/drawer.md +28 -92
- package/content/container-blocks/dropdownmenu.md +31 -119
- package/content/container-blocks/flex.md +62 -40
- package/content/container-blocks/footer.md +11 -15
- package/content/container-blocks/googlemapsheatmap.md +1 -1
- package/content/container-blocks/googlemapsscript.md +2 -2
- package/content/container-blocks/header.md +36 -71
- package/content/container-blocks/label.md +7 -34
- package/content/container-blocks/layout.md +34 -52
- package/content/container-blocks/masonry.md +71 -17
- package/content/container-blocks/mobilemenu.md +88 -131
- package/content/container-blocks/modal.md +26 -114
- package/content/container-blocks/pageheadermenu.md +31 -81
- package/content/container-blocks/pagesidebarlayout.md +26 -169
- package/content/container-blocks/pagesidermenu.md +42 -95
- package/content/container-blocks/popover.md +31 -34
- package/content/container-blocks/result.md +21 -32
- package/content/container-blocks/sider.md +122 -85
- package/content/container-blocks/span.md +7 -7
- package/content/container-blocks/spinner.md +3 -3
- package/content/container-blocks/splitter.md +68 -150
- package/content/container-blocks/tabs.md +12 -64
- package/content/container-blocks/tooltip.md +46 -22
- package/content/container-blocks/watermark.md +4 -22
- package/content/controls/reject.md +2 -4
- package/content/controls/throw.md +0 -1
- package/content/controls/try.md +2 -3
- package/content/deployment/deployment-environments.md +6 -8
- package/content/deployment/docker.md +7 -22
- package/content/deployment/node-server.md +0 -4
- package/content/deployment/vercel.md +6 -13
- package/content/display-blocks/aggrid.md +11 -26
- package/content/display-blocks/anchor.md +15 -15
- package/content/display-blocks/avatar.md +37 -57
- package/content/display-blocks/breadcrumb.md +21 -70
- package/content/display-blocks/button.md +18 -92
- package/content/display-blocks/calendar.md +0 -12
- package/content/display-blocks/dangeroushtml.md +1 -1
- package/content/display-blocks/difflist.md +1 -1
- package/content/display-blocks/difftimeline.md +1 -1
- package/content/display-blocks/divider.md +3 -64
- package/content/display-blocks/dropdownbutton.md +28 -79
- package/content/display-blocks/echart.md +1 -35
- package/content/display-blocks/floatbutton.md +42 -129
- package/content/display-blocks/html.md +1 -61
- package/content/display-blocks/icon.md +67 -250
- package/content/display-blocks/menu.md +73 -145
- package/content/display-blocks/message.md +124 -38
- package/content/display-blocks/notification.md +222 -94
- package/content/display-blocks/paragraph.md +9 -59
- package/content/display-blocks/progress.md +17 -96
- package/content/display-blocks/qrcode.md +4 -19
- package/content/display-blocks/s3download.md +1 -1
- package/content/display-blocks/search.md +7 -17
- package/content/display-blocks/skeletonbutton.md +0 -1
- package/content/display-blocks/skeletoninput.md +0 -1
- package/content/display-blocks/statistic.md +17 -75
- package/content/display-blocks/steps.md +25 -58
- package/content/display-blocks/tag.md +17 -102
- package/content/display-blocks/title.md +11 -50
- package/content/display-blocks/tour.md +23 -33
- package/content/input-blocks/autocomplete.md +9 -81
- package/content/input-blocks/buttonselector.md +8 -45
- package/content/input-blocks/checkboxselector.md +7 -97
- package/content/input-blocks/checkboxswitch.md +3 -33
- package/content/input-blocks/colorselector.md +14 -63
- package/content/input-blocks/daterangeselector.md +45 -165
- package/content/input-blocks/dateselector.md +41 -139
- package/content/input-blocks/datetimeselector.md +49 -158
- package/content/input-blocks/inputgallery.md +3 -3
- package/content/input-blocks/monthselector.md +52 -120
- package/content/input-blocks/multipleselector.md +39 -150
- package/content/input-blocks/numberinput.md +12 -98
- package/content/input-blocks/pagination.md +14 -70
- package/content/input-blocks/paragraphinput.md +37 -51
- package/content/input-blocks/passwordinput.md +6 -60
- package/content/input-blocks/phonenumberinput.md +26 -59
- package/content/input-blocks/radioselector.md +7 -83
- package/content/input-blocks/ratingslider.md +26 -57
- package/content/input-blocks/s3uploadbutton.md +24 -24
- package/content/input-blocks/s3uploaddragger.md +3 -3
- package/content/input-blocks/s3uploadphoto.md +5 -5
- package/content/input-blocks/segmentedselector.md +32 -72
- package/content/input-blocks/selector.md +21 -109
- package/content/input-blocks/switch.md +17 -65
- package/content/input-blocks/textarea.md +3 -32
- package/content/input-blocks/textinput.md +28 -69
- package/content/input-blocks/tiptapmentioninput.md +1 -1
- package/content/input-blocks/titleinput.md +12 -39
- package/content/input-blocks/treeinput.md +25 -49
- package/content/input-blocks/treemultipleselector.md +10 -127
- package/content/input-blocks/treeselector.md +9 -97
- package/content/input-blocks/upload.md +15 -64
- package/content/input-blocks/uploaddragger.md +1 -17
- package/content/input-blocks/uploadphoto.md +1 -18
- package/content/input-blocks/weekselector.md +55 -120
- package/content/list-blocks/controlledlist.md +15 -24
- package/content/list-blocks/list.md +11 -11
- package/content/list-blocks/masonrylist.md +34 -7
- package/content/migration/upgrade-guide.md +0 -1
- package/content/operators/_app.md +1 -2
- package/content/operators/_error.md +1 -23
- package/content/operators/_get.md +6 -6
- package/content/operators/_operator.md +3 -17
- package/content/operators/_ref.md +0 -258
- package/content/operators/_type.md +3 -14
- package/content/operators/_user.md +3 -3
- package/content/other/introduction.md +1 -1
- package/content/plugins/plugins-dev.md +0 -66
- package/content/plugins/plugins-introduction.md +1 -27
- package/content/testing/e2e-configuration.md +1 -8
- package/content/testing/e2e-getting-started.md +1 -1
- package/content/testing/e2e-introduction.md +1 -1
- package/content/tutorial/tutorial-actions-operators.md +2 -2
- package/content/tutorial/tutorial-add-blocks.md +2 -2
- package/content/tutorial/tutorial-create-page.md +2 -48
- package/content/tutorial/tutorial-display-data-page.md +3 -3
- package/content/tutorial/tutorial-requests-sql.md +0 -153
- package/content/tutorial/tutorial-start.md +1 -66
- package/content/user-authentication/login-and-logout.md +8 -158
- package/content/user-authentication/users-introduction.md +0 -8
- package/index.json +2 -6065
- package/package.json +1 -7
- package/scripts/extractAgentDocs.js +4 -36
- package/content/actions/emailotpsend.md +0 -58
- package/content/actions/emailotpverify.md +0 -77
- package/content/actions/getlocalstorage.md +0 -41
- package/content/actions/magiclinkverify.md +0 -113
- package/content/actions/posthogalias.md +0 -29
- package/content/actions/posthogcapture.md +0 -49
- package/content/actions/posthogcapturepageleave.md +0 -38
- package/content/actions/posthogfeatureflag.md +0 -50
- package/content/actions/posthoggroup.md +0 -37
- package/content/actions/posthogidentify.md +0 -54
- package/content/actions/posthoginit.md +0 -66
- package/content/actions/posthogoptin.md +0 -29
- package/content/actions/posthogoptout.md +0 -29
- package/content/actions/posthogpageview.md +0 -37
- package/content/actions/posthogreloadfeatureflags.md +0 -47
- package/content/actions/posthogreset.md +0 -28
- package/content/actions/posthogsetpersonproperties.md +0 -36
- package/content/actions/removelocalstorage.md +0 -26
- package/content/actions/setlocalstorage.md +0 -32
- package/content/adapter-reference/mongodbauthadapter.md +0 -46
- package/content/agents/agents-introduction.md +0 -107
- package/content/callback-reference/auth0logoutcallback.md +0 -54
- package/content/concepts/blocks.md +0 -150
- package/content/concepts/dynamic-page-content.md +0 -304
- package/content/concepts/html-attributes.md +0 -285
- package/content/concepts/lowdefy-api.md +0 -1110
- package/content/concepts/notifications.md +0 -155
- package/content/concepts/page-and-app-state.md +0 -244
- package/content/concepts/theming.md +0 -582
- package/content/connections/aigateway.md +0 -368
- package/content/connections/axioshttp.md +0 -181
- package/content/controls/while.md +0 -46
- package/content/display-blocks/clickablehtml.md +0 -239
- package/content/display-blocks/eventlog.md +0 -363
- package/content/display-blocks/pollingtimer.md +0 -263
- package/content/input-blocks/captcha.md +0 -40
- package/content/input-blocks/placesautocomplete.md +0 -319
- package/content/input-blocks/tagmultipleselector.md +0 -114
- package/content/input-blocks/tagselector.md +0 -114
- package/content/migration/auth-upgrade.md +0 -327
- package/content/migration/v3-to-v4.md +0 -417
- package/content/migration/v6-to-v7.md +0 -222
- package/content/operators/_cron.md +0 -292
- package/content/other/mongodbadapter.md +0 -3
- package/content/plugins/plugins-icon-sets.md +0 -267
- package/content/plugins/posthog.md +0 -275
- package/content/provider-reference/auth-js-providers.md +0 -107
- package/content/provider-reference/openidconnectprovider.md +0 -44
- package/content/testing/config-tests.md +0 -278
- package/content/tutorial/tutorial-requests-api.md +0 -155
- package/content/user-authentication/auth-configuration.md +0 -266
- package/content/user-authentication/auth-steps.md +0 -138
- package/content/user-authentication/mcp-oauth.md +0 -292
- package/content/user-authentication/organizations.md +0 -221
- package/content/user-authentication/protected-pages-apis.md +0 -97
- package/content/user-authentication/roles.md +0 -49
- package/content/user-authentication/two-factor.md +0 -229
- package/content/user-authentication/user-object.md +0 -58
- package/content/websockets/websocket-publish.md +0 -108
- package/content/websockets/websocket-subscriptions.md +0 -100
- package/content/websockets/websockets-introduction.md +0 -97
- package/hazards.json +0 -44
- package/scripts/hashDocSources.js +0 -38
- package/scripts/recordSourceHashes.js +0 -88
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
# Version 3 to Version 4
|
|
2
|
-
|
|
3
|
-
## Payload on Requests
|
|
4
|
-
|
|
5
|
-
In version 3, the `state`, `global`, `input`, `urlQuery` and `event` data objects were sent with the request. This allowed the use of the [`_state`](/_state), [`_global`](/_global), [`_input`](/_input), [`_url_query`](/_url_query) and [`_event`](/_event) operators inside requests and connections. If the state became too large, this would result in a payload size exceeded error on request calls.
|
|
6
|
-
|
|
7
|
-
In version 4, these operators can no longer be used in requests, and request payloads are introduced. Payloads can be used to specify the data that should be sent with the request. The data specified in the payload can be accessed using the `_payload` operator. Operators are evaluated in the payload before it is sent, so operators such as [`_state`](/_state) and [`_global`](_global) can be used in the payload.
|
|
8
|
-
|
|
9
|
-
If only the [`_state`](/_state) operator was used, the entire state object can be set as the payload:
|
|
10
|
-
|
|
11
|
-
###### Version 3:
|
|
12
|
-
|
|
13
|
-
```yaml
|
|
14
|
-
id: api_call
|
|
15
|
-
type: AxiosHttp
|
|
16
|
-
connectionId: my_api
|
|
17
|
-
properties:
|
|
18
|
-
url: /products/new
|
|
19
|
-
method: post
|
|
20
|
-
data:
|
|
21
|
-
name:
|
|
22
|
-
_state: name
|
|
23
|
-
product_category:
|
|
24
|
-
_state: name
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
###### Version 4:
|
|
28
|
-
|
|
29
|
-
```yaml
|
|
30
|
-
id: api_call
|
|
31
|
-
type: AxiosHttp
|
|
32
|
-
connectionId: my_api
|
|
33
|
-
payload:
|
|
34
|
-
_state: true
|
|
35
|
-
properties:
|
|
36
|
-
url: /products/new
|
|
37
|
-
method: post
|
|
38
|
-
data:
|
|
39
|
-
name:
|
|
40
|
-
_payload: name
|
|
41
|
-
product_category:
|
|
42
|
-
_payload: product_category
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
The payload can also be created more explicitly using more than one operator type:
|
|
46
|
-
|
|
47
|
-
###### Version 3:
|
|
48
|
-
|
|
49
|
-
```yaml
|
|
50
|
-
id: api_call
|
|
51
|
-
type: AxiosHttp
|
|
52
|
-
connectionId: my_api
|
|
53
|
-
properties:
|
|
54
|
-
url: /products/update
|
|
55
|
-
method: post
|
|
56
|
-
data:
|
|
57
|
-
id:
|
|
58
|
-
_url_query: id
|
|
59
|
-
name:
|
|
60
|
-
_state: name
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
###### Version 4:
|
|
64
|
-
|
|
65
|
-
```yaml
|
|
66
|
-
id: api_call
|
|
67
|
-
type: AxiosHttp
|
|
68
|
-
connectionId: my_api
|
|
69
|
-
payload:
|
|
70
|
-
id:
|
|
71
|
-
_url_query: id
|
|
72
|
-
name:
|
|
73
|
-
_state: name
|
|
74
|
-
properties:
|
|
75
|
-
url: /products/new
|
|
76
|
-
method: post
|
|
77
|
-
data:
|
|
78
|
-
id:
|
|
79
|
-
_payload: id
|
|
80
|
-
name:
|
|
81
|
-
_payload: name
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
The `user` data object is still available in requests, and the [`_user`](/_user) operator should be used in the request properties not in they payload as malicious users can modify the data sent in payload.
|
|
85
|
-
|
|
86
|
-
###### Don't do:
|
|
87
|
-
|
|
88
|
-
```yaml
|
|
89
|
-
id: api_call
|
|
90
|
-
type: AxiosHttp
|
|
91
|
-
connectionId: my_api
|
|
92
|
-
payload:
|
|
93
|
-
# ...
|
|
94
|
-
created_by:
|
|
95
|
-
_user: id
|
|
96
|
-
properties:
|
|
97
|
-
url: /products/new
|
|
98
|
-
method: post
|
|
99
|
-
data:
|
|
100
|
-
# ...
|
|
101
|
-
created_by:
|
|
102
|
-
_payload: created_by
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
###### Do:
|
|
106
|
-
|
|
107
|
-
```yaml
|
|
108
|
-
id: api_call
|
|
109
|
-
type: AxiosHttp
|
|
110
|
-
connectionId: my_api
|
|
111
|
-
payload:
|
|
112
|
-
# ...
|
|
113
|
-
properties:
|
|
114
|
-
url: /products/new
|
|
115
|
-
method: post
|
|
116
|
-
data:
|
|
117
|
-
# ...
|
|
118
|
-
created_by:
|
|
119
|
-
_user: id
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
> If you see a warning message like `Operator type "_state" was used but is not defined.`, you are using the `_state` operator in a request's properties and should move it to payload.
|
|
123
|
-
|
|
124
|
-
## Icons
|
|
125
|
-
|
|
126
|
-
The Ant Design icons used in version 3 have been replaced by [React Icons](https://react-icons.github.io/react-icons/), which has a much larger library of icons to choose from, including the Ant Design icons. To use a React Icon, set the `icon` or `icon.name` property to the React Icon name.
|
|
127
|
-
|
|
128
|
-
To convert existing Ant Design icons to React Icons, the icon names should be changed to the new format:
|
|
129
|
-
|
|
130
|
-
###### Version 3:
|
|
131
|
-
|
|
132
|
-
```yaml
|
|
133
|
-
id: save_button
|
|
134
|
-
type: Button
|
|
135
|
-
properties:
|
|
136
|
-
icon: SaveOutlined
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
###### Version 4:
|
|
140
|
-
|
|
141
|
-
```yaml
|
|
142
|
-
# Using the same Ant Design icon
|
|
143
|
-
id: save_button
|
|
144
|
-
type: Button
|
|
145
|
-
properties:
|
|
146
|
-
icon: AiOutlineSave
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
```yaml
|
|
150
|
-
# Using the Font Awesome icon
|
|
151
|
-
id: save_button
|
|
152
|
-
type: Button
|
|
153
|
-
properties:
|
|
154
|
-
icon: FaRegSave
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Renames and Minor changes
|
|
158
|
-
|
|
159
|
-
The `Message` action has been renamed to [`DisplayMessage`](/DisplayMessage). Change the type name of `Message` actions to [`DisplayMessage`](/DisplayMessage).
|
|
160
|
-
|
|
161
|
-
The `onEnter` and `onEnterAsync` events have been removed as their functionality is duplicated by the `onMount` and `onMountAsync` events. Rename all `onEnter` and `onEnterAsync` events to `onMount` and `onMountAsync` respectively.
|
|
162
|
-
|
|
163
|
-
Duplicate action ids in the same action chain were allowed in version 3, but are not allowed in version 4. If you get a build error about duplicate action ids, give the actions unique ids.
|
|
164
|
-
|
|
165
|
-
The `Notification` action has been removed. Switch to the [`DisplayMessage`](/DisplayMessage) action, or use a [`Notification`](/Notification) block and the `CallMethod` action to open the notification.
|
|
166
|
-
|
|
167
|
-
The 404 page is now always a public page.
|
|
168
|
-
|
|
169
|
-
The [`Anchor`](/Anchor) block properties schema has changed. The `href` property has been removed and it now takes the same props as the [`Link`](/Link) action.
|
|
170
|
-
|
|
171
|
-
The [`_yaml.parse`](/_yaml) operator now takes an object with a `on` property or an array where the first argument is the string to parse, instead of just a string, to allow it to take additional options.
|
|
172
|
-
|
|
173
|
-
The `ChromeColorSelector`, `CircleColorSelector`, `CompactColorSelector`, `GithubColorSelector`, `SliderColorSelector`, `SwatchesColorSelector`, and `TwitterColorSelector` have been replaced by the [`ColorSelector`](/ColorSelector) block.
|
|
174
|
-
|
|
175
|
-
The `color` properties in blocks like [`MobileMenu`](/MobileMenu), [`PageHeaderMenu`](/PageHeaderMenu), [`PageSiderMenu`](/PageSiderMenu) have been removed. Use Ant Design theme less variables instead.
|
|
176
|
-
|
|
177
|
-
The [`_var`](/_var) operator `name` param has been renamed to `key` to be more consistent with other getter operators.
|
|
178
|
-
|
|
179
|
-
The `_format` operator has been replaced with the [`_intl`](/_intl) and [`_moment`](/_moment) operator, with some minor schema changes. Note: `_moment` was renamed to [`_dayjs`](/_dayjs) in v5.
|
|
180
|
-
|
|
181
|
-
The format of dates in the output of the [`_json.stringify`](/_json) and [`_yaml.stringify`](/_yaml) operators, as well as in URL query parameters has changed from `_date: {iso_date_string}` to `~d: {iso_date_string}`.
|
|
182
|
-
|
|
183
|
-
## Block Loading States
|
|
184
|
-
|
|
185
|
-
The page loading states in version 4 have been improved. In general apps should load a lot faster. Blocks will now be a lot less likely to show a loading state and rather render as normal, and render their children. Input blocks will be disabled while in a loading state. This contributes to users seeing useful content sooner, and to less layout shifts once the app finishes loading.
|
|
186
|
-
|
|
187
|
-
In version 3, blocks had a `loading` property to specify the loading skeleton that should be used while the block is in a loading state. This functionality has been replaced by the `skeleton` property. The `loading` property is now used to control the loading state of the block. The block will be in a loading state if an `onInit` or `onMount` event is busy, if a parent block is loading or if the `loading` property evaluates to true. See more about loading [here](/blocks).
|
|
188
|
-
|
|
189
|
-
The convert from version 3 to version 4, replace the `loading` property on blocks with the `skeleton` property.
|
|
190
|
-
|
|
191
|
-
###### Version 3:
|
|
192
|
-
|
|
193
|
-
```yaml
|
|
194
|
-
id: paragraph_one
|
|
195
|
-
type: Markdown
|
|
196
|
-
loading:
|
|
197
|
-
type: SkeletonParagraph
|
|
198
|
-
properties:
|
|
199
|
-
lines: 5
|
|
200
|
-
properties:
|
|
201
|
-
content:
|
|
202
|
-
_request: get_text.body_text
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
###### Version 4:
|
|
206
|
-
|
|
207
|
-
```yaml
|
|
208
|
-
id: paragraph_one
|
|
209
|
-
type: Markdown
|
|
210
|
-
skeleton:
|
|
211
|
-
type: SkeletonParagraph
|
|
212
|
-
properties:
|
|
213
|
-
lines: 5
|
|
214
|
-
properties:
|
|
215
|
-
content:
|
|
216
|
-
_request: get_text.body_text
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
```yaml
|
|
220
|
-
# Keep the block in loading while the request is loading
|
|
221
|
-
id: paragraph_one
|
|
222
|
-
type: Markdown
|
|
223
|
-
loading:
|
|
224
|
-
_eq:
|
|
225
|
-
- _request: get_text
|
|
226
|
-
- null
|
|
227
|
-
skeleton:
|
|
228
|
-
type: SkeletonParagraph
|
|
229
|
-
properties:
|
|
230
|
-
lines: 5
|
|
231
|
-
properties:
|
|
232
|
-
content:
|
|
233
|
-
_request: get_text.body_text
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
## Static files
|
|
237
|
-
|
|
238
|
-
Static files placed in the `public` folder of your project were always served from the public url path - for example `https://example.com/public/filename.jpeg`. These files are now served from the root path of your app. The example above will now be served from `https://example.com/filename.jpeg`. This allows you to serve files like `robots.txt` and `sitemap.xml` from the root path. Change all references in your config to the new paths.
|
|
239
|
-
|
|
240
|
-
If you still want to serve assets under the `/public` path, you can add an addition `public` folder inside the existing `public` folder:
|
|
241
|
-
|
|
242
|
-
```txt
|
|
243
|
-
.
|
|
244
|
-
├─ public
|
|
245
|
-
│ └─ public
|
|
246
|
-
│ └─ my-logo.jpeg
|
|
247
|
-
└─ lowdefy.yaml
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Authentication Changes
|
|
251
|
-
|
|
252
|
-
In version 4, authentication has been reworked to use [NextAuth.js](https://next-auth.js.org), which offers a lot more flexibility and additional features - read more [here](/users-introduction).
|
|
253
|
-
|
|
254
|
-
To migrate a version 3 OpenID Connect provider, at least the following needs to be done:
|
|
255
|
-
- The `config.auth` property has moved to the `auth` root level property.
|
|
256
|
-
- The `config.auth.openId` properties have been removed, replace them with configuration for your provider:
|
|
257
|
-
```yaml
|
|
258
|
-
auth:
|
|
259
|
-
providers:
|
|
260
|
-
- id: auth0
|
|
261
|
-
type: Auth0Provider
|
|
262
|
-
properties:
|
|
263
|
-
clientId:
|
|
264
|
-
_secret: AUTH0_CLIENT_ID
|
|
265
|
-
clientSecret:
|
|
266
|
-
_secret: AUTH0_CLIENT_SECRET
|
|
267
|
-
issuer:
|
|
268
|
-
_secret: AUTH0_ISSUER
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
- The `NEXTAUTH_SECRET` environment variable needs to be set to a secure secret value (replacing `LOWDEFY_SECRET_JWT_SECRET`).
|
|
272
|
-
- The callback URLs configured with the provider change from `{{ protocol }}{{ host }}/auth/openid-callback` to `{{ protocol }}{{ host }}/api/auth/callback/{{ providerId }}`.
|
|
273
|
-
- The `Login` and `Logout` action params have changed between V3 and V4.
|
|
274
|
-
|
|
275
|
-
## Custom Blocks, Actions and Operators
|
|
276
|
-
|
|
277
|
-
Custom blocks, the `JsAction` action and the `_js` operator have been replaced by the new Lowdefy plugin system which is an easier, more powerful and standardized way to extend actions, blocks, connections, operators and the authentication system with custom JavaScript. See the [plugin documentation](/plugins-introduction) for more information on how to use and develop plugins.
|
|
278
|
-
|
|
279
|
-
The [AgGrid](https://github.com/lowdefy/blocks-aggrid) custom blocks have been added as default Lowdefy blocks, so these blocks can now be used without any additional configuration.
|
|
280
|
-
|
|
281
|
-
## Context has been removed
|
|
282
|
-
|
|
283
|
-
In version 3, the first block on a page needed to be a `context` category block. This was because in version 3 you could have multiple context blocks on the same page, each with it's own separate state.
|
|
284
|
-
|
|
285
|
-
This feature was found to be unnecessary, created additional complexity and was difficult to understand, so it was removed.
|
|
286
|
-
|
|
287
|
-
The `Context` type block was removed, as it was a `Box` block that also created a context. The `Context` block can be replaced by a `Box`.
|
|
288
|
-
|
|
289
|
-
If the `Context` block is no longer necessary it can also be removed:
|
|
290
|
-
|
|
291
|
-
###### Version 3:
|
|
292
|
-
|
|
293
|
-
```yaml
|
|
294
|
-
id: '404'
|
|
295
|
-
type: Context
|
|
296
|
-
style:
|
|
297
|
-
minHeight: 100vh
|
|
298
|
-
blocks:
|
|
299
|
-
- id: 404_result
|
|
300
|
-
type: Result
|
|
301
|
-
properties:
|
|
302
|
-
status: 404
|
|
303
|
-
title: '404'
|
|
304
|
-
subTitle: Sorry, the page you are visiting does not exist.
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
###### Version 4:
|
|
308
|
-
|
|
309
|
-
```yaml
|
|
310
|
-
id: '404'
|
|
311
|
-
type: Result
|
|
312
|
-
style:
|
|
313
|
-
minHeight: 100vh
|
|
314
|
-
properties:
|
|
315
|
-
status: 404
|
|
316
|
-
title: '404'
|
|
317
|
-
subTitle: Sorry, the page you are visiting does not exist.
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
## Other removed blocks
|
|
321
|
-
|
|
322
|
-
In version 4 the `PageHCF`, `PageHCSF`, `PageHSCF`, and `PageSHCF` blocks have been removed. Instead you can now use the `Layout`, `Header`, `Content`, `Sider` and `Footer` blocks. See more about this [here](https://4x.ant.design/components/layout/).
|
|
323
|
-
|
|
324
|
-
###### Layout, Header-Content-Footer example:
|
|
325
|
-
|
|
326
|
-
```yaml
|
|
327
|
-
id: layout
|
|
328
|
-
type: Layout
|
|
329
|
-
style:
|
|
330
|
-
textAlign: center
|
|
331
|
-
blocks:
|
|
332
|
-
- id: header
|
|
333
|
-
type: Header
|
|
334
|
-
blocks:
|
|
335
|
-
- id: Title
|
|
336
|
-
type: Title
|
|
337
|
-
properties:
|
|
338
|
-
content: Header
|
|
339
|
-
style:
|
|
340
|
-
backgroundColor: red
|
|
341
|
-
- id: content
|
|
342
|
-
type: Content
|
|
343
|
-
blocks:
|
|
344
|
-
- id: Title
|
|
345
|
-
type: Title
|
|
346
|
-
style:
|
|
347
|
-
backgroundColor: green
|
|
348
|
-
properties:
|
|
349
|
-
content: Content
|
|
350
|
-
- id: footer
|
|
351
|
-
type: Footer
|
|
352
|
-
blocks:
|
|
353
|
-
- id: Title
|
|
354
|
-
type: Title
|
|
355
|
-
style:
|
|
356
|
-
backgroundColor: blue
|
|
357
|
-
properties:
|
|
358
|
-
content: Footer
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
## Server Configuration
|
|
362
|
-
|
|
363
|
-
The `LOWDEFY_SERVER_BASE_PATH` environment variable configuration option has been removed. To configure a base path, use the `config.basePath` configuration option.
|
|
364
|
-
|
|
365
|
-
``yaml
|
|
366
|
-
lowdefy: 6.0.0
|
|
367
|
-
|
|
368
|
-
config:
|
|
369
|
-
basePath: /foo
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
The `_build.env` operator can be used to set the base path using an environment variable:
|
|
373
|
-
```yaml
|
|
374
|
-
lowdefy: 6.0.0
|
|
375
|
-
|
|
376
|
-
config:
|
|
377
|
-
basePath:
|
|
378
|
-
_build.env: LOWDEFY_BASE_PATH
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
The `LOWDEFY_SERVER_PUBLIC_DIRECTORY` and `LOWDEFY_SERVER_BUILD_DIRECTORY` are no longer supported because configuration is bundled with the server at build time.
|
|
382
|
-
|
|
383
|
-
The `LOWDEFY_SERVER_PORT` environment variable has been replaced by the `PORT` environment variable.
|
|
384
|
-
|
|
385
|
-
## _change_case
|
|
386
|
-
|
|
387
|
-
The options splitRegex and stripRegex are no longer supported in v4 and the following have been renamed:
|
|
388
|
-
- paramCase to kebabCase
|
|
389
|
-
- headerCase to trainCase
|
|
390
|
-
|
|
391
|
-
###### Version 3:
|
|
392
|
-
|
|
393
|
-
```yaml
|
|
394
|
-
_change_case.paramCase:
|
|
395
|
-
on: example string
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
###### Version 4:
|
|
399
|
-
|
|
400
|
-
```yaml
|
|
401
|
-
_change_case.kebabCase:
|
|
402
|
-
on: example string
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
###### Version 3:
|
|
406
|
-
|
|
407
|
-
```yaml
|
|
408
|
-
_change_case.headerCase:
|
|
409
|
-
on: example string
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
###### Version 4:
|
|
413
|
-
|
|
414
|
-
```yaml
|
|
415
|
-
_change_case.trainCase:
|
|
416
|
-
on: example string
|
|
417
|
-
```
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
# Version 6 to Version 7
|
|
2
|
-
|
|
3
|
-
This guide covers the icon changes when upgrading from Lowdefy v6 to v7. For the new auth system, see [Auth Upgrade](/auth-upgrade).
|
|
4
|
-
|
|
5
|
-
Lowdefy v7 draws every icon with [Lucide](https://lucide.dev) instead of [react-icons](https://react-icons.github.io/react-icons/). Icon names change from react-icons names (`AiOutlineDelete`) to semantic names (`delete`) and Lucide names (`Trash`). Blocks and Ant Design components draw Lucide icons too, so an app has one icon style.
|
|
6
|
-
|
|
7
|
-
## Summary of breaking changes
|
|
8
|
-
|
|
9
|
-
| Change | Impact | Action |
|
|
10
|
-
| ---------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------ |
|
|
11
|
-
| react-icons names are not built in | Almost every app | Run `lowdefy upgrade`, or install the compatibility set |
|
|
12
|
-
| An unknown icon name fails the build | Apps with old or misspelled names | Fix the name the error names |
|
|
13
|
-
| `_operator` names read at runtime need a list | Apps with a runtime `_operator` name | List the operators it may call in `operators` |
|
|
14
|
-
| Dynamic blocks render only written blocks | Apps returning stored blocks as data | Use a policy with `ValidateDynamic` |
|
|
15
|
-
| Block and Ant Design icons are Lucide | All apps | None; check screens that depend on the old look |
|
|
16
|
-
| `theme.icons.aliases` targets are Lucide names | Apps with aliases | Drop the `Lu` prefix: `LuReceipt` becomes `Receipt` |
|
|
17
|
-
| Icon hover titles come from the new names | Apps that show Icon block hover titles | Set `title` where the text matters |
|
|
18
|
-
| `react-icons` is not a server dependency | Plugins that import `react-icons` | Render `components.Icon` with a name, or add `react-icons` to the plugin |
|
|
19
|
-
| `ClickableHtml` fires only listed data events | Apps that use `data-event` | Run `lowdefy upgrade`, or list the events in `dataEvents` |
|
|
20
|
-
|
|
21
|
-
## Icon names
|
|
22
|
-
|
|
23
|
-
An icon name has one of three forms:
|
|
24
|
-
|
|
25
|
-
- **Semantic:** `edit`, `delete`, `chevron-down`. Built-in names for common jobs. [Theming](/theming) lists them all.
|
|
26
|
-
- **Lucide:** `Pencil`, `CreditCard`. The PascalCase name from [lucide.dev/icons](https://lucide.dev/icons).
|
|
27
|
-
- **Qualified:** `lucide:Pencil`. A name in a named [icon set](/plugins-icon-sets).
|
|
28
|
-
|
|
29
|
-
```yaml
|
|
30
|
-
# v6
|
|
31
|
-
- id: delete_button
|
|
32
|
-
type: Button
|
|
33
|
-
properties:
|
|
34
|
-
title: Delete
|
|
35
|
-
icon: AiOutlineDelete
|
|
36
|
-
- id: card_icon
|
|
37
|
-
type: Icon
|
|
38
|
-
properties:
|
|
39
|
-
name: AiOutlineCreditCard
|
|
40
|
-
|
|
41
|
-
# v7
|
|
42
|
-
- id: delete_button
|
|
43
|
-
type: Button
|
|
44
|
-
properties:
|
|
45
|
-
title: Delete
|
|
46
|
-
icon: delete
|
|
47
|
-
- id: card_icon
|
|
48
|
-
type: Icon
|
|
49
|
-
properties:
|
|
50
|
-
name: CreditCard
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Run the codemod
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
npx lowdefy upgrade
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
The v7 phase includes the `react-icons-to-lucide` codemod. It rewrites icon names as text, so it reaches:
|
|
60
|
-
|
|
61
|
-
- YAML, Nunjucks (`.njk`) and JSON config
|
|
62
|
-
- single-quoted names in `_js` code
|
|
63
|
-
- string literals and `meta.icons` in local plugin code
|
|
64
|
-
- `theme.icons.aliases` targets
|
|
65
|
-
|
|
66
|
-
Each old name maps to a semantic name where one fits, otherwise to a Lucide name. `Lu*` names drop the prefix (`LuPencil` becomes `Pencil`). The table lives in `@lowdefy/codemods` at `v7-0-0/react-icons-to-lucide.json`, and the build uses the same table for its error suggestions.
|
|
67
|
-
|
|
68
|
-
The codemod reports what it cannot decide for you:
|
|
69
|
-
|
|
70
|
-
- **Judgement calls**, where the closest Lucide glyph differs from the old one.
|
|
71
|
-
- **Known losses**: filled variants (`AiFillStar`), brand icons such as WhatsApp, and Word and PDF file glyphs. Lucide has no equivalents.
|
|
72
|
-
- **Runtime icon names**: icon properties set from `_state`, `_payload` or `_request`. The codemod does not change data. Use the compatibility set for names stored in a database.
|
|
73
|
-
|
|
74
|
-
## Build errors for old names
|
|
75
|
-
|
|
76
|
-
A literal icon name at an icon property that resolves to nothing fails the build. An old react-icons name gets a migration message:
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
Icon "AiOutlineDelete" is a react-icons name. Lowdefy 7 uses Lucide icons.
|
|
80
|
-
Use "delete" (or "Trash"). To keep react-icons names, install @lowdefy/icons-react-icons
|
|
81
|
-
and set theme.icons.set: react-icons. Run `lowdefy upgrade` to migrate names automatically.
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Old Ant Design names such as `HomeOutlined` get the same message, pointing at their semantic name. In v6 these names drew nothing, so the error may show icons that were missing all along.
|
|
85
|
-
|
|
86
|
-
An icon property is a key ending in `icon` (`icon`, `prefixIcon`, `suffixIcon`, ...), its `name` field, the Icon block's `name`, a `data-icon` attribute in HTML, and `theme.icons.aliases` and `theme.icons.include`. Names inside an operator are bundled but not checked. An unknown name that reaches the page at runtime draws a red `icon-missing` icon.
|
|
87
|
-
|
|
88
|
-
## Keep old names: the compatibility set
|
|
89
|
-
|
|
90
|
-
`@lowdefy/icons-react-icons` holds every react-icons 5.6.0 icon under its old name. Install it to keep old names working without edits, or for names stored in data:
|
|
91
|
-
|
|
92
|
-
```yaml
|
|
93
|
-
plugins:
|
|
94
|
-
- name: '@lowdefy/icons-react-icons'
|
|
95
|
-
version: '^7'
|
|
96
|
-
theme:
|
|
97
|
-
icons:
|
|
98
|
-
set: react-icons
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Old names then resolve in the compatibility set, and semantic and Lucide names still work. Block and Ant Design icons stay Lucide. Without `set: react-icons`, reach an old name with its qualified name: `react-icons:FaWhatsapp`. See [Icon Sets](/plugins-icon-sets).
|
|
102
|
-
|
|
103
|
-
## Visual changes
|
|
104
|
-
|
|
105
|
-
- **Block icons are Lucide.** Date picker calendars, input validation marks, selector arrows, the loading spinner, menu toggles and the dark mode toggle all use semantic names and draw Lucide icons.
|
|
106
|
-
- **Ant Design icons are Lucide.** Close buttons on modals, drawers, tags and alerts, alert and message status icons, collapse and menu arrows, pagination arrows, and button spinners use the same semantic names. Spin, Progress, QRCode, the Empty and Result illustrations, and the date picker panel arrows stay as Ant Design draws them.
|
|
107
|
-
- **Stroke width is a setting.** Lucide draws a 2px line on a 24px grid. Set `theme.icons.strokeWidth: 1.5` for a lighter look closer to Ant Design outline icons, or set `strokeWidth` on one icon.
|
|
108
|
-
- **Size is unchanged.** Icons default to `1em`, as before. Change it with `theme.icons.size`.
|
|
109
|
-
- **`color` and `rotate` go through CSS.** `color` colours stroke and fill icons alike, and `rotate` now turns the icon.
|
|
110
|
-
- **Hover titles change.** The Icon block's title comes from the name: `Pencil` gives "Pencil", and `more-vertical` gives "More vertical". Old names in the compatibility set give titles such as "Ai outline user". Set `title` where the text matters, or `title: ''` for none.
|
|
111
|
-
- **Icons without a title are hidden from screen readers** (`aria-hidden`).
|
|
112
|
-
|
|
113
|
-
## `theme.icons`
|
|
114
|
-
|
|
115
|
-
`theme.icons.aliases` targets are now Lucide or qualified names. The codemod rewrites them:
|
|
116
|
-
|
|
117
|
-
```yaml
|
|
118
|
-
# v6
|
|
119
|
-
theme:
|
|
120
|
-
icons:
|
|
121
|
-
aliases:
|
|
122
|
-
invoice: LuReceipt
|
|
123
|
-
include:
|
|
124
|
-
- LuFlag
|
|
125
|
-
|
|
126
|
-
# v7
|
|
127
|
-
theme:
|
|
128
|
-
icons:
|
|
129
|
-
aliases:
|
|
130
|
-
invoice: Receipt
|
|
131
|
-
include:
|
|
132
|
-
- Flag
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
`theme.icons` also has new keys: `set`, `size`, `strokeWidth` and `nonScalingStroke`. See [Theming](/theming).
|
|
136
|
-
|
|
137
|
-
## `_operator` names read at runtime
|
|
138
|
-
|
|
139
|
-
An `_operator` whose `name` is read at runtime (from state, a request, a payload or `__args`) must list the operators it may call in `operators`, or the build fails. The build loads exactly those operators with the page, so the call works on a direct page load, and `_operator` refuses any other name. A literal `name`, and the literal branches an `_if` or `_switch` returns, need no list.
|
|
140
|
-
|
|
141
|
-
```yaml
|
|
142
|
-
# v6
|
|
143
|
-
_operator:
|
|
144
|
-
name:
|
|
145
|
-
_state: aggregation
|
|
146
|
-
params:
|
|
147
|
-
_state: values
|
|
148
|
-
|
|
149
|
-
# v7
|
|
150
|
-
_operator:
|
|
151
|
-
name:
|
|
152
|
-
_state: aggregation
|
|
153
|
-
operators:
|
|
154
|
-
- _sum
|
|
155
|
-
- _product
|
|
156
|
-
params:
|
|
157
|
-
_state: values
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
## Blocks returned as data by a Dynamic endpoint
|
|
161
|
-
|
|
162
|
-
A `Dynamic` block without a dynamic blocks policy renders only the blocks and actions its endpoint writes in its `:return` config. Block config the endpoint reads as data (a database record, routine state, a nested endpoint's result) and returns as it is now renders the block's fallback, even when it holds no operators. Data can still fill values in written blocks, for example by mapping stored fields into blocks with `_array.map`.
|
|
163
|
-
|
|
164
|
-
To render stored or generated block config, declare a [dynamic blocks policy](/dynamic-page-content#dynamic-blocks-policies) that lists what the content may use, put it on the `Dynamic` block, and return the content through a `ValidateDynamic` step with the same policy:
|
|
165
|
-
|
|
166
|
-
```yaml
|
|
167
|
-
- id: check
|
|
168
|
-
type: ValidateDynamic
|
|
169
|
-
properties:
|
|
170
|
-
policy: stored_content
|
|
171
|
-
blocks:
|
|
172
|
-
_step: get_record.blocks
|
|
173
|
-
- :return:
|
|
174
|
-
blocks:
|
|
175
|
-
_step: check.blocks
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Plugins
|
|
179
|
-
|
|
180
|
-
Blocks no longer import icons from `react-icons` or `@ant-design/icons`, and the Lowdefy server no longer installs `react-icons`. A local block plugin should render icons by name with `components.Icon`, and list the names it uses in its `meta.icons`, so apps can restyle them:
|
|
181
|
-
|
|
182
|
-
```js
|
|
183
|
-
// v6
|
|
184
|
-
import { AiOutlineDelete } from 'react-icons/ai';
|
|
185
|
-
<AiOutlineDelete />;
|
|
186
|
-
|
|
187
|
-
// v7
|
|
188
|
-
<components.Icon blockId={`${blockId}_delete`} events={events} properties="delete" />;
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
A plugin that must keep importing `react-icons` adds it to its own `dependencies`.
|
|
192
|
-
|
|
193
|
-
## Auth links and client addresses
|
|
194
|
-
|
|
195
|
-
These changes affect apps with auth. See [Auth Upgrade](/auth-upgrade), [Auth configuration](/auth-configuration) and [Deploy with Docker](/docker#behind-a-reverse-proxy).
|
|
196
|
-
|
|
197
|
-
- **Pinned auth URL.** With `auth.email` configured, the production server refuses to start unless `BETTER_AUTH_URL` or the current environment's `url` in `config.environments` is set, so emailed auth links cannot take their host from a request. The dev server is unchanged.
|
|
198
|
-
- **Client address.** The server takes the client address for auth rate limits, sessions and request logs from the connection, and reads `X-Forwarded-For` only from the proxies listed in `config.trustedProxies`. Behind a reverse proxy or load balancer, list it there; otherwise every client shares the proxy's rate limits. On Vercel nothing changes.
|
|
199
|
-
- **Email link pages.** `SignUp` and `SendVerificationEmail` without a `callbackUrl` send the verification link to `auth.authPages.verifyEmail` (default `/verify-email`), not the home page. `RequestPasswordReset` without `redirectTo` sends the reset link to `auth.authPages.resetPassword` (default `/reset-password`). The build warns when the app sends these emails and the page does not exist.
|
|
200
|
-
|
|
201
|
-
## `ClickableHtml` data events
|
|
202
|
-
|
|
203
|
-
A `ClickableHtml` block now fires only the events its `dataEvents` property lists. A `data-event` whose name is not listed does nothing and logs a console warning, and a block without `dataEvents` fires no events from its HTML. HTML is often built from request or user data, and sanitising keeps `data-*` attributes, so in v6 markup inside that data could fire any event the block declared.
|
|
204
|
-
|
|
205
|
-
```yaml
|
|
206
|
-
# v6
|
|
207
|
-
- id: rows
|
|
208
|
-
type: ClickableHtml
|
|
209
|
-
properties:
|
|
210
|
-
html: '<i data-icon="delete" data-event="onDelete" data-id="42" data-confirm="Delete?"></i>'
|
|
211
|
-
|
|
212
|
-
# v7
|
|
213
|
-
- id: rows
|
|
214
|
-
type: ClickableHtml
|
|
215
|
-
properties:
|
|
216
|
-
dataEvents:
|
|
217
|
-
- name: onDelete
|
|
218
|
-
confirm: true
|
|
219
|
-
html: '<i data-icon="delete" data-event="onDelete" data-id="42" data-confirm="Delete?"></i>'
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
An entry is an event name, or `{ name, confirm }`: with `confirm`, every click on the event asks first, whatever the markup says. The `clickable-html-data-events` codemod in `lowdefy upgrade` adds `dataEvents` to each block and reports HTML built from data that inserts values without escaping them. It only reaches the app's files: add `dataEvents` yourself to `ClickableHtml` blocks that [dynamic page content](/dynamic-page-content) builds at page load, for example from config stored in a database. See [HTML attributes](/html-attributes).
|