Make your resume SEO friendly using JSON Resume with microdata

RMAG news

How to generate your resume with schema.org vocabulary HTML markup using JSON Resume, allowing your resume to be understood by search engine crawlers and other machines.

tl;dr

Using JSON Resume with the jsonresume-theme-microdata theme will create a resume documented with microdata following the Schema.org vocabulary set.

Prerequisites

You skimmed How to Boost SEO by Enhancing HTML with Microdata or you know how to add microdata to HTML
You know what objects and arrays are in programming
You have a general understanding of JSON Schema

Quick Tech Primer

This was originally one article, but I couldn’t easily write about adding structured data to JSON Resume without explaining structured data itself. So…it’s now a series and this article is gonna focus on adding microdata to your resume using the open source JSON Resume schema. There’s a 3rd one, but I’m still cooking it.

What is structured data, microdata, Schema.org vocabulary?

See How to Boost SEO by Enhancing HTML with Microdata for details. The article includes code examples and schema output.

Cliff notes:

structured data? web 3-ish: Google explains structured data

Schema.org? Founded by Google, Microsoft, Yahoo and Yandex: Schema.org
Schema.org Vocabulary? common content Types and property names: the Person type, the Article type

microdata? micridata primer, YouTube: Microdata vs JSON-LD: Which Structured Data Format Wins?

microdata in HTML? see 1st article and the Schema.org microdata usage guide

microdata validation? Schema.org’s validator, Google’s Rich Results Test

What is JSON Resume?

To explain adding structured data to HTML, it made sense to use a commonly-known set of data. JSON Resume fits that bill and gave me a great reason to update the HTML of my resume.

If you’re unfamiliar with JSON Resume, it’s core-premise is creating a standard data structure for a resume’s content. The JSON in “JSON Resume” refers to the JSON schema which details the expected data structure of each piece of data.

Basically it’s a detailed content-model of commonly-used resume content which has been open-sourced and widely adopted.

JSON Resume website: jsonresume.org – to dig deeper

the JSON Resume schema – to see our content model

JSON Resume themes – 400+ themes available!

JSON Resume tools/projects – resume editors, LinkedIn resume converters, validators, pdf exports, etc

JSON Resume example

Here is my resume.json file in a GitHub gist which is then combined with a JSON Resume theme and served up via the free and open-source JSON-resume-as-a-service here: registry.jsonresume.org/scottnath?theme=even

![Image has four examples of JSON Resume themes styling Scott Nath’s resume][img-themes]

resumes styled by themes, theme names left to right: kendall, mantra, even, stackoverflow

What is jsonresume-theme-microdata?

jsonresume-theme-microdata is a JSON Resume theme. It looks pretty much like the ⬆️ third one in the image above.

It is distributed as an npm package and is a fork of jsonresume-theme-even. The jsonresume-theme-microdata version has the same styles as jsonresume-theme-even (for the most part). The main differences is the microdata fork has some HTML changes and the addition of microdata throughout the HTML.

Luckily, the even theme already had good semantic HTML structure, so not tons of HTML changes – mostly converting sections to use description lists. DL’s are my jam – a totally underused set of elements.

See this basic example usage in the examples directory in the jsonresume-theme-microdata github repo

Explainer: adding structured data to a JSON Resume theme

A breakdown of how I adjusted the HTML and microdata.

This is just a subset of the changes – the JSON Resume schema is pretty big.

Step 1: Look at two similar, but different sections

basics is all the metadata about you, the person, so name, phone, label (“e.g. Web Developer”), image, etc.

work is your work history

volunteer is your volunteer history

The similarities between volunteer and work are that you spent time at an organization, and that you had a position there. Here is the relevant subset of the data, using the JSON Resume schema structure.

{
“basics”: {
“name”: “Scott Nath”,
},
“work”: [
{
“name”: “Company ABC”,
“description”: “…company description…”,
“position”: “Software developer”,
“summary”: “…details about position…”,
},
{
“name”: “Company Meow”,
“position”: “Sitting”,
},
],
“volunteer”: [
{
“name”: “Company 501c3”,
“position”: “Software developer for free”,
“summary”: “…details about position…”,
}
]
}

Step 2: Write semantic HTML which matches the resume data hierarchy

Making an article with h1 cause a resume on a page should be the main document.

<article>
<h1>Scott Nath</h1>
<section>
<h2>Work History</h2>
<article>
<h3>Company ABC</h3>
<p>…company description…</p>
<h4>Software developer</h4>
<p>…details about role…</p>
</article>
<article>
<h3>Company Meow</h3>
<h4>Sitting</h4>
</article>
</section>
<section>
<h2>Volunteer History</h2>
<article>
<h3>Company 501c3</h3>
<h4>Software developer for free</h4>
<p>…details about role…</p>
</article>
</section>
</article>

Step 3: Add microdata, using Schema.org types

A resume describes a person, so the primary itemscope of your resume will be schema.org/Person. For both volunteer and work, the person needs to connect to them in the structured data, so they are an alimni of the orgs: schema.org/alumniOf. alumniOf is a property of Person

