Structured Data (SEO)
When to Use
Add JSON-LD breadcrumb structured data to help Google display breadcrumbs in search results instead of the raw URL. This is a meaningful SEO win for content-heavy sites.
Decision
| Approach | When to use |
|---|---|
Easy Breadcrumb add_structured_data_json_ld |
You have Easy Breadcrumb installed — enable the checkbox, done |
Manual hook_page_attachments implementation |
Core-only setup with no Easy Breadcrumb |
| Metatag + Schema.org modules | Already using Metatag for other structured data; handles breadcrumbs as part of a broader strategy |
Pattern
Easy Breadcrumb approach (recommended): Enable add_structured_data_json_ld at admin/config/user-interface/easy-breadcrumb. The EasyBreadcrumbStructuredDataJsonLd service injects the result into <head> as <script type="application/ld+json">.
Generated JSON-LD:
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
{ "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog" },
{ "@type": "ListItem", "position": 3, "name": "My Article Title" }
]
}
The final segment intentionally omits the item URL when it is a non-link — per Google's guidelines, the current page URL is optional in the last ListItem.
Manual approach (without Easy Breadcrumb):
function my_module_page_attachments(array &$attachments): void {
$breadcrumb = \Drupal::service('breadcrumb')->build(\Drupal::routeMatch());
$links = $breadcrumb->getLinks();
if (count($links) < 2) { return; }
$items = [];
foreach ($links as $pos => $link) {
$item = ['@type' => 'ListItem', 'position' => $pos + 1, 'name' => (string) $link->getText()];
$url = $link->getUrl()->setAbsolute(TRUE)->toString();
if ($url) { $item['item'] = $url; }
$items[] = $item;
}
$data = ['@context' => 'https://schema.org', '@type' => 'BreadcrumbList', 'itemListElement' => $items];
$attachments['#attached']['html_head'][] = [
['#type' => 'html_tag', '#tag' => 'script', '#value' => json_encode($data), '#attributes' => ['type' => 'application/ld+json']],
'breadcrumb_json_ld',
];
}
Common Mistakes
- Wrong: Enabling Easy Breadcrumb JSON-LD while also using Metatag with breadcrumb schema → Right: Use one source only; two
BreadcrumbListblocks in<head>confuse validators and may confuse Google - Wrong: Using relative URLs in
itemproperties → Right: CallsetAbsolute(TRUE)— relative URLs are invalid in Schema.orgitem - Wrong: A
BreadcrumbListwith only one item → Right: Schema.org spec requires at least twoListItementries; skip output when fewer than 2 links exist
See Also
- Easy Breadcrumb Configuration
- Reference:
modules/contrib/easy_breadcrumb/src/EasyBreadcrumbStructuredDataJsonLd.php - Reference: https://schema.org/BreadcrumbList
- Google guidance: https://developers.google.com/search/docs/appearance/structured-data/breadcrumb