Updated 28-Jun-2024
Star ratings, which indicate review averages, can be useful indicators of quality on search results pages. There are several tactics to include star ratings (or rather, rating/review stars).
There may be an interesting use case for not having a root page /
in a WordPress website. That is, forcing a redirect from root to a stub, or rather a page. That has to do with the way Google treats
In WordPress it is common practice to have all pages end in /
and that actually works well, as instead there can be a funny implicit redirect to another page with a longer stub. In this case, though it may be a bit less elegant than without, it is clear that there are no further characters in the sought URL.
Unicode/UTF-8 Characters and Image Sprites
The standard yellow star ⭐ is a UTF-8 character ⭐
and is Hex encoded as %E2%AD%90
. These can be used in page titles, descriptions, headers, etc. They may be then passed through by Google.
> Google and Bing will currently display such stars in the URL, and both will also display the stars in the meta description. Google will display stars in the Title as well.
Unfortunately, our choice of colors is limited in Unicode characters, so they do not meet the current smaller, dark orange/reddish stars displayed in Google and Bing SERPs' semantic review markup. Actually, both Bing and Google currently use a PNG sprite for the stars.
Percent Encoding for URLs
URLs (or rather, URIs) on the Internet cannot support unicode/utf-8 as per the HTTP specification. Therefore unicode/utf-8 characters are converted into supported ascii characters using percent encoding. For example, the URL of this page in Unicode is:
But this is converted into percent encoding when copying and pasting from the URL bar of a browser, as such:
Star Color and Markup
The colors are a bit different for Bing and Google when comparing their stars. Bing uses #ff452e, though it uses #f94f2a for the actual rating in a related color; Google uses #f26b28.
To approximate the star, we can use the black star UTF-8 character ⭑, which is unicode character ⭑
and then paint it:
<span style="color:#f26b28">⭑⭑⭑⭑⭑</span>
⭑⭑⭑⭑⭑
To approximate Bing, one would add something like:
<span style="color:#f94f2a;font-weight:bold;font-size:13px">4.8/5</span>
<span style="color:#ff452e;font-weight:bold">⭑⭑⭑⭑⭑</span>
<span style="font-size:13px">21 REVIEWS</span>
Rendering as:
4.8/5 ⭑⭑⭑⭑⭑ 21 REVIEWS
For Google, it would be something like:
<span style="color:#f26b28">⭑⭑⭑⭑⭑</span>
<span style="color:#808080;font-size:small">Rating: 4.8 - 21 reviews</span>
Rendering as:
⭑⭑⭑⭑⭑ Rating: 4.8 - 21 reviews
Note that these are completely controlled by Bing and Google, and there does not appear to be a way of manually overriding Bing and Google stars. As noted above, we do seem to be able to have stars appear in the URL using Unicode/UTF-8 characters (though not the orange-red color).
Third Party Review Providers
There are larger third-party sites and review services that can provide star ratings. Usually these have some kind of deal with Google and/or Bing if one or both of the search providers are displaying third party star ratings on a SERP link. Facebook and Google are two of the more common star ratings that are displayed on the Internet. Facebook's' review stars are generally constrained to Facebook pages, however Google star ratings can show up on SERPs such as a Google Local Business or Google Plus pages. For a third party reviewing service, reviews.io has a decent business model.
For the small business or certain types of markets a public reviewing service is not a viable approach. Well, it turns out that the technical implementation of reviews and stars can be implemented on a website directly.
Rich Snippets, Rich Cards, Structured Data
Overall, Google and Bing have increasingly supported structured data, which is in a few formats. This is part of what is known as the semantic web, which means that text is marked up as having a specific meaning. Roughly, text and images can be presented as a part of a document (xhtml), and can be presented in a particular style (css). On that is built various ways of interaction (javascript). But for explicit metadata, parts of documents needs a semantic or meaning markup. Things like document types, dates, prices, authorship, ratings, and the like. There are quite a few structured data types recognized by Google. The ones that are most important are those displayed in search engine results pages (SERPS).
Now just because there is a result in a particular display type, it is important not to assume that those are automatically better for clickthrough rates. This must be demonstrated in the analytics. However, Google is also working to ensure that those rich snippets are working to the advantage of everyone, searchers and publishers alike. For the purposes of several different sites, the following are of interest as structured data, all of which can then be present in some form on the SERPs:
- Article (that is, website pages structured as news articles), Videos
- Organization, and more specifically, Local Business, Educational Organization, and others
- Products, Service, and Courses
- Events, Person, and Place
- Reviews (note that an aggregate rating can be nested under an organization) As well, as site can have structural structured data, that is then presented on SERPs, such as:
- Breadcrumbs
- Sitelinks searchbox
- Sitename will replace the standard
https://domain.tld
with a brand name. This meanshttps://www.google.com
becomesGoogle
, etc.
Current Best Practice - Comprehensive Structured Data
Our recommendation is as follows:
- Mark up sitewide the Organization, Educational Organization, or Local Business, and include an aggregate review. This done in JSON-LD can be inserted into the
...
of the page. - Include Sitename, Breadcrumbs, and Sitelinks searchbox (if applicable) in JSON-LD in the page ``
- Mark up all content pages as Articles, Courses, Products, etc., as appropriate. The focus should be on each page as a news article so that titles and descriptions have subject-verb agreement and active verbs (imperative or active voice). Even things like contact and privacy policy pages can be titled and described in a way that is news, rendering the news article an appropriate format.
- Use a single, identifying image for the organization, though it is not possible to do so for all entities, as Google was the image to belong to the instance being marked up.
Google Structured Data Tools
Google has some useful tools to create and test out structured data:
Note also that Google Adwords and Bing Ads also supports structured data, though managing that is done inside the advertising interface.
Structured Data - Remove Hentry if present in Theme
Sometimes there is a potentially incomplete hentry listing with attributes already in a theme or theme framework. For example, Ultimatum Theme has the following in a few different files.
- /wp-content/themes/ultimatum/wonderfoundry/functions/loop/loop.php (entry-content)
- /wp-content/themes/ultimatum/wonderfoundry/admin/helpers/class.css.saver.php (hentry)
- /wp-content/themes/ultimatum/wonderfoundry/functions/loop/loop-functions.php (itemtype, entry-title, bookmark)
Structured Data - Sitelinks Search Box & Website Name
- Add to Homepage Only
- Set a rel=canonical preferred home page on the home page
- Use the code below for a WordPress site, which supports
/?s={search_term}
search syntax, and to add the name and alternate name for search engines to use in SERPs - Finally, make a nice search interface and results page on the site itself, perhaps using Dave's WordPress Live Search
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Your WebSite Name",
"alternateName": "An alternative name for your WebSite",
"url": "https://domain.tld",
"potentialAction": {
"@type": "SearchAction",
"target": "https://domain.tld/?s={search_term}",
"query-input": "required name=search_term"
}
}
Structured Data - Organization, Local Business, Etc.
Currently Google and possibly Bing don't support this markup for actions, outside of a set of beta testers, but may in the future. In particular, there is the generic Organization, Educational Organization, and Local Business types of organizations, among others. For all of these, social media profiles, hours of operation, contact information, aggregate reviews, and the like can be added. There are actually quite a number of organization types, see this spreadsheet with equivalences.
- Add the code to the home, contact, or other key business pages, though it may be allowed across a site. Unclear on that at the moment.
{
"@context" : "https://schema.org",
"@type" : "LocalBusiness",
"name" : "My Business Name",
"image" : "https://domain.tld/home/logo.png",
"url":"https://domain.tld",
"sameAs": [
"https://www.facebook.com/domain/",
"https://twitter.com/domain",
"https://www.youtube.com/channel/domain",
"https://plus.google.com/+domain"
], "email" : "[email protected]",
"telephone" : [ "+66 80 123 4567", "+66 81 123 4567" ],
"address" : {
"@type" : "PostalAddress",
"streetAddress" : "99 Moo 99",
"addressLocality" : "Sansai",
"addressRegion" : "Chiang Mai",
"addressCountry" : "Thailand",
"postalCode" : "57890"
},
"openingHours": "Mo,Tu,We,Th,Fr,Sa,Su 00:00-23:59",
"aggregateRating" : {
"@type" : "AggregateRating",
"ratingValue" : "4.8",
"ratingCount" : "37"
}
}
Breadcrumbs need both markup and display (so that they are functional for visitors). This will best be done on every page in the main loop, so that categories and parent pages can be used to generate breadcrumbs, and with the use of microdata (rather than json-ld). The example from https://schema.org/BreadcrumbList is as follows, and it should be straightforward to generating these breadcrumbs from WordPress category membership and parent pages (and multiple can be supported).
Note that the code below was only enhanced by wrapping both breadcrumb trails in a paragraph <p>...</p>
, inserting a <br />
between the two trails, and adding style="display:inline;"
to the ordered lists and list items (ol, li).
<p>
<ol>
<li>
<a href="https://example.com/books">
<span>Books</span>
</li>
›
<li>
<a href="https://example.com/books/sciencefiction">
<span>Science Fiction</span>
</li>
›
<li>
<a href="https://example.com/books/sciencefiction/awardwinners">
<span>Award Winners</span>
</li>
</ol>
<br />
<ol>
<li>
<a href="https://example.com/literature">
<span>Literature</span>
</li>
›
<li>
<a href="https://example.com/literature/speculativefiction">
<span>Speculative Fiction</span>
</li>
</ol>
</p>
There is a very useful Breadcrumb NavXT plugin that, along with the Order Bender plugin, is able to produce a canonical breadcrumb trail with a lot of flexibility. One thing it does not do, however, is produce more than one breadcrumb trail. This feature request has been accepted by the plugin author as an assigned issue, but there has been no visible progress on this issue, as of 12 October 2016.
Structured Data - Article, Course, Product
- Articles are the most common data type for a page, review above for best practice with this.
- Courses data type is still going through the approval process, but Google already supports a few fields. This should be done one per page in JSON-LD.
- Product are likely the most common item for ecommerce.
- Service does not appear to have support from Google, better to shoehorn into Courses, Products, when possible.
Article Structured Data Example
<div>
<h2>Article headline</h2>
<h3>
By <span>John Doe</span>
</h3>
<span>A most wonderful article</span>
<div>
<img src="https://google.com/thumbnail1.jpg" />
</div>
<div>
<div>
<img src="https://google.com/logo.jpg" />
</div>
</div>
</div>
Course Structured Data Example
{
"@context": "https://schema.org",
"@type": "Course",
"name": "Introduction to Computer Science and Programming",
"description": "Introductory CS course laying out the basics.",
"provider": {
"@type": "Organization",
"name": "University of Technology - Eureka",
"sameAs": "http://www.ut-eureka.edu"
}
}
Product Structured Data Example
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Executive Anvil",
"image": "http://www.example.com/anvil_executive.jpg",
"description": "Sleeker than ACME's Classic Anvil, the Executive Anvil is perfect for the business traveler looking for something to drop from a height.",
"mpn": "925872",
"brand": {
"@type": "Thing",
"name": "ACME"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.4",
"reviewCount": "89"
},
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"price": "119.99",
"priceValidUntil": "2020-11-05",
"itemCondition": "https://schema.org/UsedCondition",
"availability": "https://schema.org/InStock",
"seller": {
"@type": "Organization",
"name": "Executive Objects"
}
}
}
Structured Data - Video
Video markup helps Google discover and frame the video for search results. Only useful if the video is not on other platforms for discovery and indexing.
Structured Data - Events
Events are focused around tickets and performances, rather than larger scale things like holidays. It is about as constrained as the Facebook Calendar, not useful unless one is selling performance-type event tickets.
Article, Course, Product Microdata
Given that a given web page could be one of each of these (or neither), automatic generation of breadcrumbs for these should be as straightforward as the breadcrumb microdata. The exception (besides the article) is where the data will reside to be pulled. For articles, it can be as simple as the title, description, author, and date published that is the article metadata. For course and product, additional information can reside in WooCommerce.
Alternatively it would just be a matter of additional page metadata that could be accessed.
One way of implementing this would be a custom post type and/or a custom theme template that would provide the information. Another is producing a plugin that would do the same thing (and would be much easier to implement across multiple sites, and multi-sites).
As well as a plugin, an accompanying widget might be useful, and could be placed above the main loop, just beneath the WordPress
Article, Course, Product Pseudocode
For current page, if has tag *course*, generate course microdata;
elseif has tag *product*, generate product microdata;
else generate article microdata;
Note that the use of Sensei LMS and WooCommerce already puts courses and products as custom types, and so simply querying the post type, or just having different templates for each custom type, should do the trick.