The organization for both types would have itemscope schema.org/Organization, but Organization has a lot of specific Types available on top of it – Airline, LocalBusiness, NGO, EducationalOrganization – but since that specificity is hard to automate, for now the microdata theme labels all these an Organization Type.

The position is something that happened inside the organization. Here the semantic HTML aligns great with the schema.org Types! (yes, a section was added…but…still semantic!) To connect the position is itemprop employee. Then, to describe the employee, we’re using a more specific Type of Person, EmployeeRole.

<article itemscope itemtype=“https://schema.org/Person”>
<h1 itemprop=“name”>Scott Nath</h1>
<section>
<h2>Work History</h2>
<article itemprop=“alumniOf” itemscope itemtype=“https://schema.org/Organization”>
<h3 itemprop=“name”>Company ABC</h3>
<p itemprop=“description”>…company description…</p>
<section itemprop=“employee” itemscope itemtype=“https://schema.org/EmployeeRole”>
<h4 itemprop=“roleName”>Software developer</h4>
<p itemprop=“description”>…details about role…</p>
</section>
</article>
<article itemprop=“alumniOf” itemscope itemtype=“https://schema.org/Organization”>
<h3 itemprop=“name”>Company Meow</h3>
<section itemprop=“employee” itemscope itemtype=“https://schema.org/EmployeeRole”>
<h4 itemprop=“roleName”>Sitting</h4>
</section>
</article>
</section>
<section>
<h2>Volunteer History</h2>
<article itemprop=“alumniOf” itemscope itemtype=“https://schema.org/Organization”>
<h3 itemprop=“name”>Company 501c3</h3>
<section itemprop=“employee” itemscope itemtype=“https://schema.org/EmployeeRole”>
<h4 itemprop=“roleName”>Software developer for free</h4>
<p itemprop=“description”>…details about role…</p>
</article>
</section>
</article>

Step 4: Validate your microdata to output the data

Using validator.schema.org, we can copypasta the HTML above and below is the validator output.

Person
@type Person
name Scott Nath
alumniOf
@type Organization
name Company ABC
description …company description…
employee
@type EmployeeRole
roleName Software developer
description …details about role…
alumniOf
@type Organization
name Company Meow
employee
@type EmployeeRole
roleName Sitting
alumniOf
@type Organization
name Company 501c3
employee
@type EmployeeRole
roleName Software developer for free
description …details about role…

Other fun data structues that were added

Here’s a few of the other data types that came out as interesting ways to connect to Person

basics.profiles is all your social network profiles

These I chose ContactPoint as the Type, making HTML like:

<dl>
<div itemprop=“ContactPoint” itemscope=“” itemtype=“https://schema.org/ContactPoint”>
<dt itemprop=“contactType”>Mastodon</dt>
<dd data-network=“Mastodon”>
<a href=“https://mastodon.social/@scottnath” itemprop=“url”>
<span itemprop=“identifier”>scottnath@mastodon.social</span>
</a>
</dd>
</div>
<div itemprop=“ContactPoint” itemscope=“” itemtype=“https://schema.org/ContactPoint”>
<dt itemprop=“contactType”>DEV</dt>
<dd data-network=“DEV”><a href=“https://dev.to/scottnath” itemprop=“url”><span itemprop=“identifier”>scottnath</span></a></dd>
</div>
</dl>

which ends up with this structure:

Person
@type Person
name Scott Nath
contactPoint
@type ContactPoint
contactType Mastodon
url https://mastodon.social/@scottnath
identifier scottnath@mastodon.social
contactPoint
@type ContactPoint
contactType DEV
url https://dev.to/scottnath
identifier scottnath

I added specificity with skills to allow itemtype

Here’s a couple skills from my resume.json:

“skills”: [
{
“level”: “Senior”,
“name”: “Languages”,
“itemtype”: “ComputerLanguage”,
“keywords”: [
“Javascript”,
“Typescript”,
“CSS”,
“HTML”,
“Bash/Shell”,
“Gherkin”,
“Python”,
“PHP”
]
},
{
“level”: “Senior”,
“name”: “UI Components”,
“itemtype”: “SoftwareSourceCode”,
“keywords”: [
“Web Components”,
“VueJS”,
“Lit”,
“Sass”,
“HandlebarsJS”,
“ReactJS”,
“AngularJS”
]
},
]

which came out as very interesting structured data in that it’s nice to have information about me labeled like this in the wild:

Person
@type Person
name Scott Nath
knowsAbout
@type ComputerLanguage
description Languages
name Javascript
name Typescript
name CSS
name HTML
name Bash/Shell
name Gherkin
name Python
name PHP
knowsAbout
@type SoftwareSourceCode
description UI Components
name Web Components
name VueJS
name Lit
name Sass
name HandlebarsJS
name ReactJS
name AngularJS

kewl!!

This is long, let’s stop

Thanks for reading. If you’d like to see the full data model extracted from my resume here is the Google Rich Results Test which shows all the data extracted from my resume using the jsonresume-theme-microdata theme.

Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *