Lowdefy
v3.17.2/Concepts/Custom Code/

Custom Code

SECURITY WARNING: Custom code executes JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Since Lowdefy doesn't validate your custom code, make sure that you only load trusted code.

Lowdefy runs as a single page web app (SPA). It is possible to extend the functionality of a Lowdefy app by loading custom code (HTML, CSS and JavaScript) into the HTML head and body to of the default index.html page.

The content loaded into the head and body tag can be any valid HTML, most often script tags are loaded to register a new JsAction or _js operator. However, third party code can also be imported, for example Google Analytics, Intercom, etc. Be sure to only load trusted code into your app, as this code will be able to execute JavaScript on all pages of your Lowdefy app, which could expose you app or data to security vulnerabilities. Your own code can easily be hosted from the Lowdefy public folder.

Warning: Lowdefy implements the Ant design UI component framework for app layout and most blocks, thus the default Ant Design CSS is loaded for all Lowdefy apps. Take caution not to unintentionally overwrite existing style settings and classes which can result in a degraded user experience.

Schema to load custom code

  • app.html.appendHead: string: Any valid HTML content can be loaded just before the </head> tag of the Lowdefy app index.html file.
  • app.html.appendBody: string: Any valid HTML content can be loaded just before the </body> tag of the Lowdefy app index.html file.

Most often it is convenient to abstract this HTML out to a separate file using the _ref operator.

Warning: Code imported using appendHead or appendBody will be loaded, and can execute JavaScript on every page of your Lowdefy app.

Examples

Loading third party code snippet like Google Analytics:

To add Google Analytics to a Lowdefy app, the lowdefy.yaml can be setup with:

name: google-analytics-example
lowdefy: 3.17.2
# ...
app:
  html:
    appendHead: |
      <!-- Google Analytics -->
      <script>
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

      ga('create', 'UA-XXXXX-Y', 'auto');
      ga('send', 'pageview');
      </script>
      <!-- End Google Analytics -->
# ...
Load, register and trigger a custom JsAction from code in the app public folder:

This example fetches a list of Todos from {JSON}placeholder, and updates state.

  1. First, add the JavaScript code to the public folder and resister the JsAction:
// /public/fetchTodos.js
function async fetchTodos(context, numItems, skip) {
  const data = await fetch('https://jsonplaceholder.typicode.com/todos');
  const todos = await data.json();
  return todos.slice(skip, skip + numItems);
}
// Register the JsAction for the Lowdefy app to use.
window.lowdefy.registerJsAction('fetchTodos', fetchTodos);
  1. Import the JavaScript as a module into the page:
<!-- /header_modules.html -->
<script type="module" src="/public/fetchTodos.js"></script>
  1. Set load the custom code into the app header and trigger the action on page load:
# /lowdefy.yaml
name: json-todos
lowdefy: 3.17.2
app:
  html:
    appendHead:
      _ref: header_modules.html # Load the custom HTML into the header.
pages:
  - id: todos
    type: PageHeaderMenu
    events:
      onEnter:
        - id: get_todos
          type: JsAction
          params:
            name: fetchTodos # Trigger the custom JavaScript action.
            args:
              - 10   # numItems
              - 0    # skip
        - id: set_todos
          type: SetState
          params:
            todos:
              # Set the response of the get_todos action to state.
              _actions: get_todos.response
    # ...

Loading and registering a _js operator

Similar to the loading custom JavaScript actions, custom JavaScript operators can also be loaded. In order for the Lowdefy app engine to execute a custom JavaScript operator, the JavaScript code for the operator must be loaded onto the page and registered using the registerJsOperator method available on the browser window object by calling window.lowdefy.registerJsOperator(name: string, action: function).

All _js functions must be synchronous.

Examples

Load, register and use a custom _js operator from code in the app public folder:

This example uses a _js operator to remove all duplicates from a list of names.

  1. First, add the JavaScript code to the public folder and resister the _js operator:
// /public/foo_operators.js
function removeDuplicates(items) {
  return [ ...new Set(items) ];
}
// Register the removeDuplicates function as a _js.deduplicate operator.
window.lowdefy.registerJsOperator('deduplicate', removeDuplicates);
  1. Import the JavaScript as a module into the page:
<!-- /header.html -->
<script type="module" src="/public/foo_operators.js"></script>
  1. Set load the custom code into the app header and use the new operator on the page:
# /lowdefy.yaml
name: operator-example
lowdefy: 3.17.2
app:
  html:
    appendHead:
      _ref: header.html # Load the custom HTML into the header.
pages:
  - id: some_names
    type: PageHeaderMenu
    blocks:
      - id: names
        type: ButtonSelector
        properties:
          title: Select your new friend
          options:
          # use the removeDuplicates function and pass a list of names as a function argument
            _js.deduplicate:
              - - Anne
                - Sam
                - Joe
                - Micheal
                - Sam
                - Steven
                - Anne
                - Pepper
    # ...

Custom code provides an easy way to extent the logic functionality of Lowdefy apps. However, to extend the UI capabilities beyond the existing features provided by the default Lowdefy blocks, custom blocks can be loaded onto apps.