What Is ItemList Schema? The Complete Guide (2026)
What Is ItemList Schema?
ItemList schema is a type of structured data — defined in the Schema.org ItemList vocabulary — that marks up a page listing multiple items of the same type, enabling Google's Carousel rich result. A carousel displays a horizontal row of cards in search results — each card showing an image, title, and link — for supported content types like recipes, courses, movies, and restaurants.
- ItemList requires
itemListElement— a non-empty array of ListItem objects - Each ListItem needs
position(unique sequential integer starting at 1) and eitherurloritem - Duplicate URLs or duplicate positions are errors in Greadme
- For Google Carousel eligibility: at least 2 items, all URLs on the same domain, all items of the same supported type (Recipe, Course, Movie, or Restaurant)
- Cross-domain URLs and mixed item types are warnings that reduce carousel eligibility
When to Use ItemList Schema
ItemList schema is used on "summary pages" — pages that aggregate and link to multiple individual item pages. The individual item pages must each contain their own schema markup (Recipe, Course, Movie, or Restaurant) for the carousel to be fully eligible.
Common use cases:
- A recipe index page linking to individual recipe pages
- A course catalog page listing each course with its own page
- A movie review index linking to individual film review pages
- A restaurant guide linking to individual restaurant pages
- "Best of" and "Top 10" articles where each item has its own dedicated page
ItemList is also used as the outer wrapper for carousel-style schemas — Course List (used by Course schema), Movie carousels, and Recipe collections all use ItemList as the container.
Google Carousel Eligibility Requirements
The Google Carousel is a rich result type that places your content in a horizontal scroll card above organic results. For carousel eligibility, all of the following conditions must be true:
| Requirement | Greadme behavior on violation |
|---|---|
| Minimum 2 items | Warning, −10 points |
| All URLs on the same domain as the summary page | Warning (cross-domain URLs detected), −5 points |
| All items of the same supported type | Warning (mixed item types), −5 points |
| Each linked detail page has its own valid structured data | Not checkable from the summary page — Greadme advises validating detail pages separately |
| Unique URLs for each ListItem | Error on duplicate URLs, −10 points per duplicate |
| Sequential positions starting at 1 | Warning if sequence starts above 1 or has gaps, −3 points |
Required Properties
| Property | Greadme rule |
|---|---|
itemListElement | Error if missing or not an array. Error if array is empty |
itemListElement[n].position | Error if missing on a ListItem. Must be a unique integer. Greadme errors on duplicate positions |
itemListElement[n].url or itemListElement[n].item | Error if both are missing. At least one must be present per ListItem |
ListItem Structure: url vs. item
Each ListItem in itemListElement can reference content in two ways:
| Approach | When to use | Example |
|---|---|---|
| URL-only | When the detail page has its own complete schema — the simplest approach | {"@type":"ListItem","position":1,"url":"https://example.com/recipe/1"} |
| Embedded item | When you want to include content data directly in the summary page schema (name, image, etc.) | {"@type":"ListItem","position":1,"item":{"@type":"Recipe","name":"Pasta","url":"..."}} |
The URL-only approach is simpler and the most common. The embedded item approach is used when the summary page schema is the primary or only source of structured data for the listed items.
ItemList Schema Code Example: Recipe Index
A summary page listing recipes using the URL-only approach:
{
"@context": "https://schema.org",
"@type": "ItemList",
"name": "Quick Weeknight Dinners",
"description": "Our top 5 recipes ready in under 30 minutes.",
"url": "https://example.com/recipes/quick-dinners",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"url": "https://example.com/recipes/pasta-primavera"
},
{
"@type": "ListItem",
"position": 2,
"url": "https://example.com/recipes/chicken-stir-fry"
},
{
"@type": "ListItem",
"position": 3,
"url": "https://example.com/recipes/shrimp-tacos"
}
]
}ItemList with Embedded Items: Course Catalog
Embedding course data directly in the ItemList for a course catalog page:
{
"@context": "https://schema.org",
"@type": "ItemList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@type": "Course",
"url": "https://example.com/courses/python-101",
"name": "Python for Beginners",
"description": "Learn Python from scratch in 4 weeks."
}
},
{
"@type": "ListItem",
"position": 2,
"item": {
"@type": "Course",
"url": "https://example.com/courses/web-dev",
"name": "Full-Stack Web Development",
"description": "Build web apps with React and Node.js."
}
},
{
"@type": "ListItem",
"position": 3,
"item": {
"@type": "Course",
"url": "https://example.com/courses/data-science",
"name": "Data Science Fundamentals",
"description": "Statistics, Python, and machine learning basics."
}
}
]
}Common Mistakes to Avoid
- Duplicate URLs: Every ListItem must link to a unique URL. Greadme errors on duplicate URLs and deducts 10 points per duplicate. This is also a Google disqualifier for carousel eligibility.
- Duplicate positions: Every ListItem must have a unique position number. Greadme errors on duplicate positions.
- Non-sequential positions: Positions should be consecutive integers starting at 1 (1, 2, 3, …). Gaps (1, 2, 5) or starting above 1 (2, 3, 4) trigger a Greadme warning — this is Greadme's best-practice check, not an explicit Google requirement.
- Mixed content types: Mixing Recipe and Movie items in the same ItemList triggers a Greadme warning and reduces carousel eligibility. Each ItemList should represent a single content type.
- Cross-domain URLs: All item URLs should be on the same domain as the summary page. Linking to external sites (e.g., a recipe index linking to recipes on other domains) triggers a Greadme warning.
- Only one item: A single-item ItemList is valid schema but generates a Greadme warning — carousel requires at least 2 items.
How Greadme Validates ItemList Schema
Greadme runs a dedicated ItemList validator that checks both structural integrity (positions, URLs) and carousel eligibility signals. The score starts at 100:
| Issue | Severity | Points lost |
|---|---|---|
Missing or non-array itemListElement | Error | −30 (score reset to 0) |
Empty itemListElement | Error | −30 |
| Duplicate position | Error | −10 per duplicate |
| Duplicate URL | Error | −10 per duplicate |
Missing position on ListItem | Error | −5 per item |
Missing both url and item | Error | −10 per item |
| Only 1 item in list | Warning | −10 |
| Cross-domain URLs | Warning | −5 |
| Mixed item types | Warning | −5 |
| Positions not starting at 1 | Warning | −3 |
| Non-sequential positions | Warning | −3 |
Frequently Asked Questions
Does the order of items in itemListElement affect search ranking?
The position values signal your intended ordering to Google, but Google may display carousel items in any order based on its own relevance signals. The position numbers are used for de-duplication and ordering context, not as a ranking directive to Google.
Can ItemList be used for navigation menus or breadcrumbs?
No. Breadcrumbs have their own dedicated schema type — BreadcrumbList. Navigation menus do not have a standard schema type. ItemList is specifically for content carousels and summary pages listing items of a specific content type.
What supported content types can appear in a Google Carousel?
Google supports four content types for carousel rich results: Recipe, Course, Movie, and Restaurant. Other types (Blog posts, Products, Events) may use ItemList schema but are not eligible for the Google Carousel carousel display format. They may still benefit from AI system understanding and extraction.
Is it better to embed item data or just use URL references?
URL references are simpler and preferable when each item has its own well-structured detail page. Embedding item data is useful for sites where detail pages don't have structured data, or for programmatically generated lists where embedding is more efficient than per-page schema implementation. When in doubt, use URL references and ensure each linked page has its own valid schema markup.
