Website Element Markup
Site developers use data-ai-* markup to give important elements stable names, link them to instructions, and make them exact targets for highlighting or permitted actions. Start with one visitor flow and mark only the elements that help complete it.
What Markup Changes
The data-ai-* markup helps link questions like “what is this button?”, “how to fill out this field?”, “why is this tariff not available?” to a specific page element. The visitor selects an element on the site through the widget, and the widget attaches the context of the selected element to the message.
Markup describes page elements specifically. Context for the current page, open card, project, order, or another business entity is passed separately through the widget Public API: contextProvider, SenlerWidget.setPageContext(items), and one-time contextItems for the next message. In the widget chat, all of this appears as context chips next to the message.
Without explicit markup, the widget still uses semantic HTML, form labels, and ARIA attributes. data-ai-* complements accessible markup with a stable key, exact name, and knowledge-base link.
Mark up the main site page, not elements inside the widget iframe. Internal chat markers are used by the Senler interface and are not targets for highlighting or actions on the site page.
Prepare the First Scenario
- Connect a Widget channel and add the generated code to the site.
- Enable Element selection (
features.element_selection: true). - Test an ordinary button or field with a clear HTML label.
- Add
data-ai-*to elements that need a stable documentation or action link.
For a large site, begin with routes where users get lost most often: signup, payment, connection, search, a request form, or profile settings. Do not mark decorative containers or the entire DOM for possible future use.
Verify the Visitor Flow
- The visitor clicks "Select element" in the widget.
- The widget enables selection mode on the page.
- The visitor clicks on a site element.
- The widget reads the element name, page section, context key, and search hint if they are set.
- Before sending the message, the user sees the selected element as a context chip.
- The element context is sent to the agent with the question and helps retrieve the exact article.
- If the user separately requests an action, the agent can address the element only by an exact key and only when the page allows that action.
Selecting an element never clicks or changes it. The visitor's click in selection mode only creates a context chip.
Identify Selectable Elements
These are considered selectable:
- elements with
data-ai-context-id,data-ai-label,data-ai-kind,data-ai-action,data-ai-kb-doc-id,data-ai-kb-query,data-ai-reveals-context-id, ordata-ai-reveal-action; - standard elements
button,a,input,textarea,select,label,summary; - text and structural elements
article,section,li,p,h1-h6; - elements with the roles
button,link,menuitem,tab,checkbox,combobox,radio,option,searchbox, ortextbox; - elements with
aria-labeloraria-labelledby.
data-ai-section by itself only describes the section. If you need to select the entire block, add data-ai-label, data-ai-kind or data-ai-context-id to it.
The selected-element label comes from the first available source: data-ai-label, aria-labelledby, an associated or nearby label, aria-label, title, placeholder, and finally visible text. Fix ordinary HTML/ARIA labeling first. Use data-ai-label when the interface label is not clear outside its page context.
For repeated rows and cards, always provide data-ai-entity-type and data-ai-entity-id as a pair. The shared data-ai-context-id describes the kind of element, such as a lead row, while the entity pair identifies one specific lead. Attributes are read from the selected element itself and are not inherited from its parent: repeat the entity pair on a separately selectable button inside a repeated card. If several visible elements use the same context key, an action without this pair is ambiguous and is not performed. Providing only one of the two attributes is also invalid.
Add the Required Attributes
All values are strings. The limits in this table match the amount of data that the widget retains in selected-element context.
| Attribute | Purpose | Limit / example |
|---|---|---|
data-ai-area | Stable name of a large page area. | Up to 80 characters; for example header, navigation, content, form, or modal. |
data-ai-section | Semantic section within the page. | Up to 120 characters; for example catalog, checkout-payment, or profile-settings. |
data-ai-label | Human-readable element name that makes sense outside the page. | Up to 180 characters. |
data-ai-kind | Element type in product terminology. | Up to 80 characters; for example primary-action, form-field, or product-card. |
data-ai-action | Meaning of the element's action. | Up to 120 characters; for example cart.add or checkout.pay. It does not authorize execution. |
data-ai-context-id | Stable documentation link and exact action target. | Up to 120 characters; use a lowercase dot-separated key such as checkout.payment.submit. |
data-ai-kb-doc-id | Direct reference to a known stable knowledge-base document ID. | Up to 80 characters. Do not use it as the primary link for re-imported MD documentation. |
data-ai-kb-query | Fallback knowledge-base search phrase. | Up to 240 characters; for example how to pay for an order. |
data-ai-entity-type | Type of a concrete entity in a repeated list. | Up to 80 characters; for example product, plan, or order. |
data-ai-entity-id | ID of the concrete entity. | Up to 120 characters; for example a SKU or public plan ID. Always use it with data-ai-entity-type. |
data-ai-reveals-context-id | Context key or key root revealed by this trigger. | One or more space-separated keys; up to 2,000 characters in total. |
data-ai-reveal-action | How to reveal a hidden target. | click, hover, or focus; defaults to click. |
data-ai-value | Current custom-select value or an option value used by selection actions. | For example off. Never place secrets here; this is the selection value, not its label. |
For actions on the host page, the widget compares data-ai-context-id, data-ai-entity-type, and data-ai-entity-id with case and punctuation preserved: Catalog.save and catalog.save, or item-a and item_a, are different keys. Pass them unchanged to commands and documentation. A data-ai-reveals-context-id value must match the target key or its root: catalog reveals catalog.save, but not catalogue.save or Catalog.save.
data-ai-action describes the element's purpose but does not replace site-side authentication, authorization, or confirmation. data-ai-reveals-context-id and data-ai-reveal-action are only needed for custom menus and panels; the widget detects standard aria-controls, popovertarget, commandfor, and <details>/<summary> relationships itself.
For data-ai-context-id to be extracted from Markdown during knowledge-base upload, use no more than 120 characters and at least two non-empty dot-separated parts. Parts may contain Latin letters, digits, _, and -. For example, checkout.payment.submit is valid; payment, checkout..submit, and a key containing a space are not.
Do not put passwords, tokens, email, phone, personal data, or secret service IDs in attributes. Attribute values and the selected element's visible text are sent to the agent with the question.
Custom select controls
A native HTML select works without extra option markup. For a button with a popover list, place data-ai-context-id on the button and provide role="combobox", aria-expanded, aria-controls referencing the panel ID, and data-ai-value containing the current value. ArrowDown must open a panel with role="listbox". Options need role="option", data-ai-value, and aria-selected; use aria-disabled="true" for unavailable options.
After selection, update the button value or the option's aria-selected. The widget checks this change before reporting success. It first matches value/data-ai-value, then the label; selection is rejected when several options have the same label. If a long explanation accompanies the option name, provide the short name separately in its data-ai-label.
Check Markup Quality
- The key is stable and does not depend on button text, interface language, or a specific user ID.
- The visible article text describes the action in human language instead of repeating the context key.
- The element can be found in the current page markup without navigating to another page.
- A button or field has a label, role, or clear
data-ai-label. - Every repeated card has the same semantic
data-ai-context-idand its own completedata-ai-entity-type/data-ai-entity-idpair. - For dangerous actions such as deletion or payment, the site documentation separately explains consequences, limitations, and confirmation.
Scenarios to Start With
- Online store: the user asks "how do I pay for the order?", the payment article is found and the button with
data-ai-context-id="checkout.payment.submit"is shown. - SaaS form: the user does not understand where to paste a token, and the field's
data-ai-context-idfrom documentation helps highlight the required input. - Account area: the user asks about notification settings, first a menu item on the current page is shown, then the next step after navigation is explained.
In all scenarios, article text stays human: "click the payment button", "enter the token", "open notifications". The context key lives in the span attribute and does not get in the way of reading the instruction.
Example: product card
<main data-ai-area="content" data-ai-section="catalog">
<article
data-ai-label="Product: Alpha Sneakers"
data-ai-kind="product-card"
data-ai-context-id="catalog.product-card"
data-ai-kb-query="how to choose product and size"
data-ai-entity-type="product"
data-ai-entity-id="sku-alpha-42"
>
<h2>Alpha Sneakers</h2>
<p>Sizes 39-44</p>
<button
data-ai-label="Add Alpha Sneakers to cart"
data-ai-kind="primary-action"
data-ai-action="cart.add"
data-ai-context-id="cart.add"
data-ai-kb-query="how to add a product to cart"
data-ai-entity-type="product"
data-ai-entity-id="sku-alpha-42"
>
Add to cart
</button>
</article>
</main>
Example: tariffs and payment
<section data-ai-area="content" data-ai-section="pricing">
<div
data-ai-label="Pro plan"
data-ai-kind="plan-card"
data-ai-context-id="pricing.plan.pro"
data-ai-kb-query="what is included in Pro plan"
data-ai-entity-type="plan"
data-ai-entity-id="pro"
>
<h3>Pro</h3>
<button
data-ai-label="Choose Pro plan"
data-ai-kind="primary-action"
data-ai-action="plan.choose"
data-ai-context-id="pricing.plan.choose"
data-ai-kb-query="how to choose and pay for a plan"
data-ai-entity-type="plan"
data-ai-entity-id="pro"
>
Choose
</button>
</div>
</section>
Example: form
<form data-ai-area="form" data-ai-section="checkout-delivery">
<label for="delivery-city">Delivery city</label>
<input
id="delivery-city"
name="city"
data-ai-label="Delivery city"
data-ai-kind="form-field"
data-ai-context-id="checkout.delivery.city"
data-ai-kb-query="how to enter delivery city"
/>
<button
data-ai-label="Continue checkout"
data-ai-kind="primary-action"
data-ai-action="checkout.continue"
data-ai-context-id="checkout.continue"
data-ai-kb-query="how to continue checkout"
>
Continue
</button>
</form>
Link to knowledge base
If the site has data-ai-context-id="checkout.delivery.city", add the same key to the text of the knowledge base file:
<span data-ai-context-id="checkout.delivery.city">Enter the delivery city</span>.
When the user selects a field and asks a question, Senler AI uses context_id for knowledge base search. Documents with matching context keys receive strong priority.
If the exact key is not available, data-ai-kb-query helps: it is added to the search query along with label, text and section.
If the documentation is uploaded as a Markdown folder or ZIP archive, do not rely solely on visible text without markup. During upload, inline data-ai-context-id values are saved as “Context keys for elements”. File structure and key processing are covered in Linking Markdown Documentation to Website Elements.
What to Do After Markup
First link the keys to Markdown documentation, then test element selection and every allowed action. data-ai-label and data-ai-kb-query help explanations and search, but an exact action requires data-ai-context-id. If the element is absent from the current page, the action must not choose a similar target by text.
Diagnostics
If the element is not selected:
- check whether "Element selection" is enabled in widget settings;
- check that the user clicked “Select element” in the widget;
- add
data-ai-labelordata-ai-context-idto the element; - do not mark only the parent container via
data-ai-sectionif you need to select the container itself.
If the required instructions are not found:
- check that
data-ai-context-idmatches the context key of the knowledge base file; - add
data-ai-kb-querywith a natural phrase; - check that the document is active and connected to the required agent;
- make sure that the question is sent with the selected element block in the widget.