Recently Updated: 17 min read

Reviews Loaded With JavaScript: Visibility and Markup

Reviews Loaded With JavaScript: Visibility and Markup

If the reviews on your trail running backpack page appear in the browser but not in the page source, the question is where they come from and whether Google gets them in its rendered copy of the page. Google can run JavaScript, so a review widget is not a problem by itself. What matters is that the review text ends up in the rendered HTML, that the stars and counts you mark up are visible to users on that same page, and that paging through reviews uses real links. If you sell packs through a marketplace, bolt a third-party review widget onto your own store, or run a single-page app, this walk-through gives you a testing order and a set of decisions.

Three questions before you touch any code

Start with three plain questions about one backpack page. First, is the review text in the HTML that the server returns? Second, if not, is it in the DOM after the scripts have run? Third, can a visitor who has not clicked anything read at least the first reviews? The answers sort your page into one of three situations and tell you where to look.

Answer patternSituationNext step
Yes, yes, yesServer-side reviewsCheck the markup matches the text
No, yes, yesReviews added by script on loadTest the rendered HTML with Google's tools
No, no, noReviews wait for a click or other conditionMove the first reviews out of that condition

A fourth state exists: the reviews are in the DOM but hidden from users. Markup that describes reviews users cannot read is a separate problem, covered in the review snippet guidelines discussed later.

How Google processes a script-driven page

Google's JavaScript SEO basics page describes three phases: crawling, rendering and indexing. Googlebot queues pages for both crawling and rendering. A page with a 200 status code goes into the render queue unless a robots meta tag or header says not to index it, and it may wait there for a few seconds or longer. When resources allow, a headless Chromium renders the page and runs the JavaScript. Googlebot then parses the rendered HTML for links and uses it to index the page.

For a review widget the consequence is direct. If the rendered HTML holds the review paragraphs, they are available to indexing. If the widget needs an action that rendering does not perform, the paragraphs are not in the rendered HTML. The page says to use the Rich Results Test or the URL Inspection Tool to check the rendered HTML, and that content which does not appear there will not be indexed.

Four details worth carrying into a review page

  • Links must be a elements with an href attribute to be found. Links injected by JavaScript are fine if they follow that rule.
  • When Google meets a noindex robots tag it may skip rendering and script execution, so switching noindex off with JavaScript may not work.
  • Content should not depend on URL fragments, since Googlebot cannot reliably resolve those URLs. The page points to the History API with real URLs.
  • Meaningful status codes matter. A missing page should return a 404 rather than an empty page with a 200.

Google may revise these pages, so read the current version before committing to a design.

What the review snippet page requires

The review snippet documentation sets technical guidelines that bear directly on a backpack page.

  • Provide review information about a specific item, not a category or a list of items.
  • Mark up an aggregate evaluation by several people with AggregateRating.
  • Make sure the review content you mark up is readily available to users from the marked-up page.
  • Ratings must be sourced directly from users, and reviews or ratings from other websites must not be aggregated.
  • If you include several individual reviews, also include an aggregate rating of them.
  • Do not include fake or undisclosed incentivized reviews in the page or in the markup.
  • The page recommends accepting only ratings that come with a review comment and the author's name.

Fields and their status

TypeRequiredRecommended
Reviewauthor, itemReviewed (unless nested), itemReviewed.name, reviewRating, reviewRating.ratingValuedatePublished, reviewRating.bestRating, reviewRating.worstRating
AggregateRatingitemReviewed (unless nested), itemReviewed.name, ratingValue, and at least one of ratingCount or reviewCountbestRating, worstRating

The page describes ratingValue as a numerical quality rating for the item, expressed as a number, fraction or percentage. Whatever form you choose, the page must show the same figure to users.

Mapping the markup to what a visitor sees

Check the markup field by field against the review card. A backpack review card shows an author name, a star rating, a date and the review text. In the markup these are separate fields, and each should be traceable to something on the screen.

