Google Reviews

stable

Fetches recent Google Business reviews through the Maps Data API on RapidAPI, normalizes the response, filters eligible reviews, and prepares them for use in Astro components.

The feature includes a full reviews section and an optional ticker for shorter review excerpts.

Demo

Review ticker

UluBit gave me a much cleaner starting point…
Maya Chen

UluBit recent customer reviews

A preview generated from the bundled review data.

4.9
47 reviews
  • Maya Chen

    UluBit gave me a much cleaner starting point than copying disconnected snippets from old projects. The components are focused, understandable, and easy to adapt without bringing an entire framework with them.

  • Daniel Foster

    The Google Reviews feature saved me from rebuilding the same integration again. The fetch logic, fallback fixture, filtering, components, and documentation all work together as one understandable feature.

  • Priya Raman

    I appreciate that the examples use Astro and browser APIs directly instead of hiding simple behavior behind unnecessary dependencies. It makes the code easier to inspect, maintain, and customize.

  • Marcus Reed

    The documentation explains not only how to use each component, but also where its responsibilities begin and end. That made integrating the accordion into an existing project straightforward.

  • Sofia Alvarez

    The components feel like practical source code rather than a restrictive design system. I could copy what I needed, keep the accessible behavior, and restyle it to match the project.

  • Noah Williams

    Having components and complete features documented separately makes the catalog easy to navigate. I can quickly tell whether I am getting a small UI building block or a full integration.

The demo uses normalized local data rather than making a live API request. It demonstrates how consumers render an already prepared ReviewsData object.

Included components

  • Reviews.astro renders the business summary and review cards.
  • ReviewTicker.astro rotates through shortened review excerpts.
  • getReviews() fetches and prepares live or fixture data.
  • getReviewSnippets() converts full reviews into ticker-ready excerpts.
  • refresh-reviews-fixture.mjs generates the local fixture.

Setup

Copy the complete feature folder into the project:

src/features/google-reviews/

Add the required environment values:

GOOGLE_BUSINESS_ID=
RAPIDAPI_KEY=
GOOGLE_REVIEWS_LIVE=false

Add the fixture command to package.json:

{
  "scripts": {
    "reviews:refresh": "node --env-file=.env src/features/google-reviews/scripts/refresh-reviews-fixture.mjs"
  }
}

Generate the initial fixture:

pnpm reviews:refresh

The feature is provided with an empty fixture. Generate it after configuring a project so it contains reviews for the correct business.

Usage

Call getReviews() once from the page or shared parent that renders the review UI:

---
import {
  getReviews,
  getReviewSnippets,
} from "@/features/google-reviews";

import Reviews from "@/features/google-reviews/components/Reviews.astro";
import ReviewTicker from "@/features/google-reviews/components/ReviewTicker.astro";

const googleBusiness = await getReviews();

const reviewSnippets = getReviewSnippets(
  googleBusiness?.reviews ?? [],
  {
    maxWords: 8,
    maxReviews: 8,
  },
);
---

{googleBusiness && (
  <>
    <section class="reviews-section">
      <div class="container">
        <Reviews
          {googleBusiness}
          heading="Recent customer reviews"
          subheading="What customers are saying about us."
          maxReviews={6}
        />
      </div>
    </section>

    <ReviewTicker
      reviews={reviewSnippets}
      label="Customer review excerpts"
    />
  </>
)}

Reviews does not provide its own page section, container, background, or outer spacing. Those layout concerns belong to the consuming page.

ReviewTicker is independent from the main reviews section and can instead be rendered in a hero, social-proof strip, or another suitable location.

Data flow

getReviews()

normalize and filter reviews

ReviewsData
    ├── Reviews
    └── getReviewSnippets()

       ReviewTicker

Both components should receive data derived from the same getReviews() result. Components do not fetch reviews independently.

Review selection

By default, the feature requests the 20 newest reviews and retains reviews that:

  • Have a five-star rating.
  • Contain more than 100 characters.
  • Include a valid author, avatar, review text, rating, and timestamp.

These values can be changed in:

src/features/google-reviews/server/reviews.ts

The maxReviews option belongs to each consumer:

Reviews component: first 6 eligible reviews
Review ticker: first 8 eligible reviews

Development and production behavior

During development, the generated fixture is used by default.

To test the live request locally set:

GOOGLE_REVIEWS_LIVE=true

In production, the feature requests live reviews. If a configured API request fails or returns invalid data, it uses the generated fixture.

Missing RAPIDAPI_KEY or GOOGLE_BUSINESS_ID values cause an explicit error rather than silently using the fixture.

Project dependencies

The component styles currently use project-level:

  • CSS custom properties.
  • Global typography and layout classes.
  • The SCSS breakpoint mixin from src/styles/breakpoints.

Adapt these styles and imports when copying the feature into a project with different design foundations.