Diese Seite erscheint auf Englisch und Ukrainisch; unten steht die englische Fassung.
A form the assistant fills in, step by step
For developers, in code: the «New customer» form on our page for apps, marked up for the assistant line by line — labels, options, the one Save marked data-sa-commit, private fields, hints, lists — and the panel switches that decide what it may read and press.
On the page for apps there is a small form called «New customer». Ask the assistant «Fill in the form: Olena Koval, olena@example.com, Pro plan, call in the afternoon» and it types the name and the email, picks Pro, writes the note — and asks before it presses Save. This page shows the markup behind that. There is very little of it.
In the panel: Widget → Page actions (Widget settings). Page actions are part of the Growth plan and above.
The form
<form>
<label>
<span>Name</span>
<input name="name" type="text" />
</label>
<label>
<span>Email</span>
<input name="email" type="email" />
</label>
<label>
<span>Plan</span>
<select name="plan">
<option value="">Choose a plan</option>
<option>Starter</option>
<option>Growth</option>
<option>Pro</option>
</select>
</label>
<label>
<span>Note</span>
<textarea name="note"></textarea>
</label>
<label>
<input name="welcome" type="checkbox" />
<span>Send a welcome email</span>
</label>
<button type="submit" data-sa-commit>Save</button>
</form>
One attribute is ours: data-sa-commit on Save. Everything else is what a screen reader
already reads — and that is the point. The widget names each field by the <label> text written
before it, knows the dropdown’s options by their visible text, and tells a tick-box from a button
by its type.
What happens when the visitor asks
- The widget reads the screen: five fields with their names, whether each is filled, the plan’s options, and a Save marked as the button that commits the form.
- The assistant sends one batch — fill Name, fill Email, choose Pro, fill Note — and the widget applies it at once. The visitor watches the text land in their own form and can correct any of it by hand.
- Save is held. The assistant asks, naming the button, and the widget draws two chips: Yes, press “Save” and No, don’t. The visitor can also answer in their own words or out loud.
- On a yes the widget presses Save, and the assistant says that it pressed it. The form shows its own «Saved» line, as it would for a person.
That is the default policy, Click with confirmation. Consent and commit.
Good practice, control by control
A visible label for every field. Put the field’s name in a <label> before the control, or in
aria-label. The label is the name both sides use: the visitor says «put Pro in the plan field»,
the assistant says «I filled in Email». A placeholder works as a name too, but it is usually an
example («e.g. Olena»), and a field named by its example reads oddly back to the visitor.
Options in the words people say. select matches an option by its visible text — exactly
first, then by containing it — so «Pro» finds «Pro», and «the Pro plan» finds it too. A dropdown
whose options read P-03 leaves the assistant only the code to work with.
One Save, marked. data-sa-commit on the button that commits the form, exactly one per
screen. Under Click with confirmation it is the press the assistant asks about; under Save
automatically it is the press the widget makes once the fields have landed. A switch that saves
itself the moment it moves takes the same attribute, and then it is asked about too.
Harmless buttons, declared. «Add another contact», «Show more fields» change nothing the visitor
cannot see and undo. Mark such a button data-sa-risk="safe" and the assistant presses it in the
same batch as the fills, without asking. Never on Save, Send or Delete.
Private fields, out of reach. data-sa-private on a field — or on a <fieldset> around
several — hides them from reading and from acting, in every mode:
<fieldset data-sa-private>
<legend>Card</legend>
<input name="card" inputmode="numeric" />
<input name="cvc" inputmode="numeric" />
</fieldset>
Passwords, hidden inputs and file inputs are out of reach without any markup.
A hint where the rule is not in the page. Something only you know about a field goes in
data-sa-hint. The assistant reads it beside the field’s name at the moment it decides what to
write; visitors never see it.
<textarea
name="note"
data-sa-hint="For the sales team: when to call and what about, in English."
></textarea>
Validation messages it can quote. Wrap the area where your form shows its errors in
data-sa-read, and «why won’t it save?» is answered with your own message rather than a guess.
A real disabled. Keep the disabled attribute on a Save that cannot be pressed yet. The
assistant reads it, says why if your message is readable, and does not try.
Repeated rows as a list. Contacts, order lines, FAQ entries: declare the list with
data-sa-list, data-sa-row, data-sa-field and data-sa-add, and the assistant addresses
«the second contact’s phone» by position. Lists and variants.
A stable id where the page re-renders. A framework that rebuilds the form on every change keeps
its fields addressable with data-sa-id="email". Marking up controls.
The three switches for this form
On the widget’s Page actions tab:
| Switch | On a public form like this one | In a signed-in app |
|---|---|---|
| Let the agent act on the page | on | on |
| Button clicks | Click with confirmation — fill, then ask | Save automatically, if your users expect Save to happen |
| Can the assistant see what is in the fields | Never — only whether it is filled | Only fields marked data-sa-read, or Every field on the page |
With reading at Never, the assistant still knows which fields are filled, and it can add to a
field without reading it: append joins the new text in the browser, so what the visitor typed
never leaves the page. Reading the screen.
A page that should never be acted on — a checkout, an account deletion — can switch page actions
off for its own load with Shukai.setPageActions(false).
JavaScript API.