← Back to all work
Red Cross First Aid Training VWO

Trustpilot reviews on the product listing page

A VWO test for Red Cross First Aid Training that injected a four- and five-star Trustpilot carousel between the intro content and the course grid on the workplace First Aid listing page. Conversion rose 15.04% on the primary metric, with the fuller story in how it split by device and audience.

I build and QA tests like this for brands and CRO agencies. Start a test brief →

Result

+15.04% Conversion rate primary metric · significant
+2.65% Add to basket
+5.97% Course search more users into the booking step

Rolled out to 100% of traffic.

The challenge

Visitors landing on the workplace First Aid listing page were browsing, then leaving before choosing a course. Journey analysis showed the heaviest friction sat between browsing and checkout, and the page gave people little reassurance that the training was trusted.

The reviews existed, but not where people were deciding. We tested whether surfacing that social proof on the listing page itself would move more people into the course search step and on to purchase.

The hypothesis

if we surface four- and five-star Trustpilot reviews above the course grid on the listing page then conversion and add to basket rise because social proof reassures browsers before they choose a course

What we changed

The variation injected a Trustpilot review carousel directly beneath the main course content, showing only four- and five-star reviews so the strongest social proof sat right above the course grid.

  • Widget: Trustpilot carousel (TrustBox), loaded through the official Trustpilot script
  • Reviews shown: four- and five-star only, English, en-GB
  • Placement: inserted after the main content row, above the course grid
  • Width: 73% and centred on desktop, full width with padding on mobile
  • Measurement: GA4, an experimentation event per interaction
  • Browsers: modern only, legacy IE and old Edge excluded

How it loads

Two small scripts run on the page: one for the visible change, one for measurement. Both wait for the DOM the same way, then split. Nothing runs until <body> exists, and neither script touches an old browser. The page has no framework and the widget target renders late, so the scripts poll for what they need before acting, then inject the carousel between the intro content and the grid.

// poll() waits for selectors or predicates, then runs the callback once every condition is met

poll(['.column-half-row'], function () {
  // element is in the DOM; safe to inject after it
  var row = document.querySelector('.column-half-row');
  row.insertAdjacentHTML('afterend', widgetHtml); // sits between the intro content and the grid
  window.Trustpilot.loadFromElement(document.getElementById('trustbox-carousel'));
});
<div class="column-half-container trustpilot-plp-container">
  <div id="trustbox-carousel" class="trustpilot-widget"
    data-locale="en-GB"
    data-template-id="53aa8912dec7e10d38f59f36"
    data-businessunit-id="•••••••• (client)"
    data-style-height="140px" data-style-width="100%"
    data-stars="4,5" data-review-languages="en">
    <a href="https://uk.trustpilot.com/review/redcrossfirstaidtraining.co.uk">Trustpilot</a>
  </div>
</div>

Instrumentation

Every interaction sends a GA4 gtag event named experimentation, tagged with an experiment id and a readable label. One delegated click listener on body covers three cases, and a single IntersectionObserver records the carousel being seen, once.

Event labelFires onFrequency
Conditions MetUser is bucketed into the experimentPer load
Has seen the reviewsCarousel at least 20% in the viewportOnce, gated by a body class
Clicks on a courseClick inside the course gridPer click
Clicks the reviews near the headerClick on the header Trustpilot widgetPer click
// One delegated listener covers every case.
document.body.addEventListener('click', function (e) {
  var t = e.target;
  if (t.closest('.trustpilot-widget iframe')) {
    track('clicks the reviews near the header');
  } else if (t.closest('.trustpilot-plp-container') && VARIATION === 'control') {
    track('clicks the reviews near the courses'); // control cell only
  } else if (t.closest('.course-list-grid')) {
    track('clicks on a course');
  }
});

// Seen, fired once.
var el = document.querySelector('#trustbox-carousel');
if (el) {
  new IntersectionObserver(function (entries) {
    entries.forEach(function (entry) {
      if (entry.isIntersecting && !document.body.classList.contains('trustpilot-seen')) {
        track('has seen the reviews');
        document.body.classList.add('trustpilot-seen'); // fire once
      }
    });
  }, { threshold: 0.2 }).observe(el);
}

An honest note on the tracking

In this build the variation reported "Conditions Met" through the legacy GA path while the tracking script reported it again through GA4. Reading GA4 alone you see the tracking event, so it does not distort the analysis, but it is the sort of thing worth flagging and cleaning up rather than quietly leaving in. The engineering follow-ups were to combine the two scripts into one shared helper, route everything through a single GA4 tracker so "Conditions Met" fires once, and call disconnect() on the observer after the first hit.

Inside the numbers

The lift held across the funnel, and the behaviour split by device and audience tells the fuller story. Course-click rate moved in opposite directions by device:

DeviceCourse-click rate vs control
Desktop-5.55%
Mobile+4.39%

Mobile users clicked into courses more often. Desktop clicks fell, which fits with desktop users spending longer reading the reviews and being more selective before clicking. A check on users looping back to search during a visit showed completion nudging up while looping stayed broadly flat, a sign that people were choosing with more confidence.

Loop checkControlVariation
Session start18,80718,680
Clicked on a course4,5304,592
Reached course search3,1323,167
Looped back to search577585
Journey completion3.07%3.13%

Where it worked, and where it needs work

Trust signals landed hardest with people who did not already know the brand. A couple of segments moved the other way.

What worked:

  • Mobile saw better journey completion, the audience most likely to need quick reassurance
  • New users converted more strongly, exactly the group the social proof was meant to persuade
  • Paid and organic search traffic performed better with the reviews in place

Watch-outs:

  • Desktop users engaged with the reviews but progressed less effectively, reading rather than clicking through
  • Direct traffic struggled, which points to a follow-up test for people who already arrive with intent

Recommendation and next steps

The variation won on the metrics that matter, so it ships. The segment picture shapes what we test next.

  • Roll out to 100% of traffic. The variation beat control on conversion, add to basket, and progression to course search.
  • Fix desktop and direct-traffic progression. Desktop visitors read the reviews but clicked through less, and direct traffic underperformed. Test placement and review length on desktop, and a tailored treatment for direct visitors.
  • Target unfamiliar and new-user journeys. Social proof worked best for people new to the brand. Prioritise pages where visitors do not yet know the brand, and be cautious rolling reviews onto high-familiarity journeys, where a parallel test went backwards.
  • Monitor after launch. Track conversion, add to basket, and looping behaviour once live to confirm the lift holds at full traffic.
← Back to all work