Visible elementMarkup fieldStatus on the Google page
Reviewer's display nameauthorRequired
Product nameitemReviewed.nameRequired
Star ratingreviewRating.ratingValueRequired
Review datedatePublishedRecommended
Top of the scalereviewRating.bestRatingRecommended
Bottom of the scalereviewRating.worstRatingRecommended

Practical suggestion: print the scale in words too, for example "4 out of 5", so the visible text and the value in the markup agree.

Seller replies and moderation

A seller reply to a review is its own block and does not change the rating or the author. Keep replies out of the average. When a review is removed in moderation, the visible list, the count and the markup must change together; with page caching, clear the cache on the same event that deletes the review.

Where the widget gets its reviews

Backpack pages receive reviews in one of three ways, and each has a different failure mode.

DeliverySource of the textFailure to test for
Server-renderedFirst HTML responseMarkup count differs from the visible count
Client-side on loadA script request after loadScript error or blocked request leaves the area empty
Client-side on interactionA click, scroll or consentThe rendered HTML has no review text at all

Practical suggestion: for any review you want indexed, make sure it belongs to the first group or loads without an interaction. The JavaScript documentation describes what happens when a page loads; it has no statement on whether rendering clicks buttons, so do not assume it does.

A testing routine for a trail running backpack page

Pick three backpack pages: one with a long review history, one with few, one with none. Run the same steps on each.

  1. View the page source and search for a sentence from a review. A hit means the review is server-rendered.
  2. In the browser's developer tools, search the live DOM for the same sentence.
  3. Run the URL through the Rich Results Test or URL Inspection and read the rendered HTML. Search for the sentence again.
  4. Search the rendered HTML for the JSON-LD block and compare ratingValue and the count with the numbers shown on the page.
  5. If a sentence is missing in step 3 but present in step 2, find the condition that gates it: a click, a scroll, a consent banner, a script error.
  6. Record the result with the date and the URL.

Reading a tool result with care

The tools show you what Google's rendering produced for that test request. A review that appears there is a good sign for that moment, and a review that does not appear is a warning that indexing will not pick it up. Neither result replaces watching how the page behaves over time, because a script update can change the outcome.

Some widgets load only after consent. If the rendered page without consent shows an empty reviews area, shoppers who decline also see none. Practical suggestion: render the review text on the server and use the widget only for interactive extras such as the submission form.

From symptom to cause

A short table speeds up diagnosis when a backpack page misbehaves.

SymptomPossible causeFirst check
Review visible in the browser, absent from rendered HTMLThe script waits for a condition or failsConsole errors and the loading condition
Reviews present, markup absentThe widget writes no JSON-LDSearch the rendered HTML for the structured data block
Markup present, reviews hiddenReviews removed or collapsed after loadVisibility of each marked-up review
Counts differ between text and markupCache or two data sourcesWhere each number is computed
Second review page cannot be reachedThe control is a button without an hrefThe element and its href value
Page missing from the indexA noindex tag or a robots blockRobots meta tag and response headers

Console errors and blocked requests

A script that throws an error leaves the review area empty. Open the developer tools console and look for red lines, then check the network panel for blocked or failed requests to the review vendor. A review area that fills in your browser but not in a testing tool points to a condition such as consent, a cookie or a blocked resource.

Caching and timing

If the backpack page is cached for an hour and reviews change faster, the cached page shows a stale count. Shorten the cache for the review block or clear it whenever a review is added or removed.

Paging through reviews

A pack with a long review history cannot show everything at once. Three patterns are available.

PatternHow it behavesRisk
Load-more buttonA script appends the next reviewsReviews behind the button may not be rendered
Numbered pages with their own URLsEach page has a real linkNeeds a plan for canonical and sitemaps
Fragment URLs such as #page=2The fragment switches contentGooglebot cannot reliably resolve fragment URLs

