@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.
Files changed (226) hide show
  1. package/README.md +0 -1
  2. package/content/actions/link.md +0 -17
  3. package/content/actions/login.md +5 -23
  4. package/content/actions/logout.md +5 -5
  5. package/content/actions/pdfmake.md +2 -2
  6. package/content/actions/setdarkmode.md +2 -2
  7. package/content/agents/agent-properties.md +2 -4
  8. package/content/agents/agentchat.md +6 -21
  9. package/content/agents/agentconversations.md +2 -2
  10. package/content/concepts/ai-agent-docs.md +101 -313
  11. package/content/concepts/cli.md +3 -34
  12. package/content/concepts/connections-and-requests.md +0 -402
  13. package/content/concepts/custom-html.md +0 -40
  14. package/content/concepts/custom-styling.md +5 -50
  15. package/content/concepts/events-and-actions.md +2 -64
  16. package/content/concepts/i18n.md +2 -7
  17. package/content/concepts/keyboard-shortcuts.md +2 -2
  18. package/content/concepts/layout-overview.md +1 -1
  19. package/content/concepts/logger.md +0 -81
  20. package/content/concepts/lowdefy-schema.md +1 -4
  21. package/content/concepts/menus.md +7 -7
  22. package/content/concepts/module-authoring.md +2 -2
  23. package/content/connections/anthropic.md +2 -162
  24. package/content/connections/awss3.md +0 -54
  25. package/content/connections/google.md +2 -162
  26. package/content/connections/mongodb.md +3 -121
  27. package/content/connections/openai-connection.md +2 -162
  28. package/content/container-blocks/affix.md +7 -47
  29. package/content/container-blocks/alert.md +24 -76
  30. package/content/container-blocks/badge.md +24 -100
  31. package/content/container-blocks/box.md +9 -9
  32. package/content/container-blocks/card.md +25 -80
  33. package/content/container-blocks/carousel.md +7 -60
  34. package/content/container-blocks/collapse.md +9 -87
  35. package/content/container-blocks/configprovider.md +13 -35
  36. package/content/container-blocks/confirmmodal.md +23 -69
  37. package/content/container-blocks/content.md +98 -62
  38. package/content/container-blocks/descriptions.md +4 -45
  39. package/content/container-blocks/drawer.md +28 -92
  40. package/content/container-blocks/dropdownmenu.md +31 -119
  41. package/content/container-blocks/flex.md +62 -40
  42. package/content/container-blocks/footer.md +11 -15
  43. package/content/container-blocks/googlemapsheatmap.md +1 -1
  44. package/content/container-blocks/googlemapsscript.md +2 -2
  45. package/content/container-blocks/header.md +36 -71
  46. package/content/container-blocks/label.md +7 -34
  47. package/content/container-blocks/layout.md +34 -52
  48. package/content/container-blocks/masonry.md +71 -17
  49. package/content/container-blocks/mobilemenu.md +88 -131
  50. package/content/container-blocks/modal.md +26 -114
  51. package/content/container-blocks/pageheadermenu.md +31 -81
  52. package/content/container-blocks/pagesidebarlayout.md +26 -169
  53. package/content/container-blocks/pagesidermenu.md +42 -95
  54. package/content/container-blocks/popover.md +31 -34
  55. package/content/container-blocks/result.md +21 -32
  56. package/content/container-blocks/sider.md +122 -85
  57. package/content/container-blocks/span.md +7 -7
  58. package/content/container-blocks/spinner.md +3 -3
  59. package/content/container-blocks/splitter.md +68 -150
  60. package/content/container-blocks/tabs.md +12 -64
  61. package/content/container-blocks/tooltip.md +46 -22
  62. package/content/container-blocks/watermark.md +4 -22
  63. package/content/controls/reject.md +2 -4
  64. package/content/controls/throw.md +0 -1
  65. package/content/controls/try.md +2 -3
  66. package/content/deployment/deployment-environments.md +6 -8
  67. package/content/deployment/docker.md +7 -22
  68. package/content/deployment/node-server.md +0 -4
  69. package/content/deployment/vercel.md +6 -13
  70. package/content/display-blocks/aggrid.md +11 -26
  71. package/content/display-blocks/anchor.md +15 -15
  72. package/content/display-blocks/avatar.md +37 -57
  73. package/content/display-blocks/breadcrumb.md +21 -70
  74. package/content/display-blocks/button.md +18 -92
  75. package/content/display-blocks/calendar.md +0 -12
  76. package/content/display-blocks/dangeroushtml.md +1 -1
  77. package/content/display-blocks/difflist.md +1 -1
  78. package/content/display-blocks/difftimeline.md +1 -1
  79. package/content/display-blocks/divider.md +3 -64
  80. package/content/display-blocks/dropdownbutton.md +28 -79
  81. package/content/display-blocks/echart.md +1 -35
  82. package/content/display-blocks/floatbutton.md +42 -129
  83. package/content/display-blocks/html.md +1 -61
  84. package/content/display-blocks/icon.md +67 -250
  85. package/content/display-blocks/menu.md +73 -145
  86. package/content/display-blocks/message.md +124 -38
  87. package/content/display-blocks/notification.md +222 -94
  88. package/content/display-blocks/paragraph.md +9 -59
  89. package/content/display-blocks/progress.md +17 -96
  90. package/content/display-blocks/qrcode.md +4 -19
  91. package/content/display-blocks/s3download.md +1 -1
  92. package/content/display-blocks/search.md +7 -17
  93. package/content/display-blocks/skeletonbutton.md +0 -1
  94. package/content/display-blocks/skeletoninput.md +0 -1
  95. package/content/display-blocks/statistic.md +17 -75
  96. package/content/display-blocks/steps.md +25 -58
  97. package/content/display-blocks/tag.md +17 -102
  98. package/content/display-blocks/title.md +11 -50
  99. package/content/display-blocks/tour.md +23 -33
  100. package/content/input-blocks/autocomplete.md +9 -81
  101. package/content/input-blocks/buttonselector.md +8 -45
  102. package/content/input-blocks/checkboxselector.md +7 -97
  103. package/content/input-blocks/checkboxswitch.md +3 -33
  104. package/content/input-blocks/colorselector.md +14 -63
  105. package/content/input-blocks/daterangeselector.md +45 -165
  106. package/content/input-blocks/dateselector.md +41 -139
  107. package/content/input-blocks/datetimeselector.md +49 -158
  108. package/content/input-blocks/inputgallery.md +3 -3
  109. package/content/input-blocks/monthselector.md +52 -120
  110. package/content/input-blocks/multipleselector.md +39 -150
  111. package/content/input-blocks/numberinput.md +12 -98
  112. package/content/input-blocks/pagination.md +14 -70
  113. package/content/input-blocks/paragraphinput.md +37 -51
  114. package/content/input-blocks/passwordinput.md +6 -60
  115. package/content/input-blocks/phonenumberinput.md +26 -59
  116. package/content/input-blocks/radioselector.md +7 -83
  117. package/content/input-blocks/ratingslider.md +26 -57
  118. package/content/input-blocks/s3uploadbutton.md +24 -24
  119. package/content/input-blocks/s3uploaddragger.md +3 -3
  120. package/content/input-blocks/s3uploadphoto.md +5 -5
  121. package/content/input-blocks/segmentedselector.md +32 -72
  122. package/content/input-blocks/selector.md +21 -109
  123. package/content/input-blocks/switch.md +17 -65
  124. package/content/input-blocks/textarea.md +3 -32
  125. package/content/input-blocks/textinput.md +28 -69
  126. package/content/input-blocks/tiptapmentioninput.md +1 -1
  127. package/content/input-blocks/titleinput.md +12 -39
  128. package/content/input-blocks/treeinput.md +25 -49
  129. package/content/input-blocks/treemultipleselector.md +10 -127
  130. package/content/input-blocks/treeselector.md +9 -97
  131. package/content/input-blocks/upload.md +15 -64
  132. package/content/input-blocks/uploaddragger.md +1 -17
  133. package/content/input-blocks/uploadphoto.md +1 -18
  134. package/content/input-blocks/weekselector.md +55 -120
  135. package/content/list-blocks/controlledlist.md +15 -24
  136. package/content/list-blocks/list.md +11 -11
  137. package/content/list-blocks/masonrylist.md +34 -7
  138. package/content/migration/upgrade-guide.md +0 -1
  139. package/content/operators/_app.md +1 -2
  140. package/content/operators/_error.md +1 -23
  141. package/content/operators/_get.md +6 -6
  142. package/content/operators/_operator.md +3 -17
  143. package/content/operators/_ref.md +0 -258
  144. package/content/operators/_type.md +3 -14
  145. package/content/operators/_user.md +3 -3
  146. package/content/other/introduction.md +1 -1
  147. package/content/plugins/plugins-dev.md +0 -66
  148. package/content/plugins/plugins-introduction.md +1 -27
  149. package/content/testing/e2e-configuration.md +1 -8
  150. package/content/testing/e2e-getting-started.md +1 -1
  151. package/content/testing/e2e-introduction.md +1 -1
  152. package/content/tutorial/tutorial-actions-operators.md +2 -2
  153. package/content/tutorial/tutorial-add-blocks.md +2 -2
  154. package/content/tutorial/tutorial-create-page.md +2 -48
  155. package/content/tutorial/tutorial-display-data-page.md +3 -3
  156. package/content/tutorial/tutorial-requests-sql.md +0 -153
  157. package/content/tutorial/tutorial-start.md +1 -66
  158. package/content/user-authentication/login-and-logout.md +8 -158
  159. package/content/user-authentication/users-introduction.md +0 -8
  160. package/index.json +2 -6065
  161. package/package.json +1 -7
  162. package/scripts/extractAgentDocs.js +4 -36
  163. package/content/actions/emailotpsend.md +0 -58
  164. package/content/actions/emailotpverify.md +0 -77
  165. package/content/actions/getlocalstorage.md +0 -41
  166. package/content/actions/magiclinkverify.md +0 -113
  167. package/content/actions/posthogalias.md +0 -29
  168. package/content/actions/posthogcapture.md +0 -49
  169. package/content/actions/posthogcapturepageleave.md +0 -38
  170. package/content/actions/posthogfeatureflag.md +0 -50
  171. package/content/actions/posthoggroup.md +0 -37
  172. package/content/actions/posthogidentify.md +0 -54
  173. package/content/actions/posthoginit.md +0 -66
  174. package/content/actions/posthogoptin.md +0 -29
  175. package/content/actions/posthogoptout.md +0 -29
  176. package/content/actions/posthogpageview.md +0 -37
  177. package/content/actions/posthogreloadfeatureflags.md +0 -47
  178. package/content/actions/posthogreset.md +0 -28
  179. package/content/actions/posthogsetpersonproperties.md +0 -36
  180. package/content/actions/removelocalstorage.md +0 -26
  181. package/content/actions/setlocalstorage.md +0 -32
  182. package/content/adapter-reference/mongodbauthadapter.md +0 -46
  183. package/content/agents/agents-introduction.md +0 -107
  184. package/content/callback-reference/auth0logoutcallback.md +0 -54
  185. package/content/concepts/blocks.md +0 -150
  186. package/content/concepts/dynamic-page-content.md +0 -304
  187. package/content/concepts/html-attributes.md +0 -285
  188. package/content/concepts/lowdefy-api.md +0 -1110
  189. package/content/concepts/notifications.md +0 -155
  190. package/content/concepts/page-and-app-state.md +0 -244
  191. package/content/concepts/theming.md +0 -582
  192. package/content/connections/aigateway.md +0 -368
  193. package/content/connections/axioshttp.md +0 -181
  194. package/content/controls/while.md +0 -46
  195. package/content/display-blocks/clickablehtml.md +0 -239
  196. package/content/display-blocks/eventlog.md +0 -363
  197. package/content/display-blocks/pollingtimer.md +0 -263
  198. package/content/input-blocks/captcha.md +0 -40
  199. package/content/input-blocks/placesautocomplete.md +0 -319
  200. package/content/input-blocks/tagmultipleselector.md +0 -114
  201. package/content/input-blocks/tagselector.md +0 -114
  202. package/content/migration/auth-upgrade.md +0 -327
  203. package/content/migration/v3-to-v4.md +0 -417
  204. package/content/migration/v6-to-v7.md +0 -222
  205. package/content/operators/_cron.md +0 -292
  206. package/content/other/mongodbadapter.md +0 -3
  207. package/content/plugins/plugins-icon-sets.md +0 -267
  208. package/content/plugins/posthog.md +0 -275
  209. package/content/provider-reference/auth-js-providers.md +0 -107
  210. package/content/provider-reference/openidconnectprovider.md +0 -44
  211. package/content/testing/config-tests.md +0 -278
  212. package/content/tutorial/tutorial-requests-api.md +0 -155
  213. package/content/user-authentication/auth-configuration.md +0 -266
  214. package/content/user-authentication/auth-steps.md +0 -138
  215. package/content/user-authentication/mcp-oauth.md +0 -292
  216. package/content/user-authentication/organizations.md +0 -221
  217. package/content/user-authentication/protected-pages-apis.md +0 -97
  218. package/content/user-authentication/roles.md +0 -49
  219. package/content/user-authentication/two-factor.md +0 -229
  220. package/content/user-authentication/user-object.md +0 -58
  221. package/content/websockets/websocket-publish.md +0 -108
  222. package/content/websockets/websocket-subscriptions.md +0 -100
  223. package/content/websockets/websockets-introduction.md +0 -97
  224. package/hazards.json +0 -44
  225. package/scripts/hashDocSources.js +0 -38
  226. package/scripts/recordSourceHashes.js +0 -88
