# DOM attributes

> All data-review-* attributes used by the Sayproof component, which your CSS rules and scripts can rely on.

Source: /en/reference/dom-attributes/

These attributes are a contract (version 3): within the same version they are not removed and their meanings do not change; new attributes may be added. Write your CSS rules and scripts against these attributes. For usage examples, see [Layout and CSS selectors](/en/customize/css-hooks.md).

## Container configuration

These attributes are added to the container (`data-review-mount`). For a value that is not on the container, the value on the script tag is used. When one of these attributes changes, the component refreshes itself.

| Attribute | Value |
|---|---|
| `data-review-mount` | Marks the element as a review container. A page can have more than one container. |
| `data-review-site-key` | The site key. It is read only from the script tag or from the `Sayproof.mount()` options; a value on the container is ignored, so content added to the page later cannot point the reviews at another channel. |
| `data-review-base` | The Sayproof API address. It is read only from the script tag or from the `Sayproof.mount()` options; a value on the container is ignored, so content added to the page later cannot send what the customer types in the form to another server. |
| `data-review-product` | The product code: a variant or group code |
| `data-review-scope` | `variant` (default) or `group` |
| `data-review-product-name` | The product name. It is read but is not currently used in the display; it is reserved for future use. |
| `data-review-locale` | `tr` or `en`. If it is given neither on the container nor on the script tag, the `<html lang>` value is used, and failing that the channel's language. |
| `data-review-layout` | `list` (default) or `grid` |
| `data-review-style` | `cards` or `sidebar`: the layout. If omitted, the layout chosen for the channel in the panel is used. |
| `data-review-theme` | `warm`, `trust`, `editorial`, `minimal`, `soft`, `bold`, `natural` or `night`: the built-in design. If omitted or not recognised, the design chosen for the channel in the panel is used. |
| `data-review-mode` | `headless`: the script builds no summary, list or sorting; it only runs the review writing flow |
| `data-review-gate` | The CSS selector of the element in which the review writing area is shown. If no element matches, the area is shown inside the container. |
| `data-review-viewer` | `pending`: the signed-in customer's status is awaited; the review writing area is not shown until the answer arrives |

## Container state

| Attribute | Meaning |
|---|---|
| `data-review-ready` | The component is ready; `Sayproof.write(container)` can now open the flow. When the product changes, it is removed until the new content is ready. |
| `data-review-failed` | The reviews could not be loaded; the rest of the page is not affected |

## Root element

| Attribute | Meaning |
|---|---|
| `data-review-root` | The component's root element; the style scope starts at this element |
| `data-review-version` | The contract version (`3`) |
| `data-review-style` | The layout in use: `cards` or `sidebar` |
| `data-review-theme` | The built-in design in use: `warm`, `trust`, `editorial`, `minimal`, `soft`, `bold`, `natural` or `night`; the design's variable values depend on this attribute |
| `data-review-market` | The market the reviews belong to |
| `data-review-product` | The product code whose reviews are shown |
| `data-review-layout` | Also added to the root element: `list` or `grid` |
| `data-review-busy` | A request is in progress |
| `data-review-ssr` | A root element rendered on the server; the script takes it over |
| `data-review-stylesheet` | The `<link>` at the start of the server-rendered HTML; it loads the component's base styles before the script |
| `data-review-state` | The `<script type="application/json">` tag that carries the server response; the script builds the initial display from this data without a network request |
| `data-review-frame` | The layout frame inside the root element; two columns in a wide area in the side panel layout |
| `data-review-aside` | The summary and the review writing area; the left column in the side panel layout |
| `data-review-main` | The AI summary (arrives with v2; currently not drawn), photo strip, filters, toolbar, results line, list and the "More reviews" button |

## Summary

