Agent Attributes
Custom markup patterns that help AI agents understand actions and intentions
While semantic HTML, ARIA, and structured data provide the foundation for BiModal Design, they don't always convey intent—what users (and agents) are trying to accomplish on your site. Agent attributes are custom data-* attributes and naming conventions that explicitly signal actions, purposes, and key information to AI agents.
Think of agent attributes as helpful signs on a highway. Semantic HTML provides the road structure, but agent attributes tell drivers "Exit here for gas" or "Next rest stop: 50 miles." They guide agents to complete tasks efficiently.
Why Agent Attributes Matter
Without Agent Attributes
Agent sees a button labeled "Continue" but doesn't know:
- • Is this a checkout button?
- • Does it submit a form?
- • Will it charge a credit card?
- • What page comes next?
→ Agent hesitates or guesses incorrectly
With Agent Attributes
Agent sees explicit metadata:
- •
data-action="checkout" - •
data-intent="purchase" - •
data-requires-payment="true" - •
aria-label="Proceed to payment"
→ Agent acts confidently
Core Agent Attribute Patterns
data-action
Identifies the primary action an element performs. Helps agents understand what clicking a button or submitting a form will do.
Common Values:
data-action="search"data-action="submit"data-action="purchase"data-action="subscribe"data-action="login"data-action="logout"data-action="add-to-cart"data-action="checkout"data-action="download"data-action="contact"data-action="book"data-action="cancel"<!-- Search form -->
<form
action="/search"
method="GET"
data-action="search"
>
<input type="search" name="q" placeholder="Search products..." />
<button type="submit">Search</button>
</form>
<!-- Purchase button -->
<button
type="submit"
data-action="purchase"
data-requires-payment="true"
>
Complete Purchase
</button>
<!-- Add to cart -->
<button
data-action="add-to-cart"
data-product-id="12345"
>
Add to Cart
</button>data-intent
Describes the user's goal or intention when interacting with an element. More abstract than data-action—focuses on why rather than what.
Common Values:
data-intent="navigate"data-intent="transact"data-intent="inform"data-intent="communicate"data-intent="authenticate"data-intent="configure"<!-- Checkout flow -->
<form
action="/checkout"
method="POST"
data-action="checkout"
data-intent="transact"
data-requires-payment="true"
>
<!-- Form fields -->
</form>
<!-- Contact form -->
<form
action="/contact"
method="POST"
data-action="contact"
data-intent="communicate"
>
<!-- Form fields -->
</form>
<!-- Login form -->
<form
action="/login"
method="POST"
data-action="login"
data-intent="authenticate"
>
<!-- Form fields -->
</form>data-entity-type
Identifies the type of content or data an element represents. Complements Schema.org but provides a simpler, more accessible format for agents to parse.
<!-- Product card -->
<article
data-entity-type="product"
data-product-id="12345"
itemScope
itemType="https://schema.org/Product"
>
<h2 data-field="name">Wireless Headphones</h2>
<p data-field="price">$299.99</p>
<span data-field="availability">In Stock</span>
</article>
<!-- User profile -->
<section
data-entity-type="user-profile"
data-user-id="user-789"
>
<h1 data-field="name">Jane Doe</h1>
<p data-field="bio">Product designer and developer</p>
</section>
<!-- Event listing -->
<article
data-entity-type="event"
data-event-id="evt-456"
>
<h2 data-field="name">Web Design Conference</h2>
<time data-field="start-date" datetime="2025-06-15">June 15, 2025</time>
</article>data-field
Marks specific data points that agents need to extract. Works like a simplified version of Schema.org properties but easier to parse programmatically.
<article data-entity-type="product">
<!-- Clear field labels for agents -->
<h1 data-field="name">Premium Headphones</h1>
<p data-field="description">Noise-canceling wireless headphones</p>
<div data-field="price">
<span data-currency="USD">$</span>
<span data-amount="299.99">299.99</span>
</div>
<div data-field="availability">
<span data-status="in-stock">In Stock</span>
</div>
<div data-field="rating">
<span data-value="4.5">4.5</span> / 5
(<span data-field="review-count">142</span> reviews)
</div>
<button
data-action="add-to-cart"
data-product-id="12345"
>
Add to Cart
</button>
</article>💡 Pro Tip: Use data-field alongside Schema.org structured data. Schema.org provides formal semantics, while data-field attributes make it easier for agents to extract specific values programmatically.
data-nav-priority
Hints at the importance of navigation links, helping agents prioritize which pages to explore or recommend to users.
<nav aria-label="Main navigation">
<ul>
<li>
<a href="/" data-nav-priority="high">Home</a>
</li>
<li>
<a href="/products" data-nav-priority="high">Products</a>
</li>
<li>
<a href="/about" data-nav-priority="medium">About</a>
</li>
<li>
<a href="/blog" data-nav-priority="medium">Blog</a>
</li>
<li>
<a href="/terms" data-nav-priority="low">Terms</a>
</li>
</ul>
</nav>data-requires-auth
Indicates whether an action requires authentication. Prevents agents from attempting restricted actions when the user isn't logged in.
<!-- Protected action -->
<button
data-action="checkout"
data-requires-auth="true"
data-auth-redirect="/login"
>
Proceed to Checkout
</button>
<!-- Public action -->
<button
data-action="add-to-cart"
data-requires-auth="false"
>
Add to Cart
</button>
<!-- Account settings link -->
<a
href="/account/settings"
data-requires-auth="true"
data-nav-priority="medium"
>
Account Settings
</a>Real-World Implementation Examples
E-commerce Checkout Flow
<!-- Step 1: Cart Review -->
<section
data-step="cart-review"
data-step-number="1"
data-step-total="3"
>
<h2>Your Cart</h2>
<div data-entity-type="cart">
<div
data-entity-type="cart-item"
data-product-id="12345"
>
<h3 data-field="name">Wireless Headphones</h3>
<p data-field="price">$299.99</p>
<input
type="number"
data-field="quantity"
value="1"
/>
</div>
<div data-field="cart-total">
Total: <span data-amount="299.99">$299.99</span>
</div>
</div>
<button
data-action="continue"
data-next-step="shipping"
>
Continue to Shipping
</button>
</section>
<!-- Step 2: Shipping -->
<section
data-step="shipping"
data-step-number="2"
data-step-total="3"
hidden
>
<h2>Shipping Information</h2>
<form
data-action="save-shipping"
data-intent="configure"
>
<input
type="text"
name="address"
data-field="shipping-address"
required
/>
<!-- More fields -->
<button
type="submit"
data-action="continue"
data-next-step="payment"
>
Continue to Payment
</button>
</form>
</section>
<!-- Step 3: Payment -->
<section
data-step="payment"
data-step-number="3"
data-step-total="3"
hidden
>
<h2>Payment</h2>
<form
action="/checkout/complete"
method="POST"
data-action="checkout"
data-intent="transact"
data-requires-payment="true"
data-requires-auth="true"
>
<!-- Payment fields -->
<button
type="submit"
data-action="purchase"
data-final-step="true"
>
Complete Purchase
</button>
</form>
</section>Multi-Step Registration Form
<form
action="/register"
method="POST"
data-action="register"
data-intent="authenticate"
data-multi-step="true"
data-total-steps="3"
>
<!-- Step indicator -->
<div
role="progressbar"
aria-valuenow="1"
aria-valuemin="1"
aria-valuemax="3"
data-current-step="1"
>
Step 1 of 3
</div>
<!-- Step 1: Basic Info -->
<fieldset
data-step="basic-info"
data-step-number="1"
>
<legend>Basic Information</legend>
<input
type="email"
name="email"
data-field="email"
required
/>
<input
type="password"
name="password"
data-field="password"
required
/>
<button
type="button"
data-action="next-step"
data-next-step="2"
>
Next
</button>
</fieldset>
<!-- Step 2: Profile -->
<fieldset
data-step="profile"
data-step-number="2"
hidden
>
<legend>Profile Information</legend>
<input
type="text"
name="name"
data-field="name"
required
/>
<button
type="button"
data-action="prev-step"
data-prev-step="1"
>
Back
</button>
<button
type="button"
data-action="next-step"
data-next-step="3"
>
Next
</button>
</fieldset>
<!-- Step 3: Preferences -->
<fieldset
data-step="preferences"
data-step-number="3"
hidden
>
<legend>Preferences</legend>
<!-- Preference fields -->
<button
type="button"
data-action="prev-step"
data-prev-step="2"
>
Back
</button>
<button
type="submit"
data-action="submit"
data-final-step="true"
>
Complete Registration
</button>
</fieldset>
</form>Search Interface
<!-- Search form -->
<form
action="/search"
method="GET"
role="search"
data-action="search"
data-intent="inform"
>
<input
type="search"
name="q"
placeholder="Search products..."
data-field="search-query"
aria-label="Search products"
/>
<button
type="submit"
data-action="search"
>
Search
</button>
</form>
<!-- Search results -->
<section
data-entity-type="search-results"
data-query="headphones"
data-result-count="24"
aria-label="Search results"
>
<h2>
<span data-field="result-count">24</span> results for
"<span data-field="query">headphones</span>"
</h2>
<!-- Individual results -->
<article
data-entity-type="product"
data-search-result="true"
data-result-position="1"
>
<h3 data-field="name">Wireless Headphones</h3>
<p data-field="price">$299.99</p>
</article>
<!-- More results -->
<!-- Pagination -->
<nav
aria-label="Search pagination"
data-entity-type="pagination"
>
<a
href="/search?q=headphones&page=1"
aria-current="page"
data-page="1"
>
1
</a>
<a
href="/search?q=headphones&page=2"
data-page="2"
>
2
</a>
</nav>
</section>Testing Agent Attributes
To validate that your agent attributes are working correctly, test with agent simulators and extraction tools:
1. The Curl Test
Verify that your data attributes appear in the HTML source:
curl -s https://yoursite.com/product | grep "data-action\|data-field\|data-entity"2. Browser DevTools
Inspect elements to see all data attributes. Use the Elements panel to verify attribute values are correct and complete.
3. JavaScript Extraction Test
Test programmatic extraction of your marked-up data:
// Extract all products
const products = document.querySelectorAll('[data-entity-type="product"]');
products.forEach(product => {
const name = product.querySelector('[data-field="name"]')?.textContent;
const price = product.querySelector('[data-field="price"]')?.textContent;
console.log({ name, price });
});
// Find all transactional actions
const actions = document.querySelectorAll('[data-intent="transact"]');
console.log('Transactional actions:', actions.length);4. Agent Simulation
Ask an AI agent (like Claude or GPT-4) to browse your site and complete a task. See if it can find and use the marked-up actions correctly.
Best Practices
✓ DO
- • Use semantic
data-*attributes that describe meaning, not implementation - • Keep attribute values consistent across your site (use "search" not "find"/"lookup")
- • Combine agent attributes with semantic HTML and ARIA
- • Mark all transactional actions with
data-requires-payment - • Use
data-fieldto make data extraction deterministic - • Document your agent attribute conventions in a style guide
- • Test with actual agent simulators, not just human review
✗ DON'T
- • Use agent attributes as a substitute for semantic HTML
- • Make attributes too granular or too generic
- • Include implementation details in attribute values (e.g.,
data-action="POST-to-api") - • Change attribute conventions frequently—consistency is critical
- • Forget to mark dangerous actions (purchases, deletions)
- • Assume agents will "figure it out" without explicit markup
Agent Attribute Quick Reference
Action & Intent
- data-action
- data-intent
- data-requires-auth
- data-requires-payment
- data-final-step
Entity & Fields
- data-entity-type
- data-field
- data-product-id
- data-user-id
- data-event-id
Navigation
- data-nav-priority
- data-next-step
- data-prev-step
- data-step-number
- data-step-total
Data Extraction
- data-amount
- data-currency
- data-status
- data-result-count
- data-search-result
You've Mastered BiModal Design!
You now have the complete toolkit for building websites that serve both humans and AI agents. You've learned semantic HTML, ARIA, structured data, and agent-specific attributes. Time to put it all into practice.