@@ -1,51 +1,5 @@
1
1
  # 2. Creating a page
2
2
 
3
- Let's create a page for a web form where users can log a new ticket.
4
-
5
- #### 2.1. Create `new-ticket.yaml`
6
-
7
- Create a new YAML file in the project directory (the same directory as the `lowdefy.yaml` file) called `new-ticket.yaml`, with the following content:
8
-
9
- ```yaml
10
- id: new-ticket
11
- type: PageHeaderMenu
12
- properties:
13
- title: New ticket # The title in the browser tab.
14
- layout:
15
- justify: center # Center the contents of the page.
16
- blocks:
17
- - id: content_card
18
- type: Card
19
- layout:
20
- size: 800 # Set the size of the card so it does not fill the full screen.
21
- gap: 16 # Make a 16px gap between all blocks in this card.
22
- blocks:
23
- - id: page_heading
24
- type: Title
25
- properties:
26
- content: Log a ticket # Change the title on the page.
27
- level: 3 # Make the title a little smaller (an html `<h3>`).
28
- ```
29
-
30
- #### 2.2. Update `lowdefy.yaml`
31
-
32
- Change the `lowdefy.yaml` to look like this:
33
-
34
- ```yaml
35
- name: lowdefy-project-template
36
- lowdefy: 6.0.0
37
-
38
- pages:
39
- ################ -------- Copy from here -------- ################
40
- - _ref: new-ticket.yaml
41
- ################ -------- Copy to here ---------- ################
42
- - id: welcome
43
- type: PageHeaderMenu
44
- properties:
45
- title: Welcome
46
- # ...
47
- ```
48
-
49
3
  > Indentation is important