The JavaScript page states that links need an href attribute on an a element and that fragments should not be used to load different content. For numbered review pages, decide in advance which page is the canonical one and link consistently to it.

Infinite scroll

Lazy loading is described as a good way to save bandwidth, but the guidance asks you to follow lazy loading guidelines so content stays searchable. For a review list, load the first batch without scrolling and treat further batches as a convenience for visitors.

Keeping the count honest

Suppose the page shows twenty reviews and says "47 reviews". If the markup says reviewCount 47 while only twenty are accessible from the page, a visitor cannot reach all that the markup describes. Practical suggestion: show the full count in text, give a working link to the rest, and keep markup and text derived from the same data.

Markup generated by script

Google states that JSON-LD can be generated with JavaScript and injected into the page, and asks you to test the implementation. The review snippet page links to a guide on generating structured data with JavaScript. So script-generated markup is allowed. The risk is a mismatch: a widget that writes markup from its own data while your page shows different reviews.

Practical suggestion: compute the average and the count on the server from the same table that feeds the visible list, write the JSON-LD into the first HTML response, and keep the widget for display extras. If you must let the widget write the markup, test the rendered HTML after every vendor update.

Trust rules that decide what you may mark up

The review snippet page says that when the entity being reviewed controls the reviews about itself, pages using LocalBusiness or Organization markup are ineligible for the star review feature. A store that writes its own five-star reviews and marks them up on its homepage is in that position. It also says ratings must be sourced directly from users, so a marketplace seller must not copy another shop's backpack reviews into a listing. Incentives need disclosure, and undisclosed incentivized reviews do not belong in the markup.

Example scenario: a trail running backpack with a vendor widget

Example scenario: a shop adds a vendor's review widget to its trail running backpack pages. The widget fetches reviews two seconds after load and writes the JSON-LD itself. In URL Inspection the rendered HTML contains the reviews, but the "show more" control is a button without an href, and the vendor's count comes from a cached total that is a day old.

The shop takes three steps. It renders the first ten reviews and the average on the server. It turns the "show more" button into a link to a numbered review page with its own URL. It stops using the vendor markup and writes JSON-LD from its own table. None of this promises a different result in search; the aim is that Google, shoppers and the markup all see the same reviews.

What the shop records afterwards

Example scenario, continued: the shop keeps a one-page record per backpack range. It lists the review source, who writes the markup, the paging pattern, the date of the last rendered-HTML test and the person who owns the next test. When the vendor ships an update, the owner reruns the routine on three pages. When a new pack range launches, the same record is created before launch, so the review setup is tested while the page is still in staging. The record also shows what has not been tested yet, which is useful when a marketplace partner asks how the reviews are delivered.

A second benefit is communication. Developers, content staff and the vendor all read the same short document, and a disagreement about whether reviews are visible turns into a question that a test can answer.

Questions to put to a review vendor

  • Is the review text present in the first HTML response or added by script?
  • Who writes the structured data, your server or the vendor script?
  • Are paged reviews reachable through links with an href?
  • Is the displayed count the same figure as the markup count?
  • Does the widget work without consent, and what happens without it?
  • What happens to the markup when a review is deleted?

The documentation has no statement about any specific review product, so the answers have to come from the vendor in writing.

Decision rule: can these reviews be indexed and marked up

Work through the questions in order.

  1. Is review text in the server HTML? If yes, check only that markup and text match.
  2. If not, is it in the rendered HTML in Google's tools? If yes, keep a record of the test and repeat it after vendor updates.
  3. If not, find the gating condition and move the first batch ahead of it.
  4. Is every marked-up review and the rating visible to users on this page? If not, remove the markup until it is.
  5. Are paged views reachable by real links? If not, convert the controls.

Practical suggestion: if question four fails, remove the markup the same day instead of waiting for a fix to the widget.

Recording the verdict for each page

Practical suggestion: keep one short verdict per review page in the same sheet you use for the checklist, so the next person does not repeat the tests from scratch.

