Adding Custom Attributes to Pages in a Gatsby Site

It can be useful to embed additional metadata into content pages on a Gatsby site. In this post we’ll take a look at how to add fields to the header of AsciiDoc files. These fields will be accessible via GraphQL.

🚀 TL;DR Show me the code. Look at the 9-add-graphql-fields branch. This site is deployed here.

Initial GraphQL

We’ll begin with the site created in a previous post.

GraphQL Explorer.

Taking a look at the GraphQL content accessible under allAsciidoc we see that there is metadata pertaining to the author, the title and subtitle of the post. There’s a slug field, which determines the appropriate page URL. There’s also revision information (but this is not included in the query above, although it’s visible at the bottom of the Explorer panel).

AsciiDoc Header

The information for these fields comes from the headers of each of the AsciiDoc source files. Here’s an example:

= What is Gatsby?
Some Fictional Dude <some-fictional-dude@gmail.com>
v2.0, October 2023: Rewritten for version 2
:description: An explanation of Gatsby.

If present, the header must always occur at the top of the AsciiDoc file (there cannot be any content above the header).

The first line of the header specifies the document title. This is followed by author information and revision information, each of which must conform to a specific layout. These are then followed by (optional) attribute entries. The names of the attributes are enclosed by colons. There are a number of built-in attributes and you are free to add your own user-defined attributes.

Built-in Attributes

Available built-in attributes include the following:

  • :author:
  • :title:
  • :revdate: — revision date
  • :revnumber: — revision number
  • :revremark: — revision remark
  • :doctype: — document type
  • :toc: — whether to generate a table of contents
  • :sectnums: — whether to number sections
  • :sectnumlevels: — depth of section numbering
  • :sectanchors: — whether to generate section anchors
  • :imagesdir: — location of images
  • :icons: — whether to use icons
  • :data-uri: — whether to embed images as data URIs
  • :source-highlighter: — the source code highlighter
  • :stem: — the processor for block equations
  • :linkattrs: — whether to allow attributes in links
  • :pdf-style: — custom style for generating PDFs
  • :pdf-fontsdir: — location of custom fonts for PDFs and
  • :pagenums: — whether to show page numbers in PDFs.

User-Defined Attributes

There are some guidelines for the names of user-defined attributes:

  • names should only contain alphanumeric characters, hyphens, and underscores
  • avoid starting a name with a number
  • names are case-insensitive and
  • avoid using names that conflict with built-in or system attributes.

It’s good practice to use meaningful names for user-defined attributes to make the document more maintainable and understandable.

Although there’s a lot of freedom in choosing custom attribute names, when using the gatsby-transformer-asciidoc these attributes should all begin with page-. We’ll add three attributes to each of the AsciiDoc files in the project:

  • page-version
  • page-order and
  • page-permalink.

After adding these attributes the document header might look like this:

= What is Gatsby?
Some Fictional Dude <some-fictional-dude@gmail.com>
v2.0, October 2023: Rewritten for version 2
:description: An explanation of Gatsby.
:page-version: 0.3, 1.0, 1.1, 1.2
:page-order: 10
:page-permalink: d2b6d682

Final GraphQL

The new fields are accessible via GraphQL under pageAttributes.

GraphQL Explorer after adding custom attributes.

Conclusion

There are a variety of reasons for why one would add user-defined fields to the AsciiDoc header. Foremost among these IMHO is the ability to use those fields to determine how the content is processed. In upcoming posts we’ll take a look at how this might be done:

The code for this post can be found here on the 9-add-graphql-fields branch.