50
4
 
51
5
  #### 2.3. Navigate to the new page
@@ -79,13 +33,13 @@ menus:
79
33
  - id: new-ticket
80
34
  type: MenuLink
81
35
  properties:
82
- icon: Siren
36
+ icon: AiOutlineAlert
83
37
  title: New ticket
84
38
  pageId: new-ticket
85
39
  - id: welcome
86
40
  type: MenuLink
87
41
  properties:
88
- icon: home
42
+ icon: AiOutlineHome
89
43
  title: Home
90
44
  pageId: welcome
91
45
  ################ -------- Copy to here ---------- ################
@@ -140,20 +140,20 @@ menus:
140
140
  - id: welcome
141
141
  type: MenuLink
142
142
  properties:
143
- icon: home
143
+ icon: AiOutlineHome
144
144
  title: Home
145
145
  pageId: welcome
146
146
  - id: new-ticket
147
147
  type: MenuLink
148
148
  properties:
149
- icon: Siren
149
+ icon: AiOutlineAlert
150
150
  title: New ticket
151
151
  pageId: new-ticket
152
152
  ################ -------- Copy from here -------- ################
153
153
  - id: view-tickets
154
154
  type: MenuLink
155
155
  properties:
156
- icon: Database
156
+ icon: AiOutlineDatabase
157
157
  title: View tickets