FieldWhat to writeWhy it helps
SituationServer-side, script on load, or behind a clickShows which row of the first table applied
Tool resultWhether the first reviews appear in the rendered HTMLGives a baseline to compare after a vendor update
Markup checkRating and count match the visible text, yes or noCatches drift between widget and markup
Owner and next dateWho retests and whenPrevents a green test from being treated as permanent

A page with a "no" in the markup row goes to the top of the queue, because markup that disagrees with the visible text is the case the rules warn about.

Checklist

  • The first ten reviews appear without a click.
  • Review text is found in the rendered HTML.
  • Review and AggregateRating required fields are filled.
  • The count in the markup matches the count on the page.
  • Ratings come from users of this shop, not from other websites.
  • Incentivized reviews are disclosed.
  • Paging uses a elements with an href.
  • No content depends on URL fragments.
  • JSON-LD is in the first HTML or confirmed in the rendered HTML.
  • Consent state does not hide the review text.

Repeating the checks

A review setup should be retested on a schedule, because a vendor update or a template change can break it silently. Practical suggestion: retest three backpack pages after every template change and every vendor update, compare counts and averages once a month, and review the incentive disclosure whenever the review programme changes. Write each result in a log with the date and the URL.

Script timing and completeness

Delaying a heavy review script can help page speed, but Google's documentation describes a render queue where a page may wait for seconds or longer. Test that the reviews still appear in the rendered HTML after you delay the script. A speed gain that removes the reviews from the rendered copy does not help.

Mistakes to avoid

Marking up a category average

The guideline asks for a specific item. One rating for "trail running backpacks" as a whole does not meet it.

Moving old reviews to a new model

When a new version of a pack is a different product, reviews of the old version belong to the old page.

Relying on a script to remove noindex

Google may skip rendering when it sees noindex in the original code, so a script that removes it may not run.

Treating a green test as permanent

A passing test shows one moment. Repeat it after every template or widget change.

Hiding the number in an image

If the rating exists only as a drawn star graphic with no text, the markup and the visible content are hard to compare. Print the figure as text as well.

Frequently Asked Questions

Does Google index reviews that a script loads after the page opens?

Google's documentation describes a render step in which a headless Chromium runs the JavaScript, and the rendered HTML is used for indexing. Content that does not appear in the rendered HTML in the testing tools will not be indexed.

Is generating review markup with JavaScript allowed?

Google says JSON-LD can be generated with JavaScript and injected into the page, and asks you to test it. Practical suggestion: write rating and count on the server so the markup cannot drift from the visible reviews.

What if the reviews load only after a click on a button?

The documentation has no statement on whether rendering clicks buttons. Place the first batch of reviews where it loads without interaction.

Can my own five-star score for the whole shop be marked up?

The review snippet page says that when the reviewed entity controls the reviews about itself, pages with LocalBusiness or Organization markup are ineligible for the star review feature.

May I copy a trail running backpack's reviews from another store?

No. The page says ratings must be sourced directly from users and that reviews or ratings from other websites must not be aggregated.

Should the review count in the markup equal the count on the page?

The guideline asks that the review content you mark up be readily available to users from the marked-up page. Practical suggestion: derive both numbers from one data source.

Conclusion

Script-loaded reviews work for search only when they reach the rendered HTML, show up for visitors on the page and match the markup. Put the first reviews on the server, give paged reviews real links, write the rating markup from the same data as the visible list, and rerun the test routine after each change. For the wider topic of collecting and marking up reviews, see the customer reviews guide, and for how Google handles script-built pages in general, the JavaScript SEO guide goes further.

Google sources: JavaScript SEO basics (Opens in a new tab) and Review snippet structured data (Opens in a new tab). If you want product page copy and review sections planned together, see our content writing service.

0 Comments

No comments yet for this article.

Post a comment

Please log in to leave a comment. Login