Structured Data Specification

Updating structured data to meet this format is completely optional, our crawlers are able to pick up HTML tags, Open Graph protocol. Using this structured data specification allows you to have more control over the type of data provided by the Internal Links API and add customizations.

Introduction

Graphite’s Structured Data Specification for the Internal Links API enables any web page to become a rich linking object within the Internal Links API resulting link graph while following a standard structure.

This specification version is based on the RDFa W3C recommendation for embedding rich metadata within web documents; this means the specification requires the addition of additional <meta> tags in the <head> of the user web page.

Adding metadata following this specification ensures that the API user completely controls the data provided by the Internal Links API as linking data objects. However, the Internal Links API could use other commonly available metadata to find required information if the metadata described on this document is not present at crawling time. Such additional metadata could be the HTML title tag, the first HTML h1 heading element, standard HTML meta tags, and the Open Graph protocol metadata.

Basic Metadata

A minimum set of values is required to build minimal rich linking objects:

  • graphite:content - (multiple allowed) The page's textual content. The Internal Links API uses this to find related pages when building related links. If not declared, the Internal Links API will take the text content within the page <body>; remember that the <body> may contain sections representing noise, such as headers, footers, and sidebars.
  • graphite:title - The title of the page that will be provided as the link title. If not declared, the Internal Links API will take the first <h1> element found on the page as the link title. Additionally, the Open Graph’s og:title property or the page’s meta <title> tag could be taken in that order of precedence, depending on their existence.

Example of usage for the Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts page on searchenginejournal.com:

<!DOCTYPE html>
<html lang="en" prefix="graphite: https://graphite.io/rdfa">

<head>
  <title>Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts</title>
  <meta property="graphite:title" content="Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts" />
  <meta property="graphite:content" content="It's not necessary to know how to code to be a good SEO. Coding skills are not a prerequisite for SEO competency, but additional skills always make one more effective. ... But learning how to code can make a good SEO an even better one because knowledge provides advantages." />
</head>

<body>
</body>

</html>

Optional Metadata

These following metadata properties are optional, but they are recommended if the Internal Links API user requires these metadata to build more complex internal linking modules.

  • graphite:author - (multiple allowed) The author name of an article-like page (blog post, recipe, etc.). If not declared, the Internal Links API will take the Open Graph article:author property or the HTML <meta name=”author”> element, in that other of precedence, depending on their existence. It can be declared multiple times.
  • graphite:category - (multiple allowed) The page’s category name. It can be declared multiple times.
  • graphite:description - The link description. Text that should be used as the link description; is usually used to show a snippet of the page content. If not declared, the Internal Links API will take the Open Graph og:description property or the HTML <meta name=”description”> element, in that order of precedence depending on their existence.
  • graphite:image - The link thumbnail URL. It is an image that should be used as the link image. An image of the desired size should be provided as the Internal Links API does not store or process images. If not declared, the Internal Links API will take the Open Graph og:image property if present.
  • graphite:language - The page’s language. It should follow the format for HTML global language attribute (lang). If not declared, the Internal Links API will take the language declared in the <html> root element.
  • graphite:location - The page’s geographical location in string format. This property is useful when computing related links bound to a geographical location. For example, “San Francisco, CA, US”.
  • graphite:modified_time - The page’s modified time. It is an ISO 8601 timestamp string. If not declared, the Internal Links API will take the Open Graph article:modified_time property if present.
  • graphite:published_time - The page’s published time. It is an ISO 8601 timestamp string. If not declared, the Internal Links API will take the Open Graph article:published_time property if present.
  • graphite:read_time - The reading time of an article-like page (blog post, recipe, etc.). The suggested format is "{time number} {unit}", e.g., "15 min", "2 hours", "30 sec". ISO 8601 duration format won’t be parsed.
  • graphite:type - The page type, e.g., “skill” or “tool”, is useful for identifying pages by type and applying filters efficiently.

Example of usage for the Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts page on searchenginejournal.com:

<!DOCTYPE html>
<html prefix="graphite: https://graphite.io/rdfa">

