Annotating my pages with microformats2 and h-entry
Tags: microformats, parsing, gatsby, html
Published: 2020-10-06 12:44:33

---
title: Annotating my pages with microformats2 and h-entry
published: true
description: I was looking for ways to make my site open to syndication—h-entry is an open microformat for datestamped content on the web.
tags: microformats, parsing, gatsby, html
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/7ei8syebhwkcc3e5751u.png
canonical_url: https://mnguyen.io/blog/annotating-pages-microformats2-h-entry/
---

h-entry is an open microformat for datestamped content on the web. I was looking at ways to make my site a bit more open to syndication, and also as an alternative to RSS/Atom feeds. I haven’t seen major browsers pick up on these formats, but the main focus are IndieWeb readers, and I’m all for them.

Now, please note that this post isn’t much of a guide to implementing h-entry or other parts of the microformats2 spec on your site, as it is a summary of I went about implementing it for this website.

## What it looks like

```js
{
  "items": [
    {
      "type": [
        "h-entry"
      ],
      "properties": {
        "name": [
          "My blog post"
        ],
        "author": [
          {
            "value": "John Smith"
          }
        ],
        "published": [
          "2020-01-01 12:00:00"
        ],
        "summary": [
          "A short summary of my blog post, and what you can do."
        ],
        "content": [
          {
            "value": "Starting paragraph of my blog post.",
            "html": "<p>Starting paragraph of my blog post.</p>"
          }
        ]
      }
    }
  ]
}
```

In short, there’s basically all of the information about the post, in a JSON object that could be easily be used as part of a different app. With that in mind, how does a parser go about doing this?

## Elements of h-entry

h-entry itself is a what is known as a root class name. We can use it to define a h-entry, and it has a series of properties that the parser will determine, based on knowing that. Other root class names include:

  - h-adr
  - h-event
  - h-geo
  - h-item
  - h-product
  - h-recipe

You can find a more detailed list of these on the [microformats2 page](https://microformats.org/wiki/microformats2), along with examples and detailed descriptions.

Back to h-entry, we can establish this simply by naming it as a class:

```html
<article class="h-entry">
...
</article>
```

and that’s it, our article is now parseable as it is, though it might not be very useful by itself. This is where we add some core h-entry properties!

## h-entry properties

There’s quite an amount of these, so I’ll only go with the properties that I used for this site.

### p-name

This represents the entry name or title. For the title, we just need to add this class to the element that contains it:

```html
<h1 class="p-name">{post.frontmatter.title}</h1>
```

### e-content

The full content of the entry in question i.e. the full body of the blog post:

```html
<section class="e-content">...</section>
```

### dt-published

The datestamp of when the entry was published:

```html
<time class="dt-published" datetime="2020-09-29">29 September, 2020</time>
```

## Implementing h-entry within a Gatsby content type

Let’s get topical! For this, I’m using [Gatsby](https://mnguyen.io/blog/my-gatsby-setup/) as my site generator, so in order to get this working for my blog post, I need to modify the template for the blog post’s render function (located in `/src/templates/blog-post.js`), which returns JSX as follows:

```js
export default ({data}) => {
  const post = data.markdownRemark
  return (
    <Layout>
      <SEO title={post.frontmatter.title} description={post.excerpt} />
      <section className="h-entry">
        <h1 style={{marginBottom: `0.5rem`}} className="p-name">{post.frontmatter.title}</h1>
        { post.frontmatter.draft ? (
          `Draft`
        ) : (
          <time className="dt-published" dateTime={post.frontmatter.htmldate}>{post.frontmatter.date}</time>
        )}
        <section className="e-content" dangerouslySetInnerHTML={{ __html: post.html }} />
      </section>
    </Layout>
  )
}
```

You can see that the 2 `section`, the `h1`, and the `time` elements are updated as above to have the microformat2 elements defined via the `className` attribute. While I was able to get it working on these generic HTML elements, I wasn’t able to get it working for the `time` element, which was previously a separate element called `<DateTime>`. I couldn’t figure it out, so I reverted to using the base element that it represented.

## Further reading

- [microformats2 on microformats.org](https://microformats.org/wiki/microformats2): has a lot of information about microformat types that I’ve only just touched on in this post.
- [h-entry on microformats.org](https://microformats.org/wiki/h-entry): provides information specific about h-entry, including some other optional properties I didn’t use in this post.
- [h-entry on indieweb.org](https://indieweb.org/h-entry): has some extra reasoning why you should use h-entry, as well as examples and use cases spanning from it.

Implementing a microformat isn’t difficult, and can provide new ways for people to access your content. Give it a go!