158
158
  pageId: view-tickets
159
159
  ############### -------- Copy to here ---------- ################
@@ -20,156 +20,3 @@ We will make use of an SQLite database with a table called `tickets`, that has t
20
20
  - created_date
21
21
 
22
22
  The database used in this tutorial can be downloaded <a href="/tutorial/tutorial_db.sqlite" download>here</a>.
23
-
24
- Alternatively, install [SQLite](https://www.sqlite.org/) on your computer and use the following to create the needed table:
25
-
26
- ```
27
- CREATE TABLE tickets (
28
- ticket_title varchar(100),
29
- ticket_type varchar(50),
30
- ticket_description varchar(200),
31
- product varchar(100),
32
- purchase_in_last_month real,
33
- created_date real
34
- );
35
- ```
36
-
37
- #### 6.2. Setting app environment variables
38
-
39
- Create a file called `.env` in your project directory with the following content:
40
-
41
- ##### `.env`
42
- ```
43
- LOWDEFY_SECRET_SQLITE_FILENAME= __ABSOLUTE_PATH_TO_SQLITE_DB_FILE__
44
- ```
45
-
46
- #### 5.2.3. Setting the connection environment variable secrets
47
-
48
- In your `lowdefy.yaml` file, add the following:
49
-
50
- ##### `lowdefy.yaml`
51
-
52
- ```yaml
53
- name: lowdefy-project-template
54
- version: 6.0.0
55
-
56
- connections:
57
- # ...
58
- ################ -------- Copy from here -------- ################
59
- - id: knex
60
- type: Knex
61
- properties:
62
- client: sqlite
63
- connection:
64
- filename:
65
- _secret: SQLITE_FILENAME
66
- ################ ------- Copy to here ----------- ################
67
-
68
- menus:
69
- # ...
70
- ```
71
-
72
- #### 6.3. Creating a save data request
73
-
74
- In your `new-ticket.yaml` file, add the following request:
75
-
76
- ##### `pages/new-ticket.yaml`
77
-
78
- ```yaml
79
- id: new-ticket
80
- type: PageHeaderMenu
81
- requests:
82
- # ...
83
- ################ -------- Copy from here -------- ################
84
- - id: save_new_ticket
85
- type: KnexRaw
86
- connectionId: knex
87
- payload:
88
- _state: true
89
- properties:
90
- query: |
91
- INSERT INTO tickets (
92
- ticket_title,
93
- ticket_type,
94
- ticket_description,
95
- product,
96
- purchase_in_last_month,
97
- created_date)
98
- VALUES(
99
- :ticket_title,
100
- :ticket_type,
101
- :ticket_description,
102
- :product,
103
- :purchase_in_last_month,
104
- :created_date)
105
- parameters:
106
- ticket_title:
107
- _payload: ticket_title
108
- ticket_type:
109
- _payload: ticket_type
110
- ticket_description:
111
- _payload: ticket_description
112
- product:
113
- _payload: product
114
- purchase_in_last_month:
115
- _payload: purchase_in_last_month
116
- created_date:
117
- _date: now
118
- ################ ------- Copy to here ----------- ################
119
-
120
- properties:
121
- title: New ticket # The title in the browser tab.
122
- layout:
123
- justify: center # Center the contents of the page
124
- blocks:
125
- # ...
126
- ```
127
-
128
- #### 6.4. Triggering the save data request
129
-
130
- In your `new-ticket.yaml` file, add the following action to the submit button:
131
-
132
- ##### `pages/new-ticket.yaml`
133
-
134
- ```yaml
135
- id: new-ticket
136
- # ...
137
- blocks:
138
- - id: content_card
139
- # ...
140
- blocks:
141
- - id: page_heading
142
- # ...
143
- # ...
144
- # ...
145
- - id: submit_button
146
- type: Button
147
- #...
148
- events:
149
- onClick:
150
- - id: validate
151
- type: Validate
152
- ################ -------- Copy from here -------- ################
153
- - id: save_new_ticket # Make a request to the SQLite database
154
- type: Request
155
- params: save_new_ticket
156
- - id: reset # Reset the form once data has been submitted
157
- type: Reset
158
- ################ ------- Copy to here ----------- ################
159
- ```
160
-
161
- If you click the submit button, your form data should be added into the tickets table.
162
-
163
- ### What happened
164
-
165
- We set up the table and column names we will be using in our SQLite database. We need to do this to use the `SQLite` connection.
166
-
167
- We defined the `Knex` connection, with the SQLite client.
168
-
169
- We also defined a `KnexRaw` request, to save the data to our SQLite database, and called that request when clicking the submit button. This was done by making use of the `onCLick` event on the button to execute the [`Request`](/Request) action to make the API call.
170
-
171
- > You can find the final configuration files for this section [here](https://github.com/lowdefy/lowdefy-example-tutorial/tree/main/06-requests-sql).
172
-
173
- ### Up next
174
-
175
- Next, we will add a new page to display all open tickets an a table.
@@ -4,7 +4,7 @@ In this tutorial, we will be creating a simple ticketing app that allows users t
4
4
 
5
5
  ### Requirements
6
6
 
7
- The Lowdefy CLI (Command Line Interface) is needed to run the development server. To run the Lowdefy CLI you need to install Node.js at version 24 or greater. If you don't have it installed, download Node.js from https://nodejs.org/en/download/, and follow the installation steps for your computer. All of the default settings given by the installer are fine for what we need. You will also need a text editor to modify the Lowdefy configuration files.
7
+ The Lowdefy CLI (Command Line Interface) is needed to run the development server. To run the Lowdefy CLI you need to install Node.js at version 22 or greater. If you don't have it installed, download Node.js from https://nodejs.org/en/download/, and follow the installation steps for your computer. All of the default settings given by the installer are fine for what we need. You will also need a text editor to modify the Lowdefy configuration files.
8
8
 
9
9
  Lowdefy also requires [`pnpm`](https://pnpm.io/) to be installed. We recommend making activating [Corepack](https://nodejs.org/api/corepack.html), even though it is an experimental feature, as this is the simplest way to install `pnpm`. Alternative methods to install `pnpm` can also be found [here](https://pnpm.io/installation). To activate Corepack, run the following in your computer's command line interface (Windows CMD, Terminal on MacOS).
10
10
 
@@ -58,71 +58,6 @@ Made by a Lowdefy 🤖
58
58
 
59
59
  > __Error: Could not find "lowdefy.yaml"__: Make sure your current working directory contains the _lowdefy.yaml_ file. You can verify this by running the `dir` (Windows) or `ls` (MacOS) command.
60
60
 
61
- #### 1.5. Open the configuration file
62
-
63
- Open the `lowdefy.yaml` file using a text editor like [VS Code](https://code.visualstudio.com/download). The content of the file should look like this:
64
-
65
- ```yaml
66
- lowdefy: 6.0.0
67
- name: Lowdefy starter
68
-
69
- pages:
70
- - id: welcome
71
- type: PageHeaderMenu
72
- properties:
73
- title: Welcome
74
- slots:
75
- content:
76
- justify: center
77
- blocks:
78
- - id: content_card
79
- type: Card
80
- style:
81
- maxWidth: 800
82
- blocks:
83
- - id: content
84
- type: Result
85
- properties:
86
- title: Welcome to your Lowdefy app
87
- subTitle: We are excited to see what you are going to build
88
- icon:
89
- name: heart
90
- color: '#f00'
91
- slots:
92
- extra:
93
- blocks:
94
- - id: docs_button
95
- type: Button
96
- properties:
97
- size: large
98
- title: Let's build something
99
- events:
100
- onClick:
101
- - id: link_to_docs
102
- type: Link
103
- params:
104
- url: https://docs.lowdefy.com
105
- newWindow: true
106
- footer:
107
- blocks:
108
- - id: footer
109
- type: Paragraph
110
- properties:
111
- type: secondary
112
- content: |
113
- Made by a Lowdefy 🤖
114
- ```
115
-
116
- This configuration completely describes the app you are running.
117
-
118
- #### 1.6. Make some changes
119
-
120
- Let's modify the button to link to the Lowdefy Discord community instead of to the Lowdefy docs.
121
-
122
- First, change `Let's build something` to `Join Lowdefy on Discord`, then save the file. Your page should automatically refresh and you should see the changed text of the button.
123
-
124
- Next, update the link url to the Lowdefy Discord link, replace `https://docs.lowdefy.com` with [`https://discord.gg/QQY9eJ7A2D`](https://discord.gg/QQY9eJ7A2D), then save the file. If you now click the button it should open a new window linking to the Lowdefy Discord Channel - Join our community to ask questions or learn more regarding Lowdefy ❤️
125
-
126
61
  ### What happened
127
62
 
128
63
  The Lowdefy CLI helps you develop a Lowdefy app.
@@ -8,19 +8,15 @@ The `Login` action is used to start the user login flow. If only one OAuth provi
8
8
 
9
9
  The authorization url usually hosts a page where the user can input their credentials. After the user has logged in successfully, the user is redirected to the `/api/auth/callback/<provider_id>` route in the Lowdefy app, where the rest of the authorization code flow is completed. This URL usually needs to be configured in the identity provider's settings.
10
10
 
11
- The `callbackUrl` parameter of the Login action specifies where the user lands after login is complete. Three sources are consulted, in order: the `callbackUrl` param, then the `?callbackUrl=` query parameter Lowdefy sets when it redirects an unauthenticated user to the sign-in page, then the app's home page. If none resolves the action throws, rather than staying silently on the sign-in page.
12
-
13
- In a protected app a signed-out visitor is sent to the sign-in page for every URL, present or absent, so a `404` means you are signed in — see [Page and API existence](/auth-upgrade#page-and-api-existence-is-no-longer-observable-before-you-sign-in).
14
-
15
- To sign in without navigating at all - a login form in a modal, or an embedded panel - set `callbackUrl: false`. This is not valid for magic-link or social/OAuth sign-in, which redirect through a hop Lowdefy does not control.
11
+ The `callbackUrl` parameters of the Login action specify where the user is redirected after login is complete. If `callbackUrl` parameters not set, the user will return to the page from which the action was called.
16
12
 
17
13
  The parameters are:
18
14
  - `authUrl: object`:
19
15
  - `urlQuery: object`: Query parameters to set for the authorization URL.
20
- - `callbackUrl: object | false`: Set to `false` to sign in without navigating. As an object:
16
+ - `callbackUrl: object`:
21
17
  - `home: boolean`: Redirect to the home page after the login flow is complete.
22
18
  - `pageId: string`: The pageId of the page to redirect to after the login flow is complete.
23
- - `url: string`: The URL to redirect to after the login flow is complete. An absolute URL is not `basePath`-prefixed, so it can be an external landing page.
19
+ - `url: string`: The URL to redirect to after the login flow is complete.
24
20
  - `urlQuery: object`: The urlQuery to set for the page the user is redirected to after login.
25
21
  - `providerId: string`: The ID of the provider that should be used for login. If not set and only one provider is configured the configured provider will be used. Else the user will be redirected to a sign in page where they can choose a provider.
26
22
 
@@ -95,164 +91,18 @@ events:
95
91
  screen_hint: signup
96
92
  ```
97
93
 
98
- ## Magic link sign-in
99
-
100
- `Login` with `magicLink: true` emails the user a sign-in link. By default that link points straight at Better Auth's verify endpoint, which consumes the single-use token on the first `GET` of the URL.
101
-
102
- That is a problem in corporate inboxes. Mail security products — Microsoft Defender Safe Links, Proofpoint URL Defense, Mimecast — fetch every link in a message as it is delivered, so the scanner spends the token minutes before the person clicks, and the person lands on the error page with `INVALID_TOKEN`.
103
-
104
- Set [`auth.authPages.magicLink`](/auth-configuration#auth-pages) to a page in your app to close that gap. The email then links to your page, carrying the token and the callback destinations on its URL query, and a [`MagicLinkVerify`](/MagicLinkVerify) action on a **button click** walks to the verify endpoint. Fetching the landing page does nothing, so a scanner cannot consume the token.
105
-
106
- ```yaml
107
- lowdefy: {{ version }}
108
- auth:
109
- magicLink:
110
- enabled: true
111
- authPages:
112
- magicLink: /magic-link
113
- ```
114
-
115
- ```yaml
116
- id: magic-link
117
- type: PageHeaderMenu
118
- blocks:
119
- - id: content
120
- type: Box
121
- blocks:
122
- - id: title
123
- type: Title
124
- properties:
125
- content: Sign in
126
- level: 3
127
- - id: description
128
- type: Paragraph
129
- properties:
130
- content: Click the button below to finish signing in.
131
- - id: verify_button
132
- type: Button
133
- properties:
134
- title: Sign in
135
- events:
136
- onClick:
137
- - id: verify
138
- type: MagicLinkVerify
139
- ```
140
-
141
- The landing page must be reachable while signed out, so add it to `auth.pages.public`.
142
-
143
- Do **not** run `MagicLinkVerify` in the page's `onMount`, and do not auto-redirect to the verify endpoint. Some scanning sandboxes render the page and execute its JavaScript, so an automatic verify hands the token back to the scanner and you are no better off than linking at the endpoint directly. The whole protection is that a human has to click.
144
-
145
- The action needs no parameters: the token and the `callbackURL`, `newUserCallbackURL` and `errorCallbackURL` values are read from the landing page's own URL query, which the email put there. Pass parameters only to override them.
146
-
147
- ## Email code sign-in
148
-
149
- With `auth.emailOTP` enabled the app can sign a person in with a code emailed to them. Unlike a magic link, the code is typed into the tab they started from — so it survives corporate mail security that pre-fetches links (and consumes the single-use link token), and it works when the email is read on another device.
150
-
151
- Two actions drive it:
152
-
153
- - [`EmailOtpSend`](/EmailOtpSend) sends the code to an email address.
154
- - [`EmailOtpVerify`](/EmailOtpVerify) signs the person in with the code they typed.
155
-
156
- `EmailOtpVerify` lands the user through the same three sources as `Login`: the `callbackUrl` param, then the `?callbackUrl=` query, then the app's home page. `callbackUrl: false` verifies without navigating — it is a plain JSON sign-in with no redirect hop, so staying put is valid here.
157
-
158
- ### With magic link, one email carries both
159
-
160
- When `auth.magicLink` is enabled alongside `auth.emailOTP`, the magic-link email also carries the code, so one email serves both paths. Keep using `Login` with `magicLink: true` to send it — no change is needed — and offer `EmailOtpVerify` on the same page for people whose link does not work. `EmailOtpSend` is then only needed for a code-only page, where no link is offered at all.
161
-
162
- ###### A sign-in page offering a code:
163
- ```yaml
164
- id: email-code-login
165
- type: Box
166
- blocks:
167
- - id: email
168
- type: TextInput
169
- required: true
170
- properties:
171
- title: Email
172
- - id: send_code
173
- type: Button
174
- properties:
175
- title: Send code
176
- events:
177
- onClick:
178
- - id: validate
179
- type: Validate
180
- params:
181
- regex: ^email$
182
- - id: send
183
- type: EmailOtpSend
184
- params:
185
- email:
186
- _state: email
187
- - id: sent
188
- type: DisplayMessage
189
- params:
190
- content: Check your email for the sign-in code.
191
- - id: otp
192
- type: TextInput
193
- properties:
194
- title: Sign-in code
195
- - id: sign_in
196
- type: Button
197
- properties:
198
- title: Sign in
199
- events:
200
- onClick:
201
- - id: verify
202
- type: EmailOtpVerify
203
- params:
204
- email:
205
- _state: email
206
- otp:
207
- _state: otp
208
- ```
209
-
210
- An expired, mistyped or already-used code is the auth server rejecting the attempt, not an app fault: the action throws a `UserError`, so `onClick` `catch` actions run and the message displays, but nothing is reported to the server.
211
-
212
- ## SMS sign-in
213
-
214
- `PhoneNumberVerify` completes a sign-in with an SMS code, and lands the user through the same three sources as `Login`: the `callbackUrl` param, then the `?callbackUrl=` query, then the app's home page. `callbackUrl: false` verifies without navigating.
215
-
216
- Two modes are exempt, because neither ends with the user arriving somewhere new:
217
-
218
- - `disableSession: true` creates no session to arrive with.
219
- - `updatePhoneNumber: true` is a signed-in user confirming a new number. They already had a session, and the confirmation usually runs in a modal a navigation would yank them out of.
220
-
221
- ### Carrying the destination to a separate SMS form
222
-
223
- The `?callbackUrl=` query is read from the page the action runs on, and the unauthenticated bounce puts it on `authPages.signIn`. If your SMS form lives on its own page, the link that gets the user there has to carry the parameter, or the destination falls back to the home page:
224
-
225
- ```yaml
226
- - id: to_phone_login
227
- type: Link
228
- params:
229
- pageId: phone-login
230
- urlQuery:
231
- _if:
232
- test:
233
- _eq:
234
- - _url_query: callbackUrl
235
- - null
236
- then: null
237
- else:
238
- callbackUrl:
239
- _url_query: callbackUrl
240
- ```
241
-
242
- The `_if` is what keeps a user who reached the sign-in page directly from being sent to `/phone-login?callbackUrl=null` — `urlQuery` serialises a null value rather than dropping the key.
243
-
244
94
  ## Logout
245
95
 
246
96
  When the `Logout` action is called, the user data and authorization cookies are cleared by the app.
247
97
 
248
- The `callbackUrl` parameter of the Logout action specifies where the user lands after logout is complete. Unlike the `Login` action it has no default and does not read the `?callbackUrl=` query: with no `callbackUrl` the page is reloaded and the server re-applies the page's auth rules, which sends a signed-out user off a protected page to the sign-in page.
98
+ The `callbackUrl` parameters of the Logout action specify where the user is redirected after logout is complete. If `callbackUrl` parameters are not set, the user will return to the page from which the action was called.
249
99
 
250
100
  The parameters are:
251
101
  - `callbackUrl: object`:
252
- - `home: boolean`: Redirect to the home page after the logout flow is complete.
253
- - `pageId: string`: The pageId of the page to redirect to after the logout flow is complete.
254
- - `url: string`: The URL to redirect to after the logout flow is complete. An absolute URL is not `basePath`-prefixed, so it can be an external logout landing page.
255
- - `urlQuery: object`: The urlQuery to set for the page the user is redirected to after logout.
102
+ - `home: boolean`: Redirect to the home page after the login flow is complete.
103
+ - `pageId: string`: The pageId of the page to redirect to after the login flow is complete.
104
+ - `url: string`: The URL to redirect to after the login flow is complete.
105
+ - `urlQuery: object`: The urlQuery to set for the page the user is redirected to after login.
256
106
  - `redirect: boolean`: If set to `false` the user session will be cleared, but the page will not be reloaded.
257
107
 
258
108
 
@@ -29,11 +29,3 @@ The Login and Logout actions are used to start the login and logout processes.
29
29
  ## \_user operator
30
30
 
31
31
  The `_user` operator can be used to access data in the user object received from the identity provider. The OpenID Connect standard claims (fields like `name` or `email`) are mapped to the user object by default and addition fields can be configured using the `userFields` configuration option.
32
-
33
- ### `two_factor_enrolled`
34
-
35
- `_user: two_factor_enrolled` is `true` when the caller holds a factor that satisfies [`auth.twoFactor.required`](/two-factor) — a TOTP enrolment **or** a registered passkey.
36
-
37
- It is a fact about the **user**, not the session: it does not assert that a factor was presented on this sign-in, only that the user has one on file. (The name is imperfect — a passkey is not literally a second factor. The field means precisely "holds a factor that satisfies `auth.twoFactor.required`", which a passkey does on its own.)
38
-
39
- It is present only on session-resolved callers. The API strategy and the injected callers used in dev and e2e carry no session and so do not carry this field.