| Attribute | Meaning |
|---|---|
| `data-review-summary` | The summary section |
| `data-review-score`, `data-review-score-detail` | The average rating block and, inside it, the group with the stars, the review count and the verified review count |
| `data-review-average` | The average rating |
| `data-review-stars` | Always five star characters (`★★★★★`). The filled part is shown in the star colour according to the `data-review-fill` value and the rest in the `--review-track` colour; in the summary it fills to the average. The text equivalent is in `aria-label`. |
| `data-review-count` | The number of reviews |
| `data-review-verified-count` | The number of verified reviews; its value is the number itself, and it is shown only when greater than zero |
| `data-review-shared-count` | The number of reviews from other markets shown in the list ("Reviews from other markets: 3"); its value is the number itself. Added only when reviews from other markets are shown; these reviews are not included in the average. **Cannot be hidden.** |
| `data-review-imported-count` | The share of reviews imported from marketplaces ("3 of 4 reviews imported from Trendyol"); its value is the number of imported reviews. Added only when there are imported reviews; these reviews count in the average. **Cannot be hidden.** |
| `data-review-distribution` | The rating breakdown list (`<ol>`, from 5 stars to 1 star) |
| `data-review-star`, `data-review-star-count` | The row of a star level in the breakdown and the number of reviews at that level |
| `data-review-star-filter` | The button in the row; its value is the star level. When clicked, the list is limited to reviews with that rating; clicking again removes the filter. When selected, `aria-pressed="true"`; if there are no reviews at that level, `disabled`. |
| `data-review-star-label`, `data-review-bar`, `data-review-star-total` | The star label on the button (`5★`), the bar and the count |
| `data-review-fill` | The fill of the stars and of a bar, or the position of a scale marker: between 0 and 100, in multiples of 5. On the stars it is the rating's share of 5, rounded to the nearest multiple of 5 (4.3 → 85). The bar of a star level that has reviews is at least 5. |
| `data-review-aspects-group`, `data-review-aspects` | The summary of stepped-scale rating topics (a `<dl>` inside `role="group"`); shown when at least one topic has been rated |
| `data-review-aspect` | A topic in the summary: `<div data-review-aspect="<key>"><dt>topic</dt><dd>scale · names of the ends · nearest step and number of ratings</dd></div>` |
| `data-review-scale`, `data-review-scale-marker` | The line of a stepped scale and the marker on it; the marker's position is in the `data-review-fill` value |
| `data-review-scale-ends` | The names of the steps at the two ends of the scale |
| `data-review-aspect-value` | The text value of the topic: in the summary the nearest step and the number of ratings, in a review the chosen step |
| `data-review-method-statement` | The method statement link. **Cannot be hidden.** |

## AI summary

The review summary card (arrives with v2; currently not drawn) is shown as the first item of `data-review-main`, before the photo strip, when the brand has the review summary on and the product has at least 10 reviews. Filters do not change it. The HTML prepared on the server and the script produce the same structure:

```html
<section data-review-ai-summary>
  <h3 data-review-ai-summary-title>What customers say</h3>
  <p data-review-ai-summary-text>Most buyers say the fit is right. 2 reviews mention that delivery was late.</p>
  <ul data-review-ai-topics aria-label="Main topics">
    <li data-review-ai-topic="fit" data-review-ai-sentiment="positive">Fit · 7<span data-review-sr> · mostly positive</span></li>
    <li data-review-ai-topic="delivery" data-review-ai-sentiment="negative">Delivery · 2<span data-review-sr> · mostly negative</span></li>
  </ul>
  <p data-review-ai-summary-note>Summarised by AI from 10 reviews · 12 October 2026 · <a data-review-ai-summary-link href="…" target="_blank" rel="noopener">How is it made?</a></p>
</section>
```

| Attribute | Meaning |
|---|---|
| `data-review-ai-summary` | The card of the review summary written by AI (`<section>`) (arrives with v2; currently not drawn). **Cannot be hidden.** |
| `data-review-ai-summary-title` | The "What customers say" heading |
| `data-review-ai-summary-text` | The summary text |
| `data-review-ai-topics` | The list of main topics; not added when no review has a topic |
| `data-review-ai-topic`, `data-review-ai-sentiment` | A topic and the sentiment of most reviews on it. The topic is `fit` (Fit), `quality` (Quality), `delivery` (Delivery) or `packaging` (Packaging); the sentiment is `positive`, `negative` or `neutral`. At most the 4 most mentioned topics are shown; the text is the topic name and the number of reviews that mention it. The sentiment is written for screen readers inside `data-review-sr`: "mostly positive", "mostly negative" or "mixed views". |
| `data-review-ai-summary-note` | The bottom line: how many reviews the summary was made from and on which day |
| `data-review-ai-summary-link` | The "How is it made?" link to the method statement; opens in a new tab |

