Developer Docs - Mobile Docs - Helix (Lava Applications)
C20.0M20.0
Helix lets you build dynamic, interactive screens in the mobile app without writing a single line of C#. It is built on Rock's Lava Applications: an endpoint's Code Template emits XAML instead of HTML, the app swaps that XAML into the live page, and the person never leaves the screen they were on. Helix needs Rock 20.0 or later on the server and version 20.0 or later of the app.
If you have used HTMX on the web, this will feel immediately familiar. Helix is Rock's HTMX-based approach, and the mobile vocabulary is a deliberate port of it. If you have used the mobile Content block's Callbacks, you already know most of the idea: Helix is that same swap loop, generalized so any element can start a request and any named element on the page can receive the result. Read Writing Fragments before you write your first endpoint.
Your first Helix screen
Three pieces: an element to receive the content, an element to go get it, and an endpoint to serve it.
On the page. A layout to receive the content, and a button that fetches it:
The endpoint. A GET endpoint with the slug my-groups, in an application with the slug group-toolbox. Its Code Template is ordinary Lava that happens to emit XAML instead of HTML (25 here being whichever group type you care about):
{% assign memberships = CurrentPerson | Groups:'25' %}
{% for membership in memberships %}
{% else %}
{% endfor %}
Key concepts
All Lava runs on the server. The app receives the rendered output, so a fragment is a snapshot of the moment it was served. See Writing Fragments.
One request, one target. A response has a single root element and lands in one place. There are no out-of-band swaps and no response content selection.
Setting a verb wires the interaction for you. You do not need Command="{Binding ...}" plumbing. The moment you put Hx.Get on a Button, its Clicked is wired. Put it on anything else and it gets a tap gesture.
Targeting is by id, not by selector. HTMX aims at the DOM with CSS selectors. Helix aims at an element you have given an Hx.Id. Ids work across the whole page, which is what makes it possible for one block to update an element inside a different block.
Vocabulary
These terms come up constantly in the rest of these docs.
Routes
Mobile uses the same ^ shorthand web does.
Any of them may carry a query string, and query string values stay in the URL for every verb.
Request headers
Every Helix request identifies itself as the app, with X-Helix-Client: RockMobile and the app version in X-Helix-Shell-Version. It also carries the signed-in person's credentials, so CurrentPerson resolves and your Execute security verbs are enforced exactly as they are for a browser. Attribute Reference lists every header.
To serve both a browser and the app from one endpoint, branch on the ClientType merge field rather than reading the header yourself. It is Mobile for the app and Web for everything else:
{% if ClientType == 'Mobile' %}
{% else %}
Hello from the browser
{% endif %}
ClientType is a rendering hint, never an authorization input. It is derived from a header that any caller can send, so branch presentation on it and never gate data access on it. See Security.
In this section