Structured data carousels (beta)
Google uses structured data to understand the content on the page and show that content in a richer appearance in search results, which is called a rich result. This guide focuses on a new carousel rich result that's in beta, which is a list-like rich result that people can scroll horizontally to see more entities from a given site (also known as a host carousel). Each tile in the carousel may have information from your site about the price, rating, and images for entities on the page.
To be eligible for this beta rich result, add ItemList
structured data in combination
with at least one one of the following supported structured data items:
LocalBusiness
and its subtypes, for example:Product
Event
Here's how carousels can look in Google Search when you add ItemList
markup in
combination with a supported content type:
Feature availability
This feature is in beta and you may see changes in requirements or guidelines, as we develop this feature. If your business is based in EEA, or serves users in EEA, and you would like to learn more and express interest in these new experiences, you can start by filling out the applicable form (for flights queries, use the interest form for flights queries).
This feature is currently only available in European Economic Area (EEA) countries, on both desktop and mobile devices. It's available for travel, local, and shopping queries. For shopping queries, it's being tested first in Germany, France, Czechia, and the UK.
Add structured data
Structured data is a standardized format for providing information about a page and classifying the page content. If you're new to structured data, you can learn more about how structured data works.
Here's an overview of how to add structured data to your site.
- Pick a single summary page that contains some information about every entity in the list. For example, a category page that lists the "Top hotels in Paris", with links out to specific detail pages on your site for more information about each hotel. You can mix and match different types of entities (for example, hotels, restaurants), if needed for your scenario. For example, if you have a "Things to do in Switzerland" article that lists both local events and local businesses.
- Add the required properties to that summary page. You don't need to add markup to the detail pages in order to be eligible for this beta feature. Based on the format you're using, learn where to insert structured data on the page.
- Add the required and recommended properties for the specific content type that the carousel
is about:
LocalBusiness
and its subtypes, for example:Product
Event
Depending on your scenario, you may choose the best type to use. For example, if you have a list of hotels and vacation rentals on your page, use both
Hotel
andVacationRental
types. While it's ideal to use the type that's closest to your scenario, you can choose to use a more generic type (for example,LocalBusiness
). - Follow the guidelines.
- Validate your code using the Rich Results Test.
- Deploy a few pages that include your structured data and use the URL Inspection tool to test how Google sees the page. Be sure that your page is
accessible to Google and not blocked by a robots.txt file, the
noindex
tag, or login requirements. If the page looks okay, you can ask Google to recrawl your URLs. - To keep Google informed of future changes, we recommend that you submit a sitemap. You can automate this with the Search Console Sitemap API.
Guidelines
For your page to be eligible for carousel rich results (beta), you must follow the Search Essentials and general structured data guidelines. In addition, the following guidelines apply to carousel rich results (beta):
- Use of generic types is allowed. However, to use recommended properties, you must use the
respective types. For example, to use
amenityFeature
, use theLodgingBusiness
type. - Use of additional or extra fields is allowed, but may not appear in the rich result.
- Your site must have a summary page and multiple detail pages. Currently, this feature isn't designed to support other scenarios, such as an all-in-one page where the "details" are anchor points within the same page.
- The markup must be on a summary or category page, which is a list-like page that contains information about at least three entities and then links out to other pages on your site for more information on those entities. While you don't need to add markup to the detail pages, you must include the detail page URLs in your summary page's markup.
- Mark up all items that are on the summary or category page. For paginated categories, add an
ItemList
to each subsequent page and include the entities that are listed on that page. For infinite scroll, focus on marking up the entities that are initially loaded in the viewport.
Examples
The following is a high level structure of the carousel. The order specified in the markup is the order that will be used to order the tiles in the carousel rich result.
<html> <head> <title>Top 5 Restaurants in Italy</title> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "ItemList", "itemListElement": [ { "@type": "ListItem", "position": 1, "item": { "@type": "Restaurant", "name": "Trattoria Luigi", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$", "servesCuisine": "Italian", "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.5, "reviewCount": 250 }, "url": "https://www.example.com/trattoria-luigi" } }, { "@type": "ListItem", "position": 2, "item": { "@type": "Restaurant", "name": "La Pergola", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$", "servesCuisine": "Italian", "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 1150 }, "url": "https://www.example.com/la-pergola" } }, { "@type": "ListItem", "position": 3, "item": { "@type": "Restaurant", "name": "Pasta e Basta", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$", "servesCuisine": "Italian", "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.2, "reviewCount": 690 }, "url": "https://www.example.com/pasta-e-basta" } } ] } </script> </head> <body> </body> </html>
Structured data type definitions
You must include the required properties for your content to be eligible for display as a rich result. You can also include the recommended properties to add more information about your content, which could provide a better user experience.
ItemList
ItemList
is the container item that holds all elements in the list. All URLs of the
elements in the list must point to different pages on the same domain.
The full definition of ItemList
is available at
schema.org/ItemList.
Required properties | |
---|---|
itemListElement |
List of items. To specify a list, define an |
itemListElement.item
|
Subtype of An individual item in a list. Populate this object with:
Example: For a hotel, provide |
itemListElement.position
|
The item's position in the carousel. This is a 1-based number. |
Common list item properties (LocalBusiness
, Product,
or Event
)
All of the carousel item types have the following properties in common.
Required properties | |
---|---|
image |
Repeated One or more images of the entity or item (for example, an image of the hotel). Don't include logos in this image property. Additional image guidelines:
For example: "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ] |
name |
The string name of the entity or item. For example, the name of a hotel or a vacation
listing. The |
url |
The canonical URL of the item detail page (for example, the standalone page for a single hotel or vacation listing that was referenced in the summary page). All URLs in the list must be unique, but live on the same domain (the same domain, or sub or super domain as the summary page). |
Recommended properties | |
---|---|
aggregateRating.bestRating
|
The highest value allowed in this rating system (for example, |
aggregateRating.ratingCount
|
The total number of ratings for the item on your site. |
aggregateRating.ratingValue
|
A numerical quality rating for the item, either a number, fraction, or percentage (for
example, For decimal numbers, use a dot instead of a comma to specify the value (for example
<span itemprop="ratingValue" content="4.4">4,4</span> stars |
Additional type-specific properties definitions
LocalBusiness
(and subtypes)
In addition to the ListItem
properties, Google supports the
following LocalBusiness
properties (including its subtypes) for carousel rich results
Nest these properties under itemListElement.item
.
Recommended properties | |
---|---|
amenityFeature |
For "amenityFeature": { "@type": "LocationFeatureSpecification", "name" : "beachAccess", "value": true } |
priceRange |
The relative price range of a business, commonly specified by a normalized number of currency signs. Provide the price range in either of the following formats:
This field must be shorter than 12 characters. If it's longer than 12 characters, Google won't show a price range for the business. |
servesCuisine |
For restaurants only: The type of cuisine the restaurant serves. |
Product
In addition to the ListItem
properties, Google supports the
following Product
properties for carousel rich results. Nest these properties under
itemListElement.item
.
Recommended properties | |
---|---|
offers |
A nested If you're using
If you're using
|
offers.highPrice |
The highest price of all offers available. If you're specifying a single price with
|
offers.lowPrice |
The lowest price of all offers available. If you're specifying a single price with
|
offers.price |
The offer price of a product, or of a price component when attached to |
offers.priceCurrency |
The currency used to describe the product price, in three-letter
ISO 4217 format. If a currency is
not provided, Google defaults to |
Event
In addition to the ListItem
properties, Google supports the
following Event
properties for carousel rich results. Nest these properties under
itemListElement.item
.
Recommended properties | |
---|---|
offers |
A nested If you're using
If you're using
|
offers.highPrice |
The highest price of all offers available. If you're specifying a single price with
|
offers.lowPrice |
The lowest price of all offers available. If you're specifying a single price with
|
offers.price |
The price for your tickets, including service charges and fees. Don't forget to update it
as prices change or tickets sell out. If you're specifying a price range with
If the event is available without payment, fees, or service charges, set the
"offers": { "@type": "Offer", "price": 0 } |
offers.priceCurrency |
The currency used to describe the event price, in three-letter
ISO 4217 format. If a currency is
not provided, Google defaults to |
Examples for common scenarios
Restaurant
example
Here is an example of a restaurant carousel in JSON-LD.
<html> <head> <title>Top 5 Restaurants in Paris</title> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "ItemList", "itemListElement": [ { "@type": "ListItem", "position": 1, "item": { "@type": "Restaurant", "name": "Trattoria Luigi", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$", "servesCuisine": "Italian", "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.5, "reviewCount": 250 }, "url": "https://www.example.com/restaurant-location-1" } }, { "@type": "ListItem", "position": 2, "item": { "@type": "Restaurant", "name": "La Pergola", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$", "servesCuisine": "Italian", "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 1150 }, "url": "https://www.example.com/restaurant-location-2" } }, { "@type": "ListItem", "position": 3, "item": { "@type": "Restaurant", "name": "Pasta e Basta", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$", "servesCuisine": "Italian", "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.2, "reviewCount": 690 }, "url": "https://www.example.com/restaurant-location-3" } } ] } </script> </head> <body> </body> </html>
Lodging (Hotels
and VacationRental
) example
Here is an example of a lodging carousel in JSON-LD.
<html> <head> <title>Top 5 Hotels in Paris</title> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "ItemList", "itemListElement": [ { "@type": "ListItem", "position": 1, "item": { "@type": "Hotel", "name": "Four Seasons Hotel George V, Paris", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$$", "amenityFeature": { "@type": "LocationFeatureSpecification", "name" : "internetType", "value": "Free" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 50 }, "url": "https://www.example.com/four-seasons" } }, { "@type": "ListItem", "position": 2, "item": { "@type": "VacationRental", "name": "Downtown Condo", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$", "amenityFeature": { "@type": "LocationFeatureSpecification", "name" : "instantBookable", "value": true }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.7, "reviewCount": 827 }, "url": "https://www.example.com/downtown-condo" } }, { "@type": "ListItem", "position": 3, "item": { "@type": "Hotel", "name": "Ritz Paris", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$$$$", "amenityFeature": { "@type": "LocationFeatureSpecification", "name" : "freeBreakfast", "value": true }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 1290 }, "url": "https://www.example.com/ritz-paris" } } ] } </script> </head> <body> </body> </html>
Things to do example example
Here is an example of a things to do carousel in JSON-LD.
<html> <head> <title>Top 5 Things To Do in Paris</title> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "ItemList", "itemListElement": [ { "@type": "ListItem", "position": 1, "item": { "@type": "Event", "name": "Paris Seine River Dinner Cruise", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "offers": { "@type": "Offer", "price": 45.00, "priceCurrency": "EUR" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.2, "reviewCount": 690 }, "url": "https://www.example.com/event-location1" } }, { "@type": "ListItem", "position": 2, "item": { "@type": "LocalBusiness", "name": "Notre-Dame Cathedral", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "priceRange": "$", "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.8, "reviewCount": 4220 }, "url": "https://www.example.com/localbusiness-location" } }, { "@type": "ListItem", "position": 3, "item": { "@type": "Event", "name": "Eiffel Tower With Host Summit Tour", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "offers": { "@type": "Offer", "price": 59.00, "priceCurrency": "EUR" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 652 }, "url": "https://www.example.com/event-location2" } } ] } </script> </head> <body> </body> </html>
Product
example
Here is an example of a product carousel in JSON-LD.
<html> <head> <title>Top coats of the season</title> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "ItemList", "itemListElement": [ { "@type": "ListItem", "position": 1, "item": { "@type": "Product", "name": "Puffy Coat Series by Goat Coat", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "offers": { "@type": "AggregateOffer", "lowPrice": 45.00, "highPrice": 60.00, "priceCurrency": "EUR" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 50 }, "url": "https://www.example.com/puffy-coats" } }, { "@type": "ListItem", "position": 2, "item": { "@type": "Product", "name": "Wool Coat Series by Best Coats Around", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "offers": { "@type": "AggregateOffer", "lowPrice": 189.00, "highPrice": 200.00, "priceCurrency": "EUR" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.7, "reviewCount": 827 }, "url": "https://www.example.com/wool-coats" } }, { "@type": "ListItem", "position": 3, "item": { "@type": "Product", "name": "Antartic Coat by Cold Coats", "image": [ "https://example.com/photos/1x1/photo.jpg", "https://example.com/photos/4x3/photo.jpg", "https://example.com/photos/16x9/photo.jpg" ], "offers": { "@type": "Offer", "price": 45.00, "priceCurrency": "EUR" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 1290 }, "url": "https://www.example.com/antartic-coat" } } ] } </script> </head> <body> </body> </html>
Troubleshooting
If you're having trouble implementing or debugging structured data, here are some resources that may help you.
- If you're using a content management system (CMS) or someone else is taking care of your site, ask them to help you. Make sure to forward any Search Console message that details the issue to them.
- Google does not guarantee that features that consume structured data will show up in search results. For a list of common reasons why Google may not show your content in a rich result, see the General Structured Data Guidelines.
- You might have an error in your structured data. Check the list of structured data errors and the Unparsable structured data report.
- If you received a structured data manual action against your page, the structured data on the page will be ignored (although the page can still appear in Google Search results). To fix structured data issues, use the Manual Actions report.
- Review the guidelines again to identify if your content isn't compliant with the guidelines. The problem can be caused by either spammy content or spammy markup usage. However, the issue may not be a syntax issue, and so the Rich Results Test won't be able to identify these issues.
- Troubleshoot missing rich results / drop in total rich results.
- Allow time for re-crawling and re-indexing. Remember that it may take several days after publishing a page for Google to find and crawl it. For general questions about crawling and indexing, check the Google Search crawling and indexing FAQ.
- Post a question in the Google Search Central forum.