## Photo strip

| Attribute | Meaning |
|---|---|
| `data-review-gallery` | The strip of the newest photos and videos from the product's reviews (up to 12); shown when there is at least one file. Filters do not affect it. |
| `data-review-gallery-title` | The title of the strip ("Photos and videos") |
| `data-review-gallery-list` | The horizontally scrolling list |
| `data-review-gallery-item` | The button of a file; it carries `data-review-media-kind` (`image` or `video`) and `data-review-media-index` (its position in the strip, starting at 0) and opens the photo viewer |

## Filters, search and sorting

Filters are combined: when one changes, the others are kept and the list is reloaded from the first page; the summary, the photo strip and the filter buttons stay in place. The filter buttons and the toolbar are shown only when the product has at least one review.

| Attribute | Meaning |
|---|---|
| `data-review-filters` | The group of filter buttons (`role="group"`); not added if there is no filter to show |
| `data-review-filter` | A filter button. `verified`: only reviews by verified buyers; shown when the number of verified reviews is greater than zero and less than the total. `media`: reviews with photos or video; shown when such a review exists. `topic`: reviews containing a frequently mentioned word. When selected, `aria-pressed="true"`; pressing it again removes the filter. |
| `data-review-topics`, `data-review-topics-label` | The group of topic buttons and the "Mentioned often" label |
| `data-review-topic` | The word of a topic button (on the `data-review-filter="topic"` element) |
| `data-review-toolbar` | The bar carrying the search section and the sort menu |
| `data-review-search` | The search section (`role="search"`) |
| `data-review-search-input`, `data-review-search-submit` | The search field (up to 100 characters) and the "Search" button. A search runs with the Enter key or the button; clearing the field removes the search. |
| `data-review-sort` | The sort menu; shown when the market permits more than one sort order. **Cannot be hidden.** |
| `data-review-sort-option` | A permitted sort option |
| `data-review-sort-default` | The market's default sort order |
| `data-review-results`, `data-review-results-text` | The results line and the "n reviews found" text; visible only when a filter or search is applied, otherwise `hidden` |
| `data-review-clear` | The "Clear filters" button, which removes all filters and the search |
| `data-review-announce` | The status text that announces the number of results to screen readers after filtering (`role="status"`) |

## List and review

