I'd like to add some Structured Data, following Google's recommendations. Following the instructions on their site, it says:

Markup is placed inside a script tag in the head of the HTML page. The markup does not have to be interleaved with the user-visible text, which makes nested data items easier to express, such as the Country of a PostalAddress of a MusicVenue of an Event. Also, Google can read JSON-LD data when it is dynamically injected into the page's contents, such as by JavaScript code or embedded widgets in your content management system.

It says it should be added inside a script tag in the head of the HTML page, but I was wondering if it's also possible to add it via a JSON file included in the header.php (loaded in fucntions.php). If it is possible, how would you add breadscrumb SD as well?

If the above is too much trouble, or not the right way, what is the best recommended way to add structured data to a WordPress site, that doesn't involve a plugin.


1 Answer 1


If you're creating the theme yourself, you can always use Schema Microata markup directly in the theme itself.

As we can see in the below example, adding extra attributes to your HTML can make it Schema compliant. In this instance, we are using itemscope, itemtype and itemprop:

Taken from http://schema.org/docs/gs.html#microdata_how

<div itemscope itemtype ="http://schema.org/Movie">
  <h1 itemprop="name">Avatar</h1>
  <div itemprop="director" itemscope itemtype="http://schema.org/Person">
  Director: <span itemprop="name">James Cameron</span> (born <span itemprop="birthDate">August 16, 1954</span>)
  <span itemprop="genre">Science fiction</span>
  <a href="../movies/avatar-theatrical-trailer.html" itemprop="trailer">Trailer</a>

However if you want to use JSON-LD markup, then you might want to consider generating the JSON-LD using a PHP JSON-LD library and injecting the code into your header by attaching it to the wp_head function:

Mashed together from the PHP-JSON-LD GitHub example:


// Describe your Thing to be marked up as an array
$doc = (object) array(
    "http://schema.org/name" => "Manu Sporny",
    "http://schema.org/url" => (object) array("@id" => "http://manu.sporny.org/"),
    "http://schema.org/image" => (object) array("@id" => "http://manu.sporny.org/images/manu.png")

// Describe it's schema context as well
$context = (object)array(
  "name" => "http://schema.org/name",
  "homepage" => (object)array("@id" => "http://schema.org/url", "@type" => "@id"),
  "image" => (object)array("@id" => "http://schema.org/image", "@type" => "@id")

function wp_json_ld($doc, $context) {

    // Pass it through this magical function
    $compacted = jsonld_compact($doc, $context);

    echo '<script type="application/ld+json">';
    echo json_encode($compacted, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    echo '</script>';

/* Output:
<script type="application/ld+json">
  "@context": {...},
  "image": "http://manu.sporny.org/images/manu.png",
  "homepage": "http://manu.sporny.org/",
  "name": "Manu Sporny"

// Add it to wp_head
add_action('wp_head', 'wp_json_ld');
  • Hi. Only JSON, I think microdata makes HTML mark up very messy. What is the benefit of using PHP JSON-LD library over adding it directly before the </head> tag within script tags? Sep 25, 2016 at 22:48
  • To be honest, if all you're trying to do is inject microdata, then there isn't a massive advantage to using the library other than giving you a neater way of adding context to your microdata -- it really comes into its own when you start doing things like reading schema from across the internet, and parsing documents. You can probably get away with doing a couple of json_encode calls on your data as an array. I'm assuming that you'll be assembling your data from various WordPress function calls, and that your information will naturally be presented in arrays or objects.
    – FaCE
    Sep 26, 2016 at 9:01
  • Is it not possible to wp_enqueue a .jsonld file? Would be much simpler..
    – jasie
    Sep 6, 2022 at 5:57

Your Answer

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

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