﻿---
title: Page feedback
description: The documentation site records page-level reactions and optional comments in the page-feedback-v1-{environment} Elasticsearch index. The API uses the...
url: https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/4061/development/page-feedback
products:
  - Elastic Docs Builder
---

# Page feedback
The documentation site records page-level reactions and optional comments in the
`page-feedback-v1-{environment}` Elasticsearch index. The API uses the feedback
identifier as the document `_id`, so later comment submissions and reaction
changes replace the same document.
The thumbs-up or thumbs-down selection writes a document with the reaction after
a short debounce, so quickly changing the selection records only the final
choice. The follow-up questionnaire writes the same document again with one or
more structured reasons, the reason-set version, and optional details. Readers
can select several reasons at once. One comment field applies to the whole
submission. It keeps its value when the reader switches between Yes and No.
Switching the reaction clears any selected reason that does not belong to the new
reason set. The browser stores that draft in `sessionStorage` for the current tab
and page so an accidental refresh can restore it, and clears it after a
successful submit. Submitting the questionnaire flushes any pending reaction write first.
This keeps abandoned questionnaires useful while ensuring the richer
submission wins.
Reasons are stored in the multi-valued `reasons` keyword field for filtering and
aggregation. `reason_set_version` identifies the questionnaire revision that
presented the option. Display labels may change without changing their stored value. Add a new
enum value when an option's meaning changes, and retain retired values so older
clients and historical documents remain valid.
Reason set version 3 presents these positive reasons in display order:
`solvedProblem`, `easyToUnderstand`, `accurate`, `helpfulExamples`,
`easyToFind`, and `anotherReason`. The negative reasons are
`hardToUnderstand`, `inaccurate`, `codeSampleErrors`, `missingInformation`,
`siteProblem`, and `anotherReason`. API pages use the same stored values
and `reason_set_version`. They pass `surface="api"` so labels and descriptions
talk about the spec and examples instead of a product how-to.
`siteProblem` reports a fault in the site rather than in the content. A broken
link, a control that does nothing, or a search that returns nothing belongs
here, while `inaccurate` and `codeSampleErrors` stay with the words on the page.
`inaccurate` also covers content that describes an older version of the product.
Version 3 retired `outOfDate` and folded it in, because a reader cannot tell a
page that was never right from a page that stopped being right. Two negative
sets therefore differ from version 2: it offered `outOfDate` and lacked
`siteProblem`. A query that counts either one must scope itself to a version.
`outOfDate` remains a stored value. Historical documents hold it, and a browser
running a cached bundle still submits it, so the endpoint still accepts it.
The endpoint accepts a reason only for the reaction it belongs to. A negative
reason sent with `thumbsUp` fails validation in `IsReasonValidForReaction` and
the request returns `400`. Adding an option means adding it to
`PageFeedbackReason`, to that reaction's list, and to the browser's reason set.
Retiring one means removing it from the browser's set alone.

## Provision the index

`PageFeedbackMapping` defines the mapping with `Elastic.Mapping` attributes.
During API startup, `PageFeedbackBootstrapService` uses
`Elastic.Ingest.Elasticsearch` to create or update environment-specific
component and index templates. The generated context uses the API assembly
version as its mapping version. Bootstrap skips unchanged mapping hashes and
prevents an older API task from replacing templates installed by a newer task
during a rolling deployment.
The bootstrap service and runtime gateway share one ingest channel. Feedback
upserts use `DirectWriteAsync` and await the bulk item result before the API
responds. They do not use the channel's retry overload because the browser owns
the bounded retry UX. The first successful feedback write creates the concrete
index from the templates.
The generated mapping disables dynamic field mapping. Fields that are not part
of `PageFeedbackDocument` remain unindexed instead of changing the schema.
Bootstrap failures are logged and ignored in `dev` so the local documentation
server can run without Elasticsearch. They prevent startup in `staging`, `edge`,
and `prod`.
Runtime credentials require permission to manage component and index templates,
create the environment's index, and write and delete its documents.
Template updates do not modify existing indices. For a mapping change, increment
the schema version in the index name, deploy the new template, and migrate any
documents that must be retained. Mixed task versions then write to separate
versioned indices during a rolling deployment. The assembly mapping version is
an additional downgrade guard for templates that retain the same schema-versioned
name; it does not replace index versioning.