| Attribute | Meaning |
|---|---|
| `data-review-body-slot` | The position of the list or of the empty-state message |
| `data-review-list` | The review list |
| `data-review-item` | A single review |
| `data-review-id` | The review's ID |
| `data-review-rating` | The rating |
| `data-review-head` | The top row of the review: the initials and the author part |
| `data-review-avatar` | The initials of the author's displayed name (up to two letters) |
| `data-review-avatar-tone` | The colour of the initials circle: between `0` and `5`, determined from the author's displayed name; the same name always gets the same colour |
| `data-review-byline` | The author name and the line below it |
| `data-review-author` | The author name |
| `data-review-meta` | The second line under the author name: the badges and the date |
| `data-review-badges` | The group of badges (inside `data-review-meta`); not added when there are no badges |
| `data-review-date` | The publication date (`<time datetime>`, inside `data-review-meta`) |
| `data-review-verified` | The verification badge. **Cannot be hidden.** |
| `data-review-method` | The verification method: `platform_api`, `tokenized_invite`, `in_store` or `manual` |
| `data-review-origin`, `data-review-origin-kind`, `data-review-origin-market` | The label of a review that comes from another source; the kind is `syndicated` (from another of the brand's markets; the label names the source market, such as "From the EU market") or `imported` (imported from a marketplace; the label names the source, such as "Bought on Trendyol · Imported automatically from Trendyol"). On an imported review the label is an `<a>` (`href`, `target="_blank"`, `rel="noopener"`) when the address of the review at the source is known, otherwise it stays a `<span>`; these reviews carry no `data-review-verified`. **Cannot be hidden.** |
| `data-review-experience` | Value `process`: the label of a review describing the experience, up to that point, of a customer whose order was cancelled or who returned the item. **Cannot be hidden.** |
| `data-review-stars` | The review's rating: five stars, the filled part is in `data-review-fill` |
| `data-review-title`, `data-review-body` | The title and the review text |
| `data-review-long`, `data-review-open` | On `data-review-body`: a text longer than 420 characters or 4 lines is cut at 4 lines; `data-review-open` is added when the visitor opens the text |
| `data-review-translated` | The line under the text of a translated review (arrives with v2; currently not drawn): "Translated" and the `data-review-show-original` button. When a review is not in the visitor's language and has a translation into it, the title and text are shown translated. **Cannot be hidden.** |
| `data-review-show-original` | The "Show original" / "Show translation" button (`aria-pressed`) (arrives with v2; currently not drawn); while the original is shown, the title and text carry the review's language in a `lang` attribute |
| `data-review-expand` | The "Read more" / "Show less" button (`aria-expanded`). It is visible only if the text really exceeds 4 lines; it is measured again when the component's width changes. |
| `data-review-item-aspects` | The stepped-scale topic ratings given in the review (`<dl>`); each row carries `data-review-aspect`, and `<dd>` contains the scale and the name of the chosen step (`data-review-aspect-value`) |
| `data-review-media`, `data-review-media-item`, `data-review-media-kind` | Photo and video previews; the kind is `image` or `video` |
| `data-review-media-open`, `data-review-media-index` | The preview button and the file's position in the review (starting at 0); it opens the photo viewer |
| `data-review-seller-response` | The seller response, in the same stream as the review. **Cannot be hidden.** |
| `data-review-resolution` | The resolution, in the same stream as the review. **Cannot be hidden.** |
| `data-review-reply-label` | The label of the seller response or the resolution |
| `data-review-actions` | The row containing the vote group and the "Report" button |
| `data-review-vote`, `data-review-vote-label` | The vote group (`role="group"`) and the "Helpful?" label |
| `data-review-helpful`, `data-review-helpful-count` | The "Yes" button and its vote count. The button contains a thumb icon (an inline `<svg>`) and the number; the full text ("Yes (n)") is in `aria-label`. When selected, `aria-pressed="true"`. |
| `data-review-unhelpful`, `data-review-unhelpful-count` | The "No" button and its vote count; the icon is shown upside down, and the full text ("No (m)") is in `aria-label`. When selected, `aria-pressed="true"`. Pressing the selected button again withdraws the vote; pressing the other one moves the vote to that side. |
| `data-review-vote-count` | The element inside a vote button that shows only the number |
| `data-review-actions-message` | The row's status message (for example that the vote could not be saved) |
| `data-review-report`, `data-review-report-form`, `data-review-report-sent` | The report button, form and confirmation message |
| `data-review-empty` | The message shown when there are no reviews, or when no review matches the filters |
| `data-review-more` | The button that loads the next page |
| `data-review-list-message` | The status message shown when a filter, the sort order or the next page fails to load (`role="status"`); removed on the next successful load |
| `data-review-sr` | Text intended only for screen readers |

## Questions and answers

Added as the last child of the root element (after `data-review-frame`) when the brand turns on questions and answers. The script loads this section as a separate part, only while questions and answers are on; the HTML prepared on the server carries the same structure.

| Attribute | Meaning |
|---|---|
| `data-review-questions` | The questions and answers section (`<section>`) |
| `data-review-questions-title` | The "Questions and answers" heading |
| `data-review-question-list` | The question list |
| `data-review-question`, `data-review-question-id` | A single question and its ID |
| `data-review-question-body` | The question text |
| `data-review-question-meta`, `data-review-question-author` | The line under the question and the asker's name ("Anonymous" without a name); the date with `data-review-date` |
| `data-review-answers` | The question's answer list; not added when there are no answers |
| `data-review-answer`, `data-review-answer-kind` | A single answer; the kind is `brand` (the brand) or `buyer` (a customer who bought the item) |
| `data-review-answer-head`, `data-review-answer-author` | The top line of the answer and the author's name (the channel's brand name on a brand answer) |
| `data-review-answer-badge` | The "Brand" label on a brand answer. A customer answer carries `data-review-verified` ("Verified buyer") instead. **Cannot be hidden.** |
| `data-review-answer-body` | The answer text |
| `data-review-answer-open`, `data-review-answer-form` | The "Answer" button (`aria-expanded`) and the answer form; added only while the visitor has a purchase proof (an invitation link, order verification or a signed-in customer) |
| `data-review-questions-empty` | The message shown when there are no questions |
| `data-review-questions-more` | The button that loads the next page of questions |
| `data-review-ask`, `data-review-question-form` | The "Ask a question" button (`aria-expanded`) and the question form |
| `data-review-question-asker` | The line shown instead of the name and email fields for a signed-in customer: "You are asking as Ayşe K. We will email you when it is answered."; without a name, "You are asking with your account. We will email you when it is answered." |
| `data-review-question-notify` | The `<label>` carrying the "Email me when it is answered" checkbox in a guest's form; when ticked, the email field appears and becomes required |
| `data-review-question-notice` | The information text in the form |
| `data-review-privacy` | The paragraph below the information text in the question and answer forms; its link ("Privacy notice on the processing of personal data") opens the privacy notice set on the channel in a new tab (`target="_blank"`, `rel="noopener"`). Not added if the channel has no privacy notice link. |
| `data-review-questions-message` | The section's status message (`role="status"`): sent, a missing field or an error |

