Including Schema.org Data in A PostHTML Component with Parcel.js
I love Parcel.js to build static websites. It's really neat. There is one common use-case, I recently had to wrap my head around. Utilizing reusable code. I used to have only a one-pager website (really, just an index.html) up to this point. However, with the rewrite of my personal page, I wanted to have more pages. Hence, I needed to figure how to reuse a header.
Luckily, generally spoken, that is super simple with Parcel.js and PostHTML. Really, all you have to do is create an HTML file and put it in via include
. You can even pass parameters with a special syntax. Read more about that here: https://parceljs.org/languages/html/#posthtml.
There was one issue with that. I didn't know how to pass Schema.org data. The problem was, that I used it with JSON-LD. That works through a script
tag. Usually, you have something like:
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@id": "#record",
"@type": "Book",
"additionalType": "Product",
"name": "Le concerto",
"author": "Ferchault, Guy",
"offers":{
"@type": "Offer",
"availability": "https://schema.org/InStock",
"serialNumber": "CONC91000937",
"sku": "780 R2",
"offeredBy": {
"@type": "Library",
"@id": "http://library.anytown.gov.uk",
"name": "Anytown City Library"
},
"businessFunction": "http://purl.org/goodrelations/v1#LeaseOut",
"itemOffered": "#record"
}
}
</script>
That format is what Google (or, more specifically, the Chrome team) recommends when it comes to Schema data.
Now we have a slight problem. You cannot pass JSON that easily, nor can you pass a whole HTML tag. At least not to my knowledge. However, at the same time, I didn't want to rewrite my whole Schema data, so I fiddled a bit with it.
At the end of the day, my solution was to create another reusable component as a file to be included with the original component (a header in my case). This include
tag accepts a src
attribute, that can be filled by the PostHTML parameter syntax! Hurray.
Okay, step by step. You have your HTML page. You want to have your header on there, without needing to maintain it for each page separately. So you create an HTML file for the header, that can be included via PostHTML. You parametrize all the dynamic attributes, like title
, keywords
and thereof.
PAGE.html ──includes──► HEADER.html ──includes──► SCHEMA-FILE.html
│
│
passes parameters including a src (path) to the schema file
One of those parameters is the path to the schema file that you can pass to the src
attribute of the include
tag within the header.
Thus, when everything is glued together, the page requests PostHTML to include the header, which requests to include the schema file as configured by a parameter.
The Page Includes the Header
<include src="./src/components/head.html">
{
"title": "Foobar",
"schemaFile": "./src/schemas/index-schema.html"
}
</include>
The Header Includes the Schema
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{title}}</title>
<include src="{{schemaFile}}" />
</head>
The Schema File Contains the Data
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Foobar"
}
</script>