Developer Docs - Mobile Docs - Writing Fragments
A fragment is the XAML your endpoint returns. Throughout these docs "fragment" always means the response body, never the page XAML that fired the request.
This page is short on purpose: the rules below are the most common reason a fragment fails to render. The namespace rule in particular applies to any XAML the server sends the shell, so a Lava Application Content block's Initial Template plays by it too.
The rules
One root element. A fragment has exactly one root. If you need to return several cards, wrap them in a layout. HTMX allows sibling nodes for append and prepend; mobile does not.
Lava runs on the server, not on the device. Write as much Lava in your Code Template as you like. The device never evaluates Lava, so what it receives is the rendered result. That has a consequence worth its own section, Where Lava runs, below.
Why you must not declare xmlns
The Hx.* attributes only resolve in the namespace the app sets up for you. If your fragment root declares its own xmlns, it overrides that for the whole fragment. Standard controls still work, so the fragment looks fine at a glance, but every Hx.* attribute stops working and your interactions silently do nothing.
Where Lava runs
Your Code Template is Lava, and it can be as complex as you need. It runs on the server, and the app receives only its output. So this template:
{% if ClientType == 'Mobile' %}
{% else %}
Method: {{ Method }}
{% endif %}
reaches the device as this fragment, with no Lava left in it:
A fragment is therefore a snapshot. That clock shows the time the request was served and stays frozen there until something swaps the fragment again. Nothing in a fragment re-evaluates on its own, so anything that needs to change has to come from another request.
There is no second Lava pass on the device, and the Content block's ProcessLava setting does not apply to Helix fragments.