When you are committed to a professional project, it becomes mandatory to document it properly. This is a basic requirement because a team works on the project and a way is required to understand each others’ work. Even in case of developing an API or library, we require documentation to train the users and familiarize them with functionality.

This is an extra burden and developers try to refrain themselves from doing this. It leads to incompleteness and inconsistency. Therefore developers of Docz.js created a solution to this problem.

Introduction

Doczjs is the documentation library for React projects. As it’s tagline says, “It’s never been easier to document your things!!”. It is built on the foundation of Gatsby and MDX. Gatsby is a framework built over React which makes dynamic website development a piece of cake. On the other hand, MDX is the combination of markdown and JSX.

So how does this works? You create mdx files which is just markdown & JSX and Doczjs converts it into webpage. At the end of the article we will display the live demo of whole code.

Why choose Doczjs?

There are number of reasons to choose Doczjs for documentation. Some of them are –

  1. It’s build over Gatsbyjs which means it is very fast. Also you can use Gatsby plugins and tools here.
  2. There is no need for configuration or settings. It’s pre-packed with general use cases.
  3. MDX makes it easy to use and quick to learn.
  4. TypeScript is supported.

Using Doczjs

In this section we will learn how to use Doczjs into your project. We will start with installation.

Installation

For New Project

If you are creating a new project then you may use create-docz-app package. This will automatically install the required dependencies.

Step 1: Install create-docz-app

npm install --save create-docz-app

Step 2: Create project

In this step we will create our project. Let’s say our project is doczdemo.

npx create-docz-app doczdemo

For Existing React Project

If you want to add Doczjs to an existing project you won’t need to install create-docz-app.

npm install docz

If you are complete reactjs beginner and don’t know how to create react projects then refer this, How to use React? guide.

Running Development Version

To run the development version of docz website, use this command –

yarn docz dev

The website will be available at address – http://localhost:3000

Building Production Ready Bundle

When you are done with development and is ready to deploy on server, then use this command to create static bundle-

yarn docz build

It will create an optimized production ready version in directory .docz/dist. Copy the folder content and put on a webserver. Or, you can also try it locally using this command –

yarn docz serve

Creating mdx files

As we discussed earlier, Docz works on mdx files. So, whatever you want to document, you need to put that in those mdx files. Let’s see how to create and use these files.

First of all you should know that there is no defined location for placing your mdx files. You can put them anywhere in your project. This is one of the best thing about docz. Anyways, we will create a separate directory and will call it documentation. Here we will put all the mdx files.

Now, the directory structure will look like this –

doczdemo
├── README.md
├── node_modules
├── package.json
├── .gitignore
└── documentation

Before looking at mdx files, I would like you to know few things. First, a single mdx file is a complete webpage. It means, there will be url details as well as content. Second, the routing and navigation will be auto created for you by doczjs. Let’s understand this with an example in next section.

Navigation between pages

Suppose you have 4 webpages – index, page1, page2 and page3. The routes are – /, /page1, /page2, /page3 and titles of navigation links are – Home, Page 1, Page 2, Page 3. The format of showing this in mdx files is –

---
name: {name of link}
route: {route of link}
---

So, for all 4 pages, the mdx files will start with the above block. Check this out –

index.mdx

---
name: Home
route: /
---

page1.mdx

---
name: Page 1
route: /page1
---

page2.mdx

---
name: Page 2
route: /page2
---

page3.mdx

---
name: Page 3
route: /page3
---

Create these files and put them in documentation directory. The folder structure will look like this –

doczdemo
├── README.md
├── node_modules
├── package.json
├── .gitignore
└── documentation
    ├── index.mdx
    ├── page1.mdx
    ├── page2.mdx
    └── page3.mdx

Now run the dev server using yarn docz dev and you will see this –

doczjs navigation

You can easily navigate between pages using menu bar. It’s time to add some content to the files.

MDX

Without MDX we can’t create our files. So, let’s learn in deep. As I already said, MDX is the combination of markdown and JSX. Let’s look at both of them one by one.

Markdown Syntax

If you are already familiar with markdown then feel free to skip this section. Here we are going to list all the common syntax –

ElementMarkdown Syntax
Heading 1# Heading 1
Heading 2## Heading 2
Heading 3### Heading 3
Heading 4#### Heading 4
Heading 5##### Heading 5
Heading 6###### Heading 6
Bold**Bold**
Italics*Italics*
Ordered List1. List Item 1
2. List Item 2
3. List Item 3
Unordered List(Using *)

* List Item 1
* List Item 2
* List Item 3

