← Work Pine Brook Digital.
Custom code · Webflow embed

Google Reviews widget

A reusable review feed built as a single custom-code embed you drop into any Webflow site. It fetches reviews, computes the average live, and lets visitors filter and sort, with no plugin and no monthly widget subscription. Built to demonstrate the exact task in the brief: writing custom code that integrates a data source into a pre-designed front end.

Live filtering Computed average API-shaped data Webflow embed Zero dependencies Mobile-ready
01

The live widget

This is the real component, running on this page. Tap a star filter or change the sort, the summary and list update instantly.

🔒 clientsite.com · embedded widget
Loading reviews…

A working component, not a screenshot. The average, the star distribution bars, and the count all recompute from whatever is currently showing.

02

Built to actually work

Every interactive piece does something. This is the difference between a design mockup and a component a client can ship.

1
Filter by rating. The star chips filter the list in place. The header count updates to match what is shown, so "showing 4 of 24" is always honest.
2
Sort that means something. Newest, oldest, highest, and lowest re-order the same data set without a page reload.
3
The average is computed, not hard-coded. The big number and the distribution bars are calculated from the data every time it loads or filters, so the widget can never show a stale rating.
4
Empty and loading states. A spinner while data loads, and a clear "no reviews match" message if a filter has no results, in the widget's own voice.
5
Accessible and keyboard-friendly. Filters are real buttons with pressed state, focus rings are visible, and reduced-motion is respected.
03

The code that powers it

The whole widget is one embed. Here is the core: fetch the data, compute the summary, render the list. This is written exactly as it would run against a live reviews endpoint.

In Webflow this goes into an Embed element (or the page's custom-code area). The fetch points at a data source that returns reviews as JSON. Swapping the mock URL for a real endpoint, a Google Places proxy or the client's own reviews table, is a one-line change.

reviews-widget.jsWebflow embed
// 1. Fetch reviews from the data source (JSON).
//    Swap REVIEWS_URL for a live endpoint or Places proxy.
const REVIEWS_URL = "/data/reviews.json";

async function loadReviews() {
  const res = await fetch(REVIEWS_URL);
  if (!res.ok) throw new Error("Could not load reviews");
  const data = await res.json();
  return data.reviews;
}

// 2. Compute the summary from the data — never hard-coded.
function summarize(reviews) {
  const total = reviews.length;
  const sum = reviews.reduce((a, r) => a + r.rating, 0);
  const average = total ? (sum / total) : 0;
  const dist = [5,4,3,2,1].map(s =>
    reviews.filter(r => r.rating === s).length
  );
  return { total, average, dist };
}

// 3. Apply the active star filter + sort, then render.
function apply(reviews, filter, sort) {
  let list = filter ?
    reviews.filter(r => r.rating === filter) : reviews;
  const by = {
    newest:  (a, b) => b.time - a.time,
    oldest:  (a, b) => a.time - b.time,
    highest: (a, b) => b.rating - a.rating,
    lowest:  (a, b) => a.rating - b.rating,
  };
  return [...list].sort(by[sort]);
}

// 4. Wire it up.
const reviews = await loadReviews();
renderSummary(summarize(reviews));
renderList(apply(reviews, activeFilter, activeSort));
Why a JSON source and not a live Google call? Google's Places API needs a private key and blocks browser requests, so the real integration runs through a small server-side proxy that the client owns. This demo uses a JSON file shaped like that response, so the front-end code you see is the same code that ships. That is the honest way to show it, and it is the part of the job this role is actually hiring for.