<head>
  <title>Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts</title>
  <meta property="graphite:author" content="Roger Montti" />
  <meta property="graphite:category" content="SEO" />
  <meta property="graphite:category" content="Technical SEO" />
  <meta property="graphite:category" content="Web Dev SEO" />
  <meta property="graphite:description" content="Coding knowledge turns a good SEO into a great one who's better able to stay ahead of the competition." />
  <meta property="graphite:image" content="https://cdn.searchenginejournal.com/wp-content/uploads/2022/07/coding-1000-x-1000-1-62dfe8aa712c0-sej-552x488.png" />
  <meta property="graphite:language" content="en" />
  <meta property="graphite:location" content="US" />
  <meta property="graphite:modified_time" content="2022-08-13T23:45:44+00:00" />
  <meta property="graphite:published_time" content="2022-08-13T23:45:44+00:00" />
  <meta property="graphite:read_time" content="14 min" />
  <meta property="graphite:type" content="article" />
</head>

<body>
  ...
</body>

</html>

Custom Metadata

Custom properties could be added by using the prefix graphite:custom, i.e., graphite:custom:{property}. For example, a discount price could be defined through the property graphite:custom:discount_price.

Some considerations:

  • Only alphanumeric characters and the underscore are allowed in the property names.
  • Valid and standard variable identifiers are encouraged to be used as property names.
  • The same custom property could be defined multiple times; however, only the first value will be taken.
  • Values, defined in the content attribute, will be stored and returned as string values.

Example of usage for the Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts page on searchenginejournal.com:

<!DOCTYPE html>
<html lang="en" prefix="graphite: https://graphite.io/rdfa">

<head>
  <title>Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts</title>
  <meta property="graphite:custom:shares" content="730" />
  <meta property="graphite:custom:likes" content="50000" />
</head>

<body>
  ...
</body>

</html>

Metadata as Element Properties

This metadata specification can also be used as element properties within the HTML <body>, following the RDFa recommendation, which uses the property attribute. This approach is useful to avoid duplicating content.

Example of usage for the Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts page on searchenginejournal.com:

<!DOCTYPE html>
<html lang="en" prefix="graphite: https://graphite.io/rdfa">

<head>
  <title>Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts</title>
</head>

<body>
  ...
  <main>
    <article>
      <h1 property="graphite:title">Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts</h1>
      <p property="graphite:description">Coding knowledge turns a good SEO into a great one who's better able to stay ahead of the competition.</p>
      <h3 property="graphite:author"><a href="https://www.searchenginejournal.com/author/roger-montti/">Roger Montti</a>
      </h3>
      <ul>
        <li><time property="graphite:published_time" datetime="2022-08-13T23:45:44+00:00">August 13, 2022</time></li>
        <li><span property="graphite:read_time">14 min</span> read</li>
      </ul>
      <section property="graphite:content">
        <p>It&rsquo;s not necessary to know <a href="https://www.searchenginejournal.com/ask-an-seo-html-lightning-round/395013/">how to code</a> to be a good SEO.</p>
        <p>Coding skills are not a prerequisite for SEO competency, but additional skills always make one more effective.</p>
        <p>Here are 10 ways that understanding code can help turn a good SEO into a great one.</p>

        ...

        <p>But learning how to code can make a good SEO an even better one because knowledge provides advantages.</p>
        <h2>More Resources:</h2>
        <ul id="related-articles">
          <li><a href="https://www.searchenginejournal.com/ask-an-seo-html-lightning-round/395013/">Ask An SEO: 3 HTML &amp; Coding Questions Answered</a></li>
          <li><a href="https://www.searchenginejournal.com/top-seo-skills/229623/">Top 8 Skills Every Great SEO Professional Needs To Succeed</a></li>
          <li><a href="https://www.searchenginejournal.com/technical-seo/">Advanced Technical SEO: A Complete Guide</a>
          </li>
        </ul>
      </section>
      <div>
        <span>Category</span>
        <a href="https://www.searchenginejournal.com/category/seo/" property="graphite:category">SEO</a>
        <a href="https://www.searchenginejournal.com/category/seo/technical-seo/" property="graphite:category">Technical SEO</a>
        <a href="https://www.searchenginejournal.com/category/seo/web-development/" property="graphite:category">Web Dev SEO</a>
      </div>
    </article>
  </main>
</body>

</html>

🚧

Things to consider

  • Unavailable metadata properties as item properties are:
    • graphite:custom:*
    • graphite:language
    • graphite:location
    • graphite:type
  • There are two options for declaring the value of the graphite:image property. It is better to declare this property in the <head> section, however, because the user may need an image with a specific size as the link’s thumbnail.
    • The src attribute of an <img> tag.
    • The srcset attribute of a <source> tag, when using the <picture> element.
  • The value for a property will be all the text content of the tagged element including its descendant nodes.
  • When using graphite:content this way, the Internal Links API only considers those elements that don’t contain ancestor nodes tagged with the same property.
  • When using the time-based properties graphite:modified_time and graphite:published_time in a <time> tag, the Internal Links API will try to extract the property value from the <time> tag’s datetime attribute. If datetime is not declared, the text content will be taken.

