We’re now going to bring together what we have been building in the previous two blog posts. First we added the raw AsciiDoc source into the GraphQL schema. Next we used AsciiDoc preprocessor directives to include conditional content into the rendered content pages. Specifically, we conditionally included content on pages depending on the value of a
version attribute which was dynamically inserted into the raw AsciiDoc front matter. Now we are going to set up a URL structure which includes a version number and list the available documentation versions from the landing page.
Suppose that you have a product which is undergoing rapid development. Each new release of the product is assigned a unique version number. The product documentation is diligently updated in line with the evolving product. Ideally the documentation should be consistent with the latest release of the product. However, not all of your users will be using the latest version, so they should also be able to access older versions of the documentation.
Content pages are available for various versions of the product. For example, the “What is Gatsby?” page is available for versions 0.1, 0.2, 0.3, 1.0, 1.1 and 1.2. This is specified via the
page-version attribute in the front matter.
= What is Gatsby? :page-version: 0.1, 0.2, 0.3, 1.0, 1.1, 1.2
By contrast, the “What is AsciiDoc?” page is only available for the three most recent versions of the site, 1.0, 1.1 and 1.2.
= What is AsciiDoc? :page-version: 1.0, 1.1, 1.2
Add Versions to Landing Page
We’re going to list all available versions of the documentation on the landing page. Effectively there will also be a version of the landing page for each version of the site. The various versions of the landing page will be accessible at the following paths.
To set this up we grab the
pageAttributes.version for each AsciiDoc source document via a GraphQL query in
gatsby-node.js. Then use the
extractAllVersions() function to extract all versions, flatten into a single list and remove duplicates. We iterate over the resulting list of versions and create the corresponding landing page with the
createPage() function, specifying a version-specific path as listed above.
The component for the landing page last a list of versions (as links) and text which indicates the currently selected version. It also has links to the content pages available for the selected documentation version.
Below is an image of the landing page at
/1.2/ (the latest version of the documentation). There are links to six content pages. The links are version-specific, with “What is Gatsby?” linking to
/1.2/what-is-gatsby/ and “What is Tailwind?” linking to
And this the landing page at
/0.1/ (the first version of the documentation). Note that the “Selected version” text has changed and that the list of content pages is reduced to just a single item. The link is version-specific, and “What is Gatsby?” points to
Default Landing Page
There is one small problem. Now that we have version-specific landing pages there is no default landing page and
/ returns a 404 error. There are (at least) two possible solutions:
- create another page at
- add a redirect from
/to the most recent version of the landing page at
The second option seems more elegant.
Actually, when the source for the landing page is named
src/pages/index.js a default version of this page will always be generated, without an explicit call to
createPage(). In principle this would be fine. However, since we are opting for a redirect, we actually don’t want this page to be generated. To prevent this we’ll rename
src/pages/home.js. This means that we need to update the path specified in the call to
We also need to call
createRedirect() to generate the redirect.
In this post I showed how to add a simple version selector into the landing page. Each version of the landing page is located at a specific URL and there’s a redirect from the default landing page path,
/, to the most recent version. The list of content pages on the landing page updates according to the available versions of the content pages.