TrustBnBDocs

Reading Airbnb pages

Airbnb's HTML uses generated class names that change often. TrustBnB doesn't rely on them: it finds ratings by what they look like and by the links around them. Code: extension/src/scan.ts (reading) and extension/src/content.ts (showing scores).

Where it runs

The content script runs on every Airbnb country site listed in extension/src/domains.ts (airbnb.com, airbnb.co.uk, airbnb.ae, airbnb.com.sg and 64 more). The build writes that list into the manifest.

For an Airbnb site missing from the list, or a tab that was open before TrustBnB was installed, opening the popup starts the content script in that tab. This uses the activeTab and scripting permissions, which only apply to the tab you open the popup on.

Search results

  1. Find every element whose whole text reads like a card rating: 4.92 (123), ★ 4.8 (1,234), 4,92 (1 234). A rating from 1 to 5 with one or two decimals, then a review count in brackets.
  2. Keep the innermost one. Airbnb sometimes splits the rating over several elements (<span>4.67</span> <span>(39)</span>); the element holding both pieces is the one used.
  3. Walk up from it, at most 15 levels, to the first ancestor that links to exactly one listing (/rooms/<id>). That's the card, and its listing id.

"New" listings and Airbnb's screen-reader text ("4.92 out of 5 average rating") don't match the pattern, so they're left alone.

In Replace mode the rating element is hidden and the badge is inserted right after it. In Show both mode the badge sits next to Airbnb's rating.

Listing pages

On a /rooms/<id> page, TrustBnB reads the rating and review count from the data Airbnb embeds in the page (guestSatisfactionOverall, reviewCount and similar fields). If those aren't there, it reads the visible "★ 4.92 · 123 reviews" line.

The panel goes right after the block containing the page's title.

Rewriting Airbnb's numbers

In Replace mode, TrustBnB walks the page's text and rewrites each text node whose entire content is this listing's rating ("4.92", "★ 4,92", "4.92 ·"), allowing for Airbnb's rounding. It keeps the original formatting (decimal comma, star, trailing dot) and only changes the text itself, never the elements, so Airbnb's page keeps working.

Each rewritten number is marked with an attribute that gives it the lime highlight, and gets a tooltip with Airbnb's original. Switching to Show both or turning TrustBnB off restores the original text and tooltip.

Choosing the city

pageHints collects two clues from the page:

  • Place text: the place in a search address (/s/Paris--France/homes, ?query=Paris), or a listing page's title.
  • Coordinates: the center of the map in a search address (ne_lat, sw_lng, …), or a listing's coordinates from its embedded data.

resolveCity matches the place text against city names (longest match wins, accents and punctuation ignored). Failing that, it takes the nearest city within 60 km of the coordinates. Failing that, it uses the pooled data for all cities.

Keeping up with the page

Airbnb is a single-page app: new results load as you scroll or move the map, and pages change without a reload. A MutationObserver watches the page and schedules a new pass 250 ms after the last change. TrustBnB ignores changes it made itself, and skips cards whose badge is already up to date.

When settings change in the popup, every page re-renders immediately.

Talking to the popup

After each pass, the content script keeps a small status: how many ratings it found, how many it graded, and the city it chose. The popup asks for it every second while open and shows it as the status line. That message is the only communication between the two, and it stays in your browser.

When Airbnb changes its pages

If the popup turns yellow on search or listing pages, Airbnb has likely changed how it writes ratings. The fix usually belongs in parseRatingText, findCardRatings or readListingPage in scan.ts. Add the new markup to scan.test.ts first: its fixtures are shaped like Airbnb's pages, with class names left out.