(Using -)

– List Item 1
– List Item 2
– List Item 3
Nested List
(Use 3 space indentation in children lists)
1. OL item 1
   * UL Item 1.1
   * UL Item 1.2
   * UL Item 1.3
2. OL item 2
   * UL Item 2.1
   * UL Item 2.2
   * UL Item 2.3
Inline Code`Code`
Code Block“`
function myCode(){
    var a = 5;
}
“`
Horizontal Rule
Blockquote> Blockquote
Link[title](https://example.com)
Image![alt_text](https://example.com/image.jpg)
JSX

The main building blocks of React are components and JSX. We can include both in our MDX files. Simply put them in the order in which you want them to appear.

Suppose you want a div and SuperHero component then your mdx file will look like this –

---
title: DemoPage
route: /demopage
---
import SuperHero from './path/to/SuperHero'
# Heading1 - Testing JSX and React components in MDX file

<div>This is JSX and will render accordingly</div>

<SuperHero />

And, your SuperHero component is –

import React from 'react'

const SuperHero = () => <p>I am <strong>Ironman</strong></p>;

export default SuperHero;

The rendered output will appear like this –

JSX + Components = MDX

So you saw that we used markdown (# Heading 1), JSX (div) and a component (SuperHero) all in a single page (DemoPage.mdx).

Customize Documentation using Built-in Components

Why we are discussing about customization? Let’s understand this with a scenario. Suppose, you want to write documentation for Button component. Consider it as bootstrap button which has multiple properties like –

  1. Variants – Primary, Secondary, Success, Warning, Danger, Info etc.
  2. State – Active, Disabled.
  3. Type – Submit, Reset, Button.
  4. Size – sm, lg

In your documentation page, you would like to show all the information and properties associated with your component. Now you have 2 choices – Either you write this whole information in your mdx file (which is troublesome), or somehow it gets automatically created for you :).

If you are familiar with prop-types, you must know that they are used to indicate as well as restrict the props on your component. In case of libraries where multiple developers collaborate over few files, they need to know the props required by components created by different developers. This is where prop-types helps and that’s why we use them heavily in production codes.

But, why are we suddenly talking about prop-types? About 2 paragraphs back, we talked about properties of button. In production code we need to define these properties into our component file using prop-types. Can’t we directly use this for generating our documentation? Yes we can and that’s why we were talking about prop-types. In later section we will learn more about it. Check out this screenshot of how properties are shown in documentation –

Component props shown in documentation

Another important feature of documentation is live demo, where we show how the component will look like after rendering using different properties.

Documentation Playground

Doczjs provides two built-in components for these tasks – <Props> and <Playground>. In the next section, we will look at both of them in detail.

Doczjs <Props> component

Before diving into <Props> component, let’s see how prop-types are used in React components. Although its a huge topic but we will quickly see the most used operations.

We will check 3 things –

  1. What is the props data type? (Number, string, boolean, array etc.)
  2. What are the accepted values? (Like in button, the variant could be Primary, Secondary, Info, Warning etc.)
  3. What is the default value? (Default value of variant in button could be Primary)

Suppose our Button component is –

import React from 'react'

const ButtonComponent = ({children}) => <button>{children}</button>

export default ButtonComponent;

It’s a simple component which is returning the intrinsic html button element. Let’s make it a bit fancy by using React-Bootstrap. If you don’t know how to use bootstrap in React, then follow this quick guide – Use Bootstrap In React. Now the code will change to –

import React from 'react'

import Button from 'react-bootstrap/Button'
import 'bootstrap/dist/css/bootstrap.min.css';

const ButtonComponent = ({children}) => {
  return <Button>{children}</Button>
}

export default ButtonComponent;

Now we have different props for bootstrap button like size, variant, and type. Let’s add them to the code –

import React from 'react'

import Button from 'react-bootstrap/Button'
import 'bootstrap/dist/css/bootstrap.min.css';

const ButtonComponent = ({children, size, variant, type}) => {
  return <Button size={size}
           variant={variant}
           type={type}
         >{children}</Button>
}

export default ButtonComponent;

Pretty cool. Time to use prop-types in this file. One thing we have to clearly remember that it will not work with export default. You need to export it without default.

So, remove export default ButtonComponent and use export const ButtonComponent.

import React from 'react'
import Button from 'react-bootstrap/Button'
import 'bootstrap/dist/css/bootstrap.min.css';
import PropTypes from 'prop-types';

export const ButtonComponent = ({children, ...props}) => {
  return <Button {...props}>{children}</Button>
}

ButtonComponent.propTypes = {
    /**
     * Description for variant comes here.
     */
    variant: PropTypes.oneOf([
        'primary', 
        'secondary', 
        'success', 
        'warning',
        'danger',
        'info',
        'light',
        'dark', 
        'link']),
    size: PropTypes.oneOf(['lg', 'sm']),
    /**
     * Size has no description because we didn't add comment for it. 
     * This description is for type property.
     */
    type: PropTypes.oneOf(['submit', 'reset', 'button']),
}

ButtonComponent.defaultProps = {
    variant: 'primary',
    type: 'button',
}

From the code you can see that we created two objects – ButtonComponent.propTypes and ButtonComponent.defaultProps. propTypes object defines the datatype of different props. Here we want users to provide values from subset of provided lists and that’s why we used oneOf. But there are several different datatypes which we can use. For example, in case of numeric input field, we can set value prop to PropTypes.number. To add a description for a prop into documentation, use comments above that prop. The format should be like this –

/**
* Comment
*/

Second object defaultProps defines the default values for different props.

This whole prop-types thing is not a requirement or anything related to doczjs. It is a good practice for production code. Doczjs is utilizing this functionality to ease the life of developers.

Since we completed defining prop-types, its time to use built-in component <Props> in MDX file. We will show the button on index.mdx file –

---
title: Home
route: /
---

# Home Page

import {ButtonComponent} from '../src/Button'
import {Props} from 'docz'

<ButtonComponent variant={'primary'} size={'sm'}>Click Me!!</ButtonComponent>


## Properties

<Props of={ButtonComponent} />

First we imported Props from docz package using the code –

import {Props} from 'docz'

Next, used the below code to show the props list –

<Props of={ButtonComponent} />

The rendered output will look like this –

doczjs props table
Docz <Playground> component

Playground is the live demo of your component. Suppose you want to showcase different variant of button then you can show them using Playground. This helps in showing the relevant code as well as rendered output. Users are also free to make changes and view them live.

To use this built-in component, first import it and then place in mdx file just like we did for <Props> component. Let’s use it in our index.mdx file –

---
title: Home
route: /
---

# Home Page

import {ButtonComponent} from '../src/Button'
import {Playground, Props} from 'docz'

<ButtonComponent variant={'primary'} size={'sm'}>Click Me!!</ButtonComponent>


## Properties

<Props of={ButtonComponent} />

## Playground

<Playground>
    <ButtonComponent variant={'primary'}>Primary</ButtonComponent>{' '}
    <ButtonComponent variant={'secondary'}>Secondary</ButtonComponent>{' '}
    <ButtonComponent variant={'info'}>Info</ButtonComponent>{' '}
</Playground>

The rendered output will be –

doczjs playground component on button

In the above image we can see that we included 3 <ButtonComponent> with different variant prop. The Playground rendered them and displayed the code for us to play with different values. Remember, the code in the box is editable.

You can have multiple playgrounds on a single page. So, if you want to display the size prop in separate playground, you can do so by creating another <Playground> component. Check this code –

---
title: Home
route: /
---

# Home Page

import {ButtonComponent} from '../src/Button'
import {Playground, Props} from 'docz'

<ButtonComponent variant={'primary'} size={'sm'}>Click Me!!</ButtonComponent>


## Properties

<Props of={ButtonComponent} />

## Playground

<Playground>
    <ButtonComponent variant={'primary'}>Primary</ButtonComponent>{' '}
    <ButtonComponent variant={'secondary'}>Secondary</ButtonComponent>{' '}
    <ButtonComponent variant={'info'}>Info</ButtonComponent>{' '}
</Playground>

<Playground>
    <ButtonComponent size={'sm'}>Small Button</ButtonComponent>{' '}
    <ButtonComponent size={'lg'}>Large Button</ButtonComponent>{' '}
</Playground>

    Tweet this to help others

Output will look like this –

doczjs multiple playground

Live Demo

This is the live demo of the whole code. If it’s not loading here, then open it in new tab with this link – https://codesandbox.io/embed/codesandboxsse-example-forked-9pucf?fontsize=14&hidenavigation=1&theme=dark

Conclusion

To create documentation using docjs you need a basic knowledge of markdown and React. We create MDX files which gets parsed into the beautiful webpages with navigation, title bar and dark/light mode button. There are few built-in components to complete the work quickly and efficiently.

Comments

About the Author

akamit

I am Akash Mittal, an overall computer scientist. If you want to guest post, need help in your projects, want to advertise, Feel free to contact me at [email protected]

View All Articles