Product pages tuck their most useful details behind tabs, accordions, "read more" links, hover tooltips and carousels. That keeps the page tidy for people. For AI agents, one question decides whether that works: is the hidden content in the page already, or does it only arrive when someone clicks? Here's the difference, and how to build each pattern so agents can reach what's inside.
In the HTML, or loaded on click
There are two ways to hide content behind a control, and they look identical on screen:
- Present but collapsed. The text for every tab or accordion panel is in the HTML the server sends. CSS or the
hiddenattribute keeps the closed panels out of sight, and pressing the control only changes what's shown. - Loaded on click. The panel is empty until someone presses the control. Then a script fetches the content and inserts it.
The first works for every kind of agent. An assistant such as ChatGPT, Claude or Perplexity reading your HTML without running JavaScript gets the text of every panel, open or closed. A browser agent can read it too, or press the control to reveal it.
The second hides content from any agent that doesn't run JavaScript, and makes browser agents press every control on the page, in the right order, to find what they're after. Many won't. If your delivery times, size guide or ingredients load on click, many agents will simply never see them.
Present but collapsed
- All panel text in the served HTML
- The control only shows or hides it
- Readable with or without JavaScript
Loaded on click
- Empty panels in the served HTML
- A script fetches content when pressed
- Invisible to agents that read HTML
The rule is the same one behind why AI agents can't see your JavaScript-only content: if it matters, put it in the HTML. Collapse it all you like.
Accordions with details and summary
For most accordions, HTML already has the answer. The <details> element creates a disclosure widget that opens and closes without any script, and the <summary> inside it is the label people and agents press.
<details>
<summary>Delivery and returns</summary>
<p>Free delivery over $50. Returns within 30 days.</p>
</details>
Why it works well for agents:
- The content is always in the HTML, because closing the panel only hides it.
- The control is real and named. The browser treats the summary as the control that opens and closes the panel, and its text is the name, so agents know what it opens.
- It needs no JavaScript. Nothing breaks if a script fails to load.
- One open at a time is built in. MDN documents a
nameattribute that groups several<details>elements so only one is open at once, the classic accordion, without scripting.
If you build a custom accordion instead, follow the W3C ARIA Authoring Practices Guide accordion pattern: each header is a real button inside a heading, with aria-expanded saying whether its panel is open and aria-controls pointing at the panel. That gives an agent the same three facts: there's a control, here's its name, and here's whether it's open.
Hidden until found. MDN also describes hidden="until-found", which hides content but lets the browser's find-in-page feature and links to an anchor reveal it. It's useful for long FAQ pages; check browser support before relying on it.
Tabs agents can read
Product tabs ("Description", "Specifications", "Reviews", "Delivery") are a tablist. The ARIA Authoring Practices Guide tabs pattern sets out what each part should say:
- The container has the role
tablist, each tab has the roletab, and each panel has the roletabpanel. - Each tab points to its panel with
aria-controls, and each panel points back to its tab witharia-labelledby. - The active tab has
aria-selected="true"and the others"false".
Browser agents that read the accessibility tree can then see the tabs, which one is selected, and the names of the others. And if every panel's content is in the HTML, agents that read the source get the lot without pressing anything.
A simpler option suits many product pages: no tabs at all for the HTML, just headings and sections, with tabs added as a visual layer by CSS or script. Agents and people without JavaScript get a well-structured page; everyone else gets tabs. Either way, use specific tab names. "Specifications" helps an agent looking for dimensions. "More info" doesn't.
Description Specifications Delivery Real tabs, specific names
Specifications panel: 40 grind settings, 250 g hopper In the HTML while closed
Delivery panel: fetched when pressed Missed by HTML readers
"Read more", tooltips and carousels
The same principle covers the smaller patterns. A full description matters most, because it's what agents compare; see product descriptions AI agents can compare.
| Pattern | What goes wrong | What works |
|---|---|---|
| "Read more" on descriptions | Only the first lines are in the HTML; the rest loads on click | Put the full text in the HTML and clip it with CSS |
| Hover tooltips | The text only exists while a pointer hovers, and agents don't hover | Show it on focus and on press too, or write it into the page |
| Carousels | Only the visible slide is in the HTML, and arrows are unnamed icons | All slides in the HTML, with "Previous slide" and "Next slide" buttons |
| Size or fit notes in a pop-up | The pop-up is built when opened | A link to a size guide page, or the notes in the page |
Tooltips deserve a special word. Many agents never hover, so the safest tooltip is one whose text is in the page anyway, for example as the button's accessible description. Anything a shopper needs to decide, like "Ships in 3 to 5 days" or "Runs small", shouldn't live only in a tooltip. For size and color choices themselves, see size, color and variant pickers AI agents can use.
Collapse it all you like. Just don't make agents click to fetch it.
Give every control a name
Content in the HTML is half the job. Browser agents also need to recognize the control that reveals it. The usual problems:
- Icon-only toggles. A "+" or a chevron with no text. Give it words, or an
aria-labelsuch as "Show delivery details". - Clickable boxes. A
<div>with a click handler instead of a<button>or<summary>. Agents may not know they can press it. - No state. Nothing says whether a panel is open, so an agent presses a toggle and closes the very panel it wanted.
In our study of 255 stores, 58% had buttons or links with no name an agent can read, and 67% had elements that look clickable but aren't real buttons or links. Toggles like these are a common source. See buttons, links and forms agents can use for the full checklist.
- 58% of stores have buttons or links with no readable name
- 67% have clickable things that aren't real buttons or links
What AgentScore checks
AgentScore doesn't open your tabs or accordions, but three checks on your home page cover the groundwork:
- "Content loads without JavaScript" compares the text in the HTML your server sends, including panels that start closed, with the text a browser shows once scripts have run. If less than 70% of the text is in the HTML, it warns, and below 30% it fails. Content that only loads when someone clicks isn't in either measurement, so this check can't see it; you have to look.
- "Clickable things are real buttons and links" flags boxes and list items that show a pointer cursor but aren't buttons or links and have no role or tabindex. A
<summary>and anything inside it is left out, so native accordions never count against you. - "Buttons and links have names" flags visible buttons and links with no text, label, title or image description, such as an icon-only toggle.
These run on the home page only. Your product pages are where most tabs live, so test one yourself. What an AI agent sees when it visits your store shows how.
Where to start
Hidden content checklist
- All panel text in the served HTML, closed or open
- <details> and <summary> for simple accordions
- Tabs with roles and aria-selected, and specific names
- Named toggles that are real buttons
- Full descriptions clipped with CSS, not loaded on "read more"
- Facts only in a hover tooltip
Try it this week: open a product page, view the source and search for a sentence from each tab or accordion panel, without opening any of them first. Any panel you can't find is loaded on click. Ask your developer to render it into the page instead.