Thank you for your interest in contributing to Configu!
Don't feel shy about contributing! All input is welcome. No fix is too trivial.
If something confuses you or feels lacking about the docs, please feel free to make an issue. If you find something that you think you can fix, please go ahead. You don't need to ask permission.
If you haven't previously contributed to other open source project, make sure to familiarize yourself with the Contributor Covenant.
The documentation content is MDX-based, specifically the second version. Make sure you know how to write proper MDX before you dive in!
A list of common gotchas:
- MDX supports standard markdown (a.k.a
CommonMark
). GFM, which stands for GitHub-Flavoured Markdown, is not supported - Know what is interleaving
- Pass HTML attributes as JSX (e.g. use
className
instead ofclass
)
Documentation is connected to the main Configu's website using rewrite proxy, and the documentation part is build using Gatsby's --path-prefix
flag.
What's important to understand:
- in dev mode, when working locally, there won't be any
/docs
part visible in documentation urls. Your entry point will belocalhost:8000
- in production, or when you run
npm run build
command, the/docs
prefix will be added to all paths on the site, making entry pointlocalhost:9000/docs
Learn more on path prefixing here
We use Segment to track user behavior on the Configu website. It is configured for both main
and docs
projects. This helps us understand how people use the site and what we can do to improve it. The setup is abstracted into a useSegmentEvent
which is being leveraged in Link
and Button
custom components. In case you ever need to add another tracking event, simply pass isClickTracked
prop to one of the mentioned component, like so:
<Button isClickTracked>Click me</Button>
<Link isClickTracked>Follow for more</Link>
This will enable yet another event that will be sending passed to
prop as a url
and text content of the button as a name
in Segment.
Note, that the isClickTracked
prop is optional and defaults to false
.
Also note, that though isClickTracked
can be leveraged in Button
component, but works only if your intention is to use Button
as a link and to
prop is passed.
For small changes and spelling fixes, the GitHub UI is most convenient. For larger contributions, consider running the project locally to see how the changes look like before making a pull request. You can build locally with Node, as described in the project's README.
Markdown files for the documentation are located in src/content
folder. The URL structure is generated by page frontmatter slug
field.
Sidebar data is stored in the src/content/sidebar.json
file.
Each Markdown page should start with the following frontmatter.
---
slug: <page-slug>
title: <page title>
---
slug
— the string with path to the page (required)title
— title of the page (required)
The source of truth for sidebar generation is stored in the src/content/sidebar.json
file. The content in this file determines sidebar hierarchy.
To add a top-level sidebar section, place a sibling in a desired position inside top-level items
array:
{
"items": [
// your new item
{
"title": "Before the overview section",
"isOpenByDefault": false, // change to true if you want the section to be open by default
"items": [
// add entries to populate the section with subpages
]
},
// an item that will lead user elsewhere from Configu's docs,
// an external link. Must begin with `http`
{
"title": "An external link to app",
"slug": "https://app.configu.com"
},
{
"title": "Overview",
"isOpenByDefault": false,
"items": [
{ "title": "Introduction", "slug": "/" },
{ "title": "Architecture", "slug": "architecture" },
{ "title": "Quick Start Guide", "slug": "quick-start" },
{ "title": "Configu's Data privacy", "slug": "data-privacy" }
]
}
]
}
.md
file used for page generation.
To add an external link to the sidebar section, place it at the desired position within the top-level external
array:
{
"external": [
// your new item
{
"title": "An external link to app",
"slug": "https://app.configu.com"
}
]
}
external
array.
Attributes breakdown:
- the
title
attribute is required and is a representation of a certain.md
page in sidebar.title
may differ from the on inside the page slug
should always match page's slug. Under the hood we define the active item by comparing current page url and the passedslug
metadata. Also, the sidebar links are being constructed using this attribute.
It is prohibited to add h1
to a page since it will be rendered automatically using the value from title
field of frontmatter.
Use typical ##
markdown definition to format headings which stands for a h2
tag, e.g:
## Quick start
The table of content will being dynamically created on each page based on h2
tags.
You can use ##
headers as landmarks, which stands for a h2
tag. h3
won't make to autogenerated table of content.
h2
, h3
, h4
heading tags in your mdx content, as h1
is reserved for the page title and h5
and h6
doesn't make sense to bring, because of the semantics and vertical rhythm.
The images should be sourced in docs directory and be used in .md
with the relative path
![Alt of an image](./configu-logo.png)
If you really have to put there some remote picture, write it like that:
![Alt of an image](https://files.readme.io/9e92efd-insights-url-table-full.png)
But keep in mind the size of an image on the other side of a link to prevent page overweighting.
You can embed videos with the native video tag.
In this case you have full control over the player – you can set the width and height, play videos automatically or not, mute or not, and so on.
A video element can contain one or more video sources. To specify the source of the video, the src attribute or the <source>
element should be used - the browser will determine the most appropriate source:
<video>
<source type="video/webm" src="video.webm" />
<source type="video/mp4" src="video.mp4" />
</video>
Don't forget that videos can and should be optimised. Finding the right format and how to optimise your video will help you in this article
- Media links are the relative paths to the file (image or video), e.g.
./images/image.png
- External links should begin with
https
protocol and will be shown with the small 🔗 icon to the right side. Only md-like links ([]()
) are getting processed like this. If you want to get an icon at thea
-tag external links, you need to specify the className asexternal-link
. - The relative links to other documentation pages should start with the slash
/
.
/docs
prefix manually in your relative links inside mdx content! It works automatically according to path-prefix feature
To improve the documentation readability, one can leverage an Admonition custom component. Wrap your piece of text with <Admonition></Admonition>
, make sure content within starts and ends with an empty line, and pass the type.
There are 5 types of Admonition: note
, warning
, info
, caution
, tip
, ; the default is note
.
You may also specify an optional title with prop title
.
Example:
<Admonition type="note" title="Your title">
// note the empty line
The branch creation process does not increase load on the originating project. You can create a branch at any time without worrying about downtime or performance degradation.
// note the empty line
</Admonition>
<Admonition type="info">
// note the empty line
The branch creation process does not increase load on the originating project. You can create a branch at any time without worrying about downtime or performance degradation.
// note the empty line
</Admonition>
Custom mdx
component that makes possible using extended Markdown syntax for descriptions lists. Fully WCAG-compliant. It provides an accessible way to make term lists, and it's a generally good way to add structure to a text when a writer needs more than bullets and less than headings.
To use the Version component, you need to include <Version></Version>
and provide its type. The type can be one of three options: green, blue, or pink.
<DefinitionList>
`-c, --clip` <Version type='green'>New in v0.31.0</Version>
: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Adipiscing massa sed ultrices sed felis volutpat ac. Congue sit nibh sed ipsum, erat facilisis mauris. Amet, est urna facilisi tempus ut amet. Pharetra orci curabitur faucibus purus in nibh. Dolor, sodales malesuada nec vitae scelerisque leo convallis ac dictumst. Euismod.
`-m, --multiline` **(boolean)** <Version type='blue'>New in v0.31.0</Version>
: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Adipiscing massa sed ultrices sed felis volutpat ac. Congue sit nibh sed ipsum, erat facilisis mauris. Amet, est urna facilisi tempus ut amet. Pharetra orci curabitur faucibus purus in nibh. Dolor, sodales malesuada nec vitae scelerisque leo convallis ac dictumst. Euismod.
**(boolean)** <Version type='pink'>New in v0.31.0</Version>
: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Adipiscing massa sed ultrices sed felis volutpat ac. Congue sit nibh sed ipsum, erat facilisis mauris. Amet, est urna facilisi tempus ut amet. Pharetra orci curabitur faucibus purus in nibh. Dolor, sodales malesuada nec vitae scelerisque leo convallis ac dictumst. Euismod.
[Stress test](/)
: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Read more: [link](/)
: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Adipiscing massa sed ultrices sed felis volutpat ac. Congue sit nibh sed ipsum, erat facilisis mauris. Amet, est urna facilisi tempus ut amet. Pharetra orci curabitur faucibus purus in nibh. Dolor, sodales malesuada nec vitae scelerisque leo convallis ac dictumst. Euismod.
</DefinitionList>
To display code tabs, wrap all pieces of code with <CodeTabs></CodeTabs>
and write labels of code tabs in order:
<CodeTabs labels={["Linux", "MacOs",]}>
// note the empty line
```shell
curl https://cli.configu.com/install.sh | sh
```
```shell
curl https://cli.configu.com/install.sh | sh
```
// note the empty line
</CodeTabs>
Collapsible accordion elements that allow to expand and collapse content by clicking on them. Could be used to hide content that is not immediately relevant to the user.
To add a collapsible to your article, use the following syntax in the .md
file:
<CollapsibleItem title="Collapsible title">
<!-- the content that will expand/collapse -->
</CollapsibleItem>
The CollapsibleItem
expects a string title
and some content.
If you want the component to be expanded by default, use optionalisOpen
prop and set it to true
: <CollapsibleItem title="Collapsible title" isOpen="true">
.
The rest of elements you could write as you would in native md: links, images, inline code, tables etc.
It is also possible that you want to use a custom UI block in a certain .md
document, not defined in this guide, like CTA button, or really any other piece of content from normal react page.
By no means do not copypaste generated html into md file, just import the component you need right into md
exactly the way you would import it on any react page and provide necessary props.
If you feel like you could use another custom component, feel free to raise an issue on this matter.
If the time is of the essence, you can create your own custom mdx component in no time.
- Check out the Gatsby documentation on this matter
- Create your component in
components/shared/your-component
- Import it in the content.mdx
- Extend the
components
constant accordingly - Use it like you would use
Admonition
orCodeTabs
!
There is a parser underneath each of those, and it works on children
prop, which is absent when empty lines are omitted
// ok! proper functioning is guaranteed
<CustomComponent>
// note the empty line
Content with [link](/link)
// note the empty line
</CustomComponent>
// sometimes ok, but not always!
<CustomComponent>
Content with [link](/link)
</CustomComponent>
// not ok!
<CustomComponent>Content with [link](/link)</CustomComponent>
A heading is a piece of text that can be turned into a link, but nothing more. We programmatically generate anchors attributes and links in ToC, so the parser can be broken quite easily.
// ok
## Heading
// also ok
## [Heading](/link)
// not ok, also that breaks the semantics
## [Heading](/link) [compound](/link2)
// parser will break trying to treat <..> as a jsx component
Piece of text that <uses.reserved> symbols
// []() is the notation for links in md, will break the parser as well
Piece of [text][that] uses reserved symbols
// {{...}} is the notation in mdx2 that assumes there is a js conde inside
Piece of {{text}} that uses reserved symbols
How to solve? Screen the symbols out with a /
!
Piece of text that \<uses.reserved\> symbols
Piece of \[text\]\[that\] uses reserved symbols
Piece of \{\{text\}\} that uses reserved symbols
There is a bug with falsy white space warning when using tables in mdx content:
Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <tr>. Make sure you don't have any extra whitespace between tags on each line of your source code..
The issue is open in MDX repo and can be tracked here.
Current workaround is to wrap thead
with curly brackets.
Example:
{/* rest of content */}
<table>
{
<thead>
<tr>
<th>Concept</th>
<th>Explanation</th>
<th>Resources</th>
</tr>
</thead>
}
<tbody>
{/* rest of content */}
This erorr usually pops up when your syntax is incorrect and the parser doesn't get a proper content to digest, thus failing to recognize the piece of content starting from the frontmatter
record itself.
There is no know workaround on how to make this error more informative. Please, try to:
- Check your mdx content is aligned with MDX spec
- Check the usage of custom components
- Check if you have screened out all the special characters that can be mistreated