Welcome to the Jose Madrid Salsa developer docs — explore features, APIs, and deployment guides.
Jose Madrid SalsaJMS Docs

Google Reviews

Google Business reviews integration via the Places API

Google Reviews Integration

The platform displays Google Business reviews on the storefront by fetching them from the legacy Google Places API (Place Details). Reviews are loaded server-side and cached via ISR to avoid client-side API calls.

Architecture

Reviews come from one server component fetcher, lib/server/google-data.ts, which calls the legacy Places API (Place Details) with ISR caching (2-hour revalidation). There is no client-accessible reviews endpoint; the former /api/reviews/google route was removed because it called the billable Places API (New) with no callers.

Environment Variables

VariableDescriptionRequired
GOOGLE_PLACES_API_KEYServer-side Places API keyRecommended
NEXT_PUBLIC_GOOGLE_MAPS_API_KEYFallback if server key not setAlternative
GOOGLE_PLACE_IDGoogle Place ID for the businessRecommended
NEXT_PUBLIC_GOOGLE_PLACE_IDFallback public place IDAlternative

If no Place ID is configured, the fetcher returns empty reviews; set GOOGLE_PLACE_ID.

Setup

Find your Google Place ID

Search for your business on Google Maps and extract the Place ID from the URL, or use the Place ID Finder.

Enable the Places API

In Google Cloud Console, enable the Places API (New) for your project.

Configure environment variables

GOOGLE_PLACES_API_KEY=AIza...
GOOGLE_PLACE_ID=ChIJ...

API Call

The Places API v1 is called with specific field masks:

GET https://places.googleapis.com/v1/places/{placeId}
Headers:
  X-Goog-Api-Key: {apiKey}
  X-Goog-FieldMask: reviews,rating,userRatingCount

Data Types

type Review = {
  authorName: string
  rating: number
  text: string
  relativePublishTime: string | null
}

type ReviewsData = {
  reviews: Review[]
  totalRating: number
  totalReviews: number
}
  • authorName comes from review.authorAttribution.displayName
  • relativePublishTime is formatted as a readable date string (e.g., "March 15, 2026")
  • totalRating is the aggregate business rating
  • totalReviews is the total review count from userRatingCount

Caching

Server Component Fetcher

Uses Next.js ISR with next: { revalidate: 7200 } (2 hours):

const response = await fetch(url, {
  next: { revalidate: 7200 },
})

API Route

Uses Next.js route segment config:

export const revalidate = 7200 // 2 hours

Error Handling

The fetcher returns empty data on failure rather than throwing:

return { reviews: [], totalRating: 0, totalReviews: 0 }

Key Files

FilePurpose
lib/server/google-data.tsServer component data fetcher

How is this guide?

Edit on GitHub

Last updated on

On this page