Embedded Reviews at Yelp
David W., Software Engineer
- Oct 4, 2016
Yelp is known for useful, funny, and cool reviews of all kinds of businesses, so it’s no surprise that they often get shared in other places. While we love seeing screenshots of these reviews shared on other websites, they don’t make for a great user experience. Their image formats make it easy to create and share but they become outdated, load slower than text, and make it hard for users to find out more about the business. We wanted to build something that retains screenshots’ ease of sharing while solving some their biggest shortcomings, so we created embedded reviews. Now, content creators and business owners can directly embed Yelp reviews on their websites. Embedded reviews are always up-to-date, load as HTML, and link back to the business.
What makes a good embed widget?
The HTML snippet is what content creators and business owners copy and paste onto their websites, so it should have the minimal amount of HTML code necessary to achieve an embedded review. It should also be consistent so that it doesn’t need to be changed every time the review widget is updated with new contextual information.
The HTML snippet renders and displays fully styled embedded review widgets which should be responsive, so that it looks good on any website or any device. The content should also stay up-to-date with contextual information like the latest rating of the business and the reviewer’s most recent edit of their review.
To better understand how embedding is being used, and to inform future improvements, we should also record accurate analytics on the widgets to see where reviews are being embedded and which reviews are being embedded.
Performance is a major consideration for the embed widget. Embedded reviews need to load fast alongside the content on the embedding page. Embedded reviews also need to gracefully handle traffic spikes from popular websites.
Minimizing HTML and Maximizing Functionality
This is what users see before widgets.js runs:
Dynamically Creating the Fully Styled Embedded Review
Once the page loads, widgets.js executes. Widgets.js does a bit of magic to create a fully styled embedded review. We decided to have widgets.js create the fully styled embedded review widgets within iframes, rather than directly in the containing page. Review widgets are served as Yelp pages within iframes, adhere to the Yelp Styleguide, and show the most up-to-date review.
iframe embeds are preferable to direct embeds in these ways:
- iframe embeds allow for a simpler widgets.js. widgets.js only needs to construct the iframe and it defers rendering and styling the review widget to the iframe. In order to display the same review widget with direct embeds, widgets.js needs to retrieve review data from Yelp, construct the markup for the content, and style the markup.
- iframe embeds make development easier. The review widget can be developed and tested as its own Yelp page instead of as part of widgets.js, which also contains the embedding functionality. Yelp pages also come with Yelp Styleguide resources built in. Direct embeds would have to duplicate these resources inside widgets.js.
The review widget is built so that it displays nicely inside the iframe. Initially, the iframe has 0 height and width. After the review widget is loaded, the iframe height and width changes to fully display the review widget. This requires the review widget hosted on Yelp to pass sizing information to widgets.js running on the embedding page. Communication between scripts hosted on different domains are restricted due to the same-origin policy. window.postMessage() enables us to safely do cross-origin communication.
Accurate Analytics in Embedded iframes
So far, our responsive embedded review widget consists of the widgets.js controller, iframes for review widgets, and postMessage to communicate between the two. We realized that we could overcount page impressions for embedded reviews if a user embedded multiple reviews on the same site. To handle this we architected our analytics to serve Google Analytics (GA) on a Yelp domain in a separate, standalone iframe on the embedding page. We call this the GA iframe. We create one instance of the GA iframe per embedding page to handle sending events: one ‘pageview’ event when the user loads the embedding page and a separate ‘load’ event for every review widget iframe on the embedding page. These events are all sent through the single GA iframe. Review widget iframes and the GA iframe communicate with postMessage with widgets.js as the hub. Once a review widget loads inside the iframe, it notifies widgets.js via postMessage. widgets.js then resizes the review widget’s iframe and sends a GA event. Putting it all together, this is what the architecture looks like:
Speedy and Scalable
Now that we have all the functionality of a good embedded review widget, we need to look at performance. Embedded reviews were designed with speed and scalability in mind. We wanted our embedded review widgets to load fast to be as seamless as possible with the web page content. We also wanted our embedded reviews to be scalable to handle traffic spikes so that viral web pages loading multiple embedded reviews wouldn’t overload our servers. We identified two parts of the embed flow that could be optimized to be speedy and scalable: widgets.js and the iframes served by Yelp.
Since the review widget iframe and GA iframes are static pages served by Yelp, we use full page HTML caching. This way, most of the user traffic sees the cached page and our servers won’t even be contacted from traffic spikes from particularly viral web pages.
In summary, here is how we designed a good embed widget:
- The embed HTML snippet consists of unstyled and empty elements so that the HTML snippet is minimal and durable.
- We use a Google Analytics iframe served by Yelp to handle sending events for multiple review widget iframes on a single page. Resources served by Yelp, such as the controller and the iframes are either cached or served via CDN.
Check out Embedded Reviews on Yelp Business Pages!