AsciiDoc is a powerful format for authoring content. Like Markdown it’s simple to use, but offers more features and flexibility. In this post I’ll look at how to adapt a Gatsby site to use AsciiDoc.
🚀 TL;DR
Show me the code. Look at the 2-asciidoc
branch. This site is deployed here.
Starter Project
The Gatsby Starter Project has content pages implemented as JavaScript files. Specifically, there are three files:
index.js
page-2.js
andpage-3.js
.
During the build process these are transformed into static HTML.
This is not ideal. Content is not code. Having to write code for each new piece of content is just another source of friction in the writing process. Wouldn’t it make more sense to write content in a more suitable format?
Markdown is IMHO the best option for site content. There are many flavours of markdown. The one that we will consider now is AsciiDoc, which has a number of features which make it well particularly suited to writing documentation.
Asciidoctor & Gatsby
Asciidoctor is a text processor that translates AsciiDoc markdown into HTML5. Asciidoctor is implemented in Ruby, however, there is a JavaScript port, Asciidoctor.js. We won’t need to worry about integrating Asciidoctor.js into our Gatsby site though because there’s a transformer, gatsby-transformer-asciidoc
, to do that.
Install
Add gatsby-transformer-asciidoc
as a dependency in package.json
. Update dependencies.
Configure
Add gatsby-transformer-asciidoc
to gatsby-config.js
as a plugin:
plugins: [`gatsby-transformer-asciidoc`]
You can also specify one or more options if you need to tweak the default setup.
plugins: [
{
resolve: `gatsby-transformer-asciidoc`,
options: {
attributes: {
showtitle: true,
icons: "font"
},
fileExtensions: [`adoc`, `md`],
}
}
]
Add AsciiDoc Content
We’ll put the AsciiDoc source into a dedicated content
directory. Create three files:
content/what-is-asciidoc.adoc
content/what-is-gatsby.adoc
andcontent/what-is-tailwind.adoc
.
The content for the landing page can still be found in src/pages/index.js
. This is the only page which is implemented in JavaScript. The content for the remaining pages is all specified using AsciiDoc.
Where to Find AsciiDoc Content?
We need to tell Gatsby where it will find the AsciiDoc content. To do this we’ll add another gatsby-source-filesystem
plugin entry in gatsby-config.js
:
{
resolve: "gatsby-source-filesystem",
options: {
name: "docs",
path: `${__dirname}/content/`,
},
}
Install & Configure Tailwind CSS
This is not really necessary but it’s a very handy thing to do. Tailwind will take a lot of the pain out of styling your site.
Follow the guide here, which will instruct you to install the tailwindcss
and postcss
packages. While you’re about it, install the @tailwindcss/typography
plugin too.
There are two configuration files linked to Tailwind and PostCSS:
tailwind.config.js
(where are the files that use the Tailwind classes?) andpostcss.config.js
(informs PostCSS of thetailwindcss
package).
The Tailwind CSS is included by placing the following directives to the existing site CSS file:
@tailwind base;
@tailwind components;
@tailwind utilities;
💡 You won’t see Tailwind CSS files being explicitly included in your site. They will be bundled into the commons.css
file which is linked into all pages.
Add Layout
The files in the src/layouts
directory define the layout of page contents. They provide a consistent structure to multiple pages of the site. A page layout is defined in src/layouts/index.js
.
💡 The dedicated src/layouts
directory is no longer a special or required directory in a Gatsby project. Layout components can now be defined anywhere.
Add Template
Whereas a layout specifies the high level structure of pages, a template dictates how the page content is incorporated into the layout. Since we are using AsciiDoc to write the site content, our template needs to tell Gatsby how to translate the AsciiDoc content into page content.
Templates work in conjunction with GraphQL. A GraphQL query fetches the data from each of the AsciiDoc files and then the template controls how that content is rendered on the page.
A page template is defined in src/templates/article.js
. This is where we set up the footer content on each of the AsciiDoc pages, where the author and revision information are extracted from the AsciiDoc header.
Add a Head
The default <head>
content generated by Gatsby is sufficient to get started. However, you’ll normally want to insert more content (like SEO tags) into the <head>
. Use the Head API.
We export Head
from src/templates/article.js
and it sets a couple of SEO tags, populating them dynamically with content from the GraphQL query.
GraphQL
If you fire up a development server and head to http://localhost:8000/___graphql then you can use the GraphiQL interface to create and run GraphQL queries on the site.
Now that we have added AsciiDoc functionality you’ll see a few new top level fields, namely allAsciidoc
and asciidoc
. The former is used to generate a list of all AsciiDoc pages in gatsby-node.js
, while the latter is used for extracting page-specific content in the template.
Render AsciiDoc to HTML
Now it’s time to pull this all together. The final changes are made to gatsby-node.js
, which exports a createPages()
. This function uses a GraphQL query (the same one illustrated in the GraphiQL screenshot above) to extract information on each of the AsciiDoc pages. For each page the createPage
method is run, which generates the corresponding static HTML.
Conclusion
Using AsciiDoc makes the process of writing site content smoother and easier. The code for this post can be found here and the deployed site is here.