Background / Motivation

I maintain a Drupal module (Crumbs), that calculates breadcrumbs for a Drupal site.

I want to make those breadcrumbs SEO-friendly by using e.g. schema.org metadata semantic markup. Ideally this should automatically work on every site, no matter which theme is active.

On the other hand, I don't want to interfere with themes that override the HTML of a breadcrumb, or that target the breadcrumb html with CSS.

This means I am in a conflict. Either the module controls the HTML, or the theme does, but both is difficult.

So I thought of a workaround: Have a hidden SEO-optimized breadcrumb with "display: none;", generated by the module, and a visible breadcrumb where the HTML is generated by the theme (based on structured data from the module).


If I have a hidden SEO-optimized breadcrumb and a visible non-SEO-optimized breadcrumb, does this diminish the effect on SEO?

Afaik, the only real effect is having the breadcrumb show up in the search result, so if that is the case all is good?

The schema.org page http://schema.org/BreadcrumbList mentions Microdata, RDFa and JSON-LD. Naturally the JSON-LD variation doesn't have any output, so perhaps this would be the natural fit?


The module now uses json-ld for breadcrumb metadata.

  • 1
    Perhaps I answered my own question here. I only learned about JSON-LD while writing the question. the previous time I checked, this didn't exist yet, or was not mentioned on the schema.org page. Stil, if someone wants to confirm this in an answer, or reject it, go ahead!
    – donquixote
    Commented May 14, 2018 at 23:55

1 Answer 1


All three syntaxes make it possible to provide hidden structured data:

  • JSON-LD: The script element is hidden by default.
  • Microdata and RDFa: You can use link/meta elements (which are hidden by default) in the body + meaningless div/span elements if grouping is needed.

Hiding the markup for breadcrumbs will most likely not affect your SEO, as the hidden duplicated breadcrumbs don’t provide any content that isn’t also visible on the page.

From a Drupal themer’s perspective

For a Drupal module, I think the best practice is to use the syntax RDFa:

  • Support is part of Drupal core in D7 and D8 (RDF module, RDF Mapping API)

    Modules can provide mappings of their bundles' data and metadata to RDF classes and properties. This module takes care of injecting these mappings into variables available to theme functions and templates. All Drupal core themes are coded to be RDFa compatible.

  • If you use the RDF Mapping API in your module, I think themers won’t even see any kind of RDFa in the template, only general Drupal attributes they are used to from working with other template files (rdf_rdfa_attributes)

    This array will typically be passed through Drupal\Core\Template\Attribute to create the attributes variables that are available to template files. These include $attributes, $title_attributes, $content_attributes and the field-specific $item_attributes variables.

  • If themers are interested in structured data, they’ll likely learn RDFa because that’s what Drupal supports out of the box. In case they do want to manipulate the structured data somehow, and you use a different syntax, they would have to learn another syntax just because of your module.

  • If you would use a different syntax, it makes it harder to integrate your Microdata/JSON-LD with the RDFa generated by Drupal.

    For example, to add your BreadcrumbList (in JSON-LD or Microdata) item to the WebPage item (in RDFa, generated by Drupal) with the breadcrumb property, you can’t nest the list with the property attribute under the WebPage. Instead, you have to generate a URI for the BreadcrumbList (and make sure that it’s unique, i.e., not used by the site owner in any other way), and reference this URI as value for the breadcrumb property under WebPage (so you would have to use RDFa anyway).

  • If a site owner wants their site to output JSON-LD, it’s easy to convert the whole RDFa to JSON-LD. But it’s impossible to convert JSON-LD to RDFa that uses the existing markup, because the connection from the markup to its content isn’t captured with JSON-LD.

  • +1 for the first section. Not sure I understand your Drupal themer's perspective. The goal is to be compatible with existing themes that were developed without knowledge of my breadcrumb module. So ideally the themer should not even see any difference. I just made a proof of concept locally with json-ld via hook_html_head_alter() (D7) to add a script tag as documented here, schema.org/BreadcrumbList, I imagine this will do the trick.
    – donquixote
    Commented May 15, 2018 at 1:05
  • Btw the age-old issue is this one, drupal.org/project/crumbs/issues/2119537 I had a patch there but was afraid it would conflict with some themes, and overall make the theming of breadcrumbs more complex.
    – donquixote
    Commented May 15, 2018 at 1:08
  • @donquixote: I’m not a module developer, but as far as I understand it, for RDFa you don’t need to add the syntax to the template at all -- you just use core’s RDF API, and then the template generates the RDFa when rendering. And using these APIs, other modules could be used by site builders to change the mapping (e.g., add properties from another vocabulary to your breadcrumbs), without needing to change anything in the templates.
    – unor
    Commented May 15, 2018 at 1:58
  • Can you incorporate some example html for RDFa into your answer? The problem I see is that some themes only put out a list of <a> tags with separator string in between, and any added ol/li would break the CSS. This is why I thought to have two distinct breadcrumbs, one hidden with RDFa, and another visible with whichever html the theme wants.
    – donquixote
    Commented May 15, 2018 at 2:48
  • @donquixote: Schema.org’s BreadcrumbList type page contains an RDFa example. If you wonder if/how RDFa for BreadcrumbList could be used with specific preexisting HTML, I think it makes the most sense to post a separate question specifically about this markup. FWIW, it is possible to only have a parent element (like div) containing a elements (with child elements); not elegant, but possible (but I have no idea if Drupal’s RDF API also supports it).
    – unor
    Commented May 15, 2018 at 3:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.