## Review writing area

| Attribute | Meaning |
|---|---|
| `data-review-gate-root` | The root element of the review writing area; it carries the same `data-review-theme` value as the root element |
| `data-review-gate-state` | `pending` (HTML prepared on the server, or the signed-in customer's status is awaited), `closed`, `open` (form open), `refused` (no eligible order) or `submitted` (review submitted) |
| `data-review-gate-info` | The information text a visitor who is not signed in sees |
| `data-review-gate-verify` | The button that opens the order verification. In the `pending` state it is shown `disabled` until the script takes over. |
| `data-review-gate-form` | The order number and email form |
| `data-review-gate-message` | The single, general error message |
| `data-review-gate-write` | The "Write a review" button shown to a signed-in customer; only when the server has confirmed eligibility |
| `data-review-viewer-state` | `can_write` or `written` |
| `data-review-own-standing` | The status of the customer's own review: `published`, `pending`, `rejected` or `removed` |

## Review form

The form opens in a dialog and is added to the `body` element. If the component is inside an open modal `<dialog>` element on the page, the form is added inside that dialog, so it does not end up underneath the top layer. Inside the dialog, the Tab key stops once on each star row and each step group; within a group, the arrow keys make the choice.

| Attribute | Meaning |
|---|---|
| `data-review-form-overlay`, `data-review-form-dialog` | The backdrop layer and the dialog (`role="dialog"`; focus is kept inside the dialog and the Esc key closes it) |
| `data-review-form-verify` | The order verification step inside the dialog |
| `data-review-form-head`, `data-review-form-title`, `data-review-form-lede`, `data-review-form-close` | The header: title, description and close button |
| `data-review-form-content`, `data-review-form-foot` | The content and the footer |
| `data-review-form` | The review form |
| `data-review-form-product`, `data-review-form-name`, `data-review-form-variant` | A product's section, name and variant information |
| `data-review-form-rating`, `data-review-form-star` | The star group and a single star |
| `data-review-form-body`, `data-review-form-body-label` | The review text field and its label |
| `data-review-form-who` | The name part below the item parts of the form: the optional name field (an `input[type=text]` inside a `<label>`) and the `data-review-hide-name` checkbox for hiding the name. In the correction form the fields come filled with the name and the choice already on the review. In the order detail rating, the part appears once below the item forms and is used for each item that is sent |
| `data-review-hide-name` | The `<label>` carrying the "Hide my name on the site" checkbox; it is in the review form, the question form and the answer form. When ticked, the name shows on the site as the first letter of every word followed by `***` |
| `data-review-form-prompts` | When the product has rating topics, neutral questions under the text field ("You could mention: how was the Fit? …"); the field points to this line with `aria-describedby`. It contains no ready-made sentences or suggestions. |
| `data-review-form-aspects`, `data-review-form-aspects-title`, `data-review-form-aspect` | Rating topics; shown when topics are defined for the product. When there are topics both about the product and about delivery and service, the first are asked under "Detailed scores", the second under "Delivery and service", and `data-review-form-aspects-title` appears twice |
| `data-review-form-steps`, `data-review-form-step`, `data-review-form-step-checked` | A stepped scale and the selected step |
| `data-review-form-media`, `data-review-form-media-add`, `data-review-form-media-list`, `data-review-form-media-item`, `data-review-form-media-state`, `data-review-form-media-message` | Adding photos and videos: section, add button, list, single file, upload state (`pending`, `ready`, `refused`, and `kept` for earlier files in a correction) and message |
| `data-review-form-media-remove` | The button in the correction form that removes an earlier photo or video from the review (on the `data-review-form-media-state="kept"` element) |
| `data-review-form-media-progress`, `data-review-form-media-cancel` | While a file is being prepared and uploaded (state `pending`): the progress text ("Preparing 42%", then "Uploading 17%") and the button that cancels this file; both leave the item when the work ends |
| `data-review-form-notice`, `data-review-form-hint` | The publication notice and helper text |
| `data-review-privacy` | The privacy notice link below the publication notice (an `<a>` inside a `<p>`, opens in a new tab); only if a privacy notice link is set on the channel |
| `data-review-form-submit`, `data-review-form-cancel`, `data-review-form-message`, `data-review-form-done` | The submit and cancel buttons, the error message and the message after submission |

## Photo viewer

When a preview or a file in the photo strip is clicked, the file is enlarged in a dialog. The viewer is loaded as a separate chunk when it first opens and uses the same dialog structure as the review form (`data-review-form-overlay`, `data-review-form-dialog`, `data-review-form-head`, `data-review-form-title`, `data-review-form-close`). The title is "Photos and videos"; the description line (`data-review-form-lede`) gives the position of the file shown ("2 of 5"). Opened from the strip, it moves through all files in the strip; opened from a review, through that review's files. If there is more than one file, the left and right arrow keys move to the previous and next file; while focus is on a video, the arrow keys are left to the video. The Esc key closes the dialog and focus returns to the button that opened it.

| Attribute | Meaning |
|---|---|
| `data-review-lightbox` | The viewer dialog; it is on the `data-review-form-dialog` element |
| `data-review-lightbox-stage` | The area containing the file and the previous/next buttons |
| `data-review-lightbox-figure` | The enlarged file (`<figure>`): a photo, or a video with player controls |
| `data-review-lightbox-caption`, `data-review-lightbox-author` | The rating and author line below the file, and the author name |
| `data-review-lightbox-previous`, `data-review-lightbox-next` | The previous and next buttons; shown only when there is more than one file. After the last file it returns to the first. |

## Reviews on the order page

On the signed-in customer's order detail page, a rating and review form is shown inside the page for each item of the order (no dialog opens). For the setup, see [Signed-in customers › Order detail page](/en/integrate/signed-in-customers.md#order-detail-page).

| Attribute | Meaning |
|---|---|
| `data-review-order` | The element you add to your page; its value is the order number. The script replaces this element's content with the section it builds. As on a container, the site key, the API address and the design (`data-review-theme`) are read from the element's own attributes, or failing that from the script tag; the texts are in the language of the order answer. |
| `data-review-order-state` | The `<script type="application/json">` tag inside the element; it carries Sayproof's order answer |
| `data-review-order-root` | The root element of the section; it carries `data-review-theme` |
| `data-review-order-title` | The section title ("Rate your items") |
| `data-review-order-lines`, `data-review-order-line` | The item list and the row of one item; the row's value is the ID of the order line (`line_reference`) |
| `data-review-line-state` | The row's state: `can_write`, `pending`, `published`, `rejected`, `removed`, `waiting` or `closed`. After a review is sent it becomes `pending`. |
| `data-review-order-form` | The form in a row that can be reviewed. The item part carries the same fields as the review form (`data-review-form-product`, `data-review-form-name`, `data-review-form-rating`, `data-review-form-body`, `data-review-form-media`, `data-review-form-aspects`). |
| `data-review-order-foot` | The bottom line of the form: the message (`data-review-form-message`) and the row's own **Send** button (`data-review-form-submit`) |
| `data-review-order-status` | The status text shown in a row that cannot be reviewed, or after sending (`role="status"`) |
| `data-review-form-notice` | The publication notice; shown below the list if at least one row can be reviewed |
| `data-review-privacy` | The privacy notice link below the publication notice; shown if a privacy notice link is set on the channel and at least one row can be reviewed |

## Style tags

The script loads its styles with three `<style>` tags: `#sayproof-style` (the default component), `#sayproof-style-form` (the review form, the order verification and the reviews on the order page; loaded when first opened) and `#sayproof-style-lightbox` (the photo viewer; loaded when first opened). `#sayproof-style` comes from a separate chunk that loads in parallel with the first review list request; it is not added in headless use. The `nonce` value on the script tag is added to all three tags. For CSS variables, see [CSS variables](/en/customize/theme.md).

## Examples

### A container with all configuration attributes

```html
<div id="write-review-area"></div>

<div id="reviews"
     data-review-mount
     data-review-product="PRODUCT-38"
     data-review-scope="variant"
     data-review-product-name="Running shoe"
     data-review-locale="en"
     data-review-layout="grid"
     data-review-style="sidebar"
     data-review-theme="trust"
     data-review-gate="#write-review-area"></div>

<script type="module" src="https://cdn.sayproof.example/sayproof.js"
        data-review-site-key="YOUR-SITE-KEY"
        data-review-base="https://api.sayproof.example"
        data-review-locale="en"></script>
```

### Changing the product when a variant is selected

Changing the `data-review-product` value is sufficient; the script detects the change and loads the new product's reviews. No additional call is needed.

```html
<select id="size">
  <option value="PRODUCT-38">38</option>
  <option value="PRODUCT-39">39</option>
</select>

<div id="reviews" data-review-mount data-review-product="PRODUCT-38"></div>

<script>
  document.querySelector("#size").addEventListener("change", (event) => {
    document.querySelector("#reviews").dataset.reviewProduct = event.target.value;
  });
</script>
```

### Variant and group reviews on the same page

```html
<section>
  <h2>Reviews for this size</h2>
  <div data-review-mount data-review-product="PRODUCT-38" data-review-scope="variant"></div>
</section>

<section>
  <h2>Reviews for all sizes</h2>
  <div data-review-mount data-review-product="PRODUCT" data-review-scope="group"></div>
</section>
```

### Keeping your own button disabled until the component is ready

```html
<button id="write-review" type="button" disabled>Write a review</button>
<div id="reviews" data-review-mount data-review-product="PRODUCT-38"></div>

<script>
  const container = document.querySelector("#reviews");
  const button = document.querySelector("#write-review");

  const sync = () => {
    button.disabled = !container.hasAttribute("data-review-ready");
  };
  new MutationObserver(sync).observe(container, { attributes: true, attributeFilter: ["data-review-ready"] });
  sync();

  button.addEventListener("click", () => window.Sayproof?.write(container));
</script>
```

### Reviews on the order page

The content of the `data-review-order-state` tag is the answer your server received from the `GET /v1/viewer/order` call, as it is; escape the `<`, `>` and `&` characters when writing it into the tag. The script finds the element and replaces its content with the review section; the site key and the API address are taken from the script tag.

```html
<div data-review-order="100245">
  <script type="application/json" data-review-order-state>{"order":"100245","token":"…","lines":[…],"limits":{…},"language":"en","theme":"warm","words":{…}}</script>
</div>

<script type="module" src="https://cdn.sayproof.example/sayproof.js"
        data-review-site-key="YOUR-SITE-KEY"
        data-review-base="https://api.sayproof.example"
        data-review-locale="en"></script>
```

### Styling by state

```css
[data-review-root][data-review-busy] [data-review-list] {
  transition: opacity 0.2s;
}

[data-review-gate-root][data-review-gate-state="submitted"] {
  border-left: 3px solid var(--review-accent, #1f1b16);
}

[data-review-item]:has([data-review-origin-kind="imported"]) [data-review-body] {
  font-style: italic;
}

[data-review-media-item][data-review-media-kind="video"] {
  outline: 1px solid var(--review-border, #ece5da);
}

[data-review-star-filter][aria-pressed="true"] [data-review-bar]::before {
  background: var(--review-accent, #1f1b16);
}

[data-review-order-line][data-review-line-state="published"] [data-review-order-status] {
  color: #1f7a4d;
}
```