Marking Noisy Nodes

When using a property in an HTML element that contains many children (the expected case of the graphite:content property), some of those descendant nodes may be considered noise, i.e., the API user doesn’t want the text content of them to be included in the property value.

In the Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts page example described above, the user may want to exclude the unordered list with id related-articles from the graphite:content property value because such content is the actual output of the Internal Links API, and it is desired not to feed the system back with its resultant data. For such a case, this specification provides the graphite:exclude property.

  • graphite:exclude - (multiple allowed) Use it to mark descendant nodes that should be excluded from property values. The Internal Links API will remove those nodes from the HTML document before starting the parsing process.

For the example described previously:

<!DOCTYPE html>
<html lang="en" prefix="graphite: https://graphite.io/rdfa">

<head>
  <title>Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts</title>
</head>

<body>
  ...
  <main>
    <article>
      <section>
        ...
        <ul id="related-articles" property="graphite:exclude">
          <li><a href="https://www.searchenginejournal.com/ask-an-seo-html-lightning-round/395013/">Ask An SEO: 3 HTML &amp; Coding Questions Answered</a></li>
          <li><a href="https://www.searchenginejournal.com/top-seo-skills/229623/">Top 8 Skills Every Great SEO Professional Needs To Succeed</a></li>
          <li><a href="https://www.searchenginejournal.com/technical-seo/">Advanced Technical SEO: A Complete Guide</a>
          </li>
        </ul>
      </section>
      ...
    </article>
  </main>
</body>

</html>

JSON-LD Alternative

Graphite’s Structured Data Specification is also available through JSON-LD.

Supported Metadata

  • All properties defined in Basic Metadata and Optional Metadata can be provided through a JSON-LD document embedded within the HTML response.
  • JSON-LD documents must be defined with @context and @type properties.
    • @context: "https://graphite.io/ns".
    • @type: "WebPage".
  • Properties that allow multiple definitions can be defined through JSON arrays or different JSON-LD documents using the same @context.
  • If single-value properties are defined as JSON Arrays or multiple times within JSON-LD documents using the same @context, they will be parsed to only get the first value found.
  • Unknown properties will be discarded.

Example of usage for the Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts page on searchenginejournal.com:

<!DOCTYPE html>
<html lang="en">

<head>
  <script type="application/ld+json">
    {
      "@context": "https://graphite.io/ns",
      "@type": "WebPage",
      "author": "Roger Montti",
      "category": [
        "SEO",
        "Technical SEO",
        "Web Dev SEO"
      ],
      "content": [
        "It's not necessary to know how to code to be a good SEO. Coding skills are not a prerequisite for SEO competency, but additional skills always make one more effective.",
        "...",
        "But learning how to code can make a good SEO an even better one because knowledge provides advantages."
      ],
      "description": "Coding knowledge turns a good SEO into a great one who's better able to stay ahead of the competition.",
      "image": "https://cdn.searchenginejournal.com/wp-content/uploads/2022/07/coding-1000-x-1000-1-62dfe8aa712c0-sej-552x488.png",
      "language": "en",
      "location": "US",
      "modified_time": "2022-08-14T23:45:44+00:00",
      "published_time": "2022-08-13T23:45:44+00:00",
      "read_time": "14 min",
      "title": "Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts"
    }
  </script>
</head>

<body>
  ...
</body>

</html>

Custom Metadata for JSON-LD

Custom properties are also supported through JSON-LD documents, which are the recommended way to provide custom metadata if the user wants to handle more complex data types than strings.

The custom properties should be defined within a valid JSON Object through the custom field.

Some considerations:

  • If the custom field is defined multiple times in different JSON-LD documents using the same @context, or as a JSON Array of JSON Objects, which resembles multiple definitions, it will be parsed to contain the last value found for each included property.
  • The custom field only expects valid JSON-serializable data types for each property: string, number, object, array, boolean, and null.

Example of usage for the Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts page on searchenginejournal.com:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Coding For SEO: 10 Ways Coding Skills Can Improve SEO Efforts</title>
  <script type="application/ld+json">
    {
      "@context": "https://graphite.io/ns",
      "custom": {
          "shares": 730,
          "likes": 50000
      }
    }
  </script>
</head>

<body>
  ...
</body>

</html>

What’s Next