How MDX unified PatternFly’s documentation

Zack Allen
PatternFly
Published in
5 min readFeb 14, 2020
3 stacked white binders full of paper
Photo by Beatriz Pérez Moya on Unsplash

Documentation is never completely seamless. Everyone aims for helpful, efficient, and — of course — consistent content. But with so many content creators and file formats, stuff gets clunky.

At one time, we had that problem with PatternFly documentation. Our HTML/CSS community was writing documentation in a different format than our React community, and maintaining consistency was tricky when trying to create our combined documentation site, patternfly.org.

But we found a way. Here’s how we unified our documentation with MDX.

Documentation problems

PatternFly comes in two major offerings: HTML and React. Until recently, these offerings used two completely different systems for their documentation and were hosted on two completely different websites. Merging the two systems together into patternfly.org was error-prone for a lot of reasons:

  • Patternfly.org required copied code that would have to be updated whenever either documentation system changed.
  • Each build of patternfly.org would build our entire React library. This was because our documentation system expected to be able to import directly from source code rather than just downloading our own released build.
  • CSS issues always arose since we were importing our own styles in a variety of ways across multiple HTML and React versions.
  • Bug fixes or features made to our patternfly.org docs couldn’t easily be copied back to the HTML or React workspaces.

Yikes!

Despite all these errors, keeping the documentation separate wasn’t an option. We needed to find some way to unify both the CSS and React documentation for a unified user experience complete with full text search.

Finding common ground

Luckily, both the CSS and React workspaces were using a common build system called Gatsby. CSS had a whole host of Markdown (MD) files, while React had Javascript (JSX) files. We had multiples of these files for each example.

Two examples for PatternFly’s HTML badge component
Two examples for our HTML Badge component. Their content used to be kept in Handlebars files, a JSX file, some MD files, and a boilerplate JSX file.
Two examples for PatternFly’s React Badge component
Two examples for our React Badge component. Their content used to be kept in two separate JSX files, with an additional boilerplate JSX file to render the entire documentation page.

There’s quite a bit of overlap in the design of these docs! Yet they were stored in completely different formats. This is where MDX comes in: a new Javascript-enabled MD format.

By converting all of our docs to MDX files (where each MDX file maps to a page), we could easily load them into our site generator Gatsby to create consistent documentation pages. Here’s an example of an MDX file for HTML, which uses Handlebars (denoted by ```hbs code blocks).

 — -title: Badgesection: componentscssPrefix: pf-c-badge — -## Examples```hbs title=Read{{#> badge badge — modifier=”pf-m-read”}}...{{/badge}}``````hbs title=Unread{{#> badge badge — modifier=”pf-m-unread”}}...{{/badge}}```## Documentation### OverviewAlways add a modifier class. Never use the class `.pf-c-badge` on its own.### Usage| Class | Applied to | Outcome || — | — | — || `.pf-c-badge` | `<span>` | Initiates a badge. **Always use with a modifier class.** || `.pf-m-read` | `.pf-c-badge` | Applies read badge styling. || `.pf-m-unread` | `.pf-c-badge` | Applies unread badge styling. |

Our docs were given a fresh new syntax that includes all the content rendered on the page thanks to this pull request. No more digging around in multiple files to change content.

 — -title: ‘Badge’section: componentscssPrefix: ‘pf-c-badge’typescript: truepropComponents: [‘Badge’] — -import { Badge } from ‘@patternfly/react-core’;## Examples```js title=Read<Badge>
Read badge
</Badge>
``````js title=Unread<Badge isUnread>
Unread badge
</Badge>
```

React followed suit with a similar format. Now the way we store docs is consistent, and each documentation page maps 1:1 with a MD file.

No more copying code

Even after converting the docs to a common format, the code that used to build our three documentation sites had to be stored in three separate repositories.

Luckily, another new technology, Gatsby themes, allowed for sharing configuration across projects. By moving shared code into a Gatsby theme, we can now make sweeping changes to our HTML and React developer workspaces, or our official documentation site patternfly.org. We can change any part of the site layout, how fullscreen pages are created, or how examples are rendered without having to copy code between repositories!

Pitfalls

Gatsby isn’t perfect, and neither is MDX. While turning our Gatsby projects into first-class documentation websites, we hit a few roadblocks with our developer workspace:

  • MDX takes time to first be converted to Javascript (whereas before it started as Javascript), and Gatsby needs to handle a new file node for each MDX file.
  • The plugin we use for Gatsby and MDX called gatsby-plugin-mdx has a bug where changing the imports for an existing MDX file might require restarting the dev server.
  • Gatsby renders hundreds of more pages than it used to for a consistent documentation experience at the cost of 10–30 seconds more to start up.
  • Gatsby has to process and watch 10,000+ files to properly generate documentation, whereas before it needed to watch only around 1000.
  • We have our own system for how to render Handlebars templates tied to Gatsby lifecycle methods that don’t always hot-reload properly.

As we make our documentation better, we face a few challenges like these. So this is a good area for future work.

A better documentation experience

Flyers can now expect unified content with a consistent look and feel across PatternFly’s HTML and React offerings. On top of that, things are more efficient. Combined with Gatsby themes, our documentation code is only written in one place, and it’s easier to maintain.

The end result? A better PatternFly documentation experience for the community.

Have a UX story of your own? Send your ideas our way. More writers and fresh perspectives can only make PatternFly’s Medium publication stronger.

--

--