Skip to content

Latest commit

 

History

History
667 lines (441 loc) · 22.3 KB

gatsby-reference.md

File metadata and controls

667 lines (441 loc) · 22.3 KB

Contributor's reference

The k6 documentation is a Gatsby application using React components and markdown files for the content of the different pages.

There are two types of pages: Welcome Pages and Documentation articles.

Welcome Pages are the pages shown on the header menu: Guides, JavaScript API, Cloud Docs, Integration, and Examples. They are made as separate React Components for maximum customisation.

Documentation articles are markdown files structured under the src/data/markdown/docs folder.

Folder structure

Root folders represent main categories at the top of the page. Use numbers in front of the folder name to set the order.

Pattern: {number}{space}{page name}

Example: 02 Hello world

The same pattern used to define orders not only root folders but also pages(md files) inside the category.

Links

The root of the site begins at k6.io/docs.

So /cloud as an anchor will render as k6.io/docs/cloud.

Redirects

Everytime you change a page path, you MUST program in a redirect at gatsby-node.js. Search createRedirect and follow the syntax.

Test redirects in staging.k6.io before deploying.

Headings

Use typical ## markdown definition to format headings.

## Making HTTP requests

Make sure you are using '##' which stands for a h2 tag - h1 is reserved for the title of a page, that gets parsed from the frontmatter. Also the table of content that is being dynamically created on each page based on h2 tags.

internal-images/Untitled%202.png

You can use h2 and h3 headers as landmarks. h3 won't make to autogenerated table of content.h4 tag is designed to be used in your blockquote heading, like that:

internal-images/Untitled%203.png

And h5,h6 have no specified styles, therefore will be rendered by default very similar to h1, so you probably do not want to use them, but if there are use cases, please, let us know.

Headings with custom anchors

By default the anchor for h2 and h3 will be autogenerated based on its plain text content. However, you can change this behavior by passing a custom anchor like this:

## Making HTTP requests {#http-requests}
<!-- or -->
## Making HTTP requests {http-requests}
<!-- or even -->
## Making HTTP requests {http Requests}

Now the value in curly brackets will be anchorified (stripped out of special chars, lowercased and formatted) and used as the anchor.

The parser somewhat fault-tolerant and can handle following cases:

## Remove me: default {#test-0}
<!--yields id="test-0", anchor href="#test-0" -->
## Remove me: default no hash {test-1}
<!--yields id="test-1", anchor href="#test-1" -->
## Remove me: default no hash free content {test 1 Absolutely free text content}
<!--yields id="test-1-absolutely-free-text-content", anchor href="#test-1-absolutely-free-text-content" -->
## Remove me: default double brackets {test-2}{}
<!--yields id="test-2", anchor href="#test-2" -->
## Remove me: default faulty double brackets with content {test-3}{#test-faulty}
<!--yields id="test-3", anchor href="#test-3" -->
## Remove me: [compound link](/nope) {#test-4}
<!--yields id="test-4", anchor href="#test-4" -->
## 🚀 Remove me: [compound link](/nope) with emoji 🚀 {#test-5}
<!--yields id="test-5", anchor href="#test-5" -->
## 🚀 Remove me: `compound code` with emoji 🚀 {test-6}
<!--yields id="test-6", anchor href="#test-6" -->
### 🚀 Remove me: `compound code` low hierarchy 🚀 {test-7}
<!--yields id="test-7", anchor href="#test-7" -->
See the result

Images

Default image syntax for markdown files

![Alt of an image](../internal-images/insights-url-table-full.png)

Note, that path begins with /, not just images/.

Every image with the contents of the title attribute, when this is not empty, turns into image with the caption

![Alt of an image](../internal-images/insights-url-table-full.png "Title that will be used a caption")

Store images relative to a source .md file, and access them from .md files by using relative path. image-sharp-plugin will handle your image: compress, convert and lazy load.

Example file structure

.
├── markdown
│   └── article
|       ├── article.md
|       ├── image.png

or

.
├── markdown
│   └── article
|       ├── article.md
|       ├── images
|           ├── image.png

or, in more comples scenarios:

.
├── markdown
│   └── article cluster
│       └── images
│           └── article-1
|               ├── image.png
│           └── article 2
|               ├── image.png
│           └── article 3
|               ├── image.png
│       └── article 1
|           ├── article 1.md
│       └── article 2
|           ├── article 2.md
│       └── article 3
|           ├── article 3.md

If you really have to put there some remote picture, write it like that:

![Alt field 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.

There are also cases when the path to an image contains white space characters. You have to replace them with % sign, like on the screenshot below:

Alt field of an image

Note, that for some reason not every %-ed path with spaces works everytime. The truly foolproof solution is using kebab only case: like [](/images/kebab-cased-folder-name/kebab-cased-image-name.png)

Blockquotes or admonitions

Here things are getting a bit hairy. It is still default md, so it is perfectly fine to write blockquotes like:

> #### Docker syntax
>
> When using the `k6` docker image, you can't just give the script name since
> the script file will not be available to the container as it runs. Instead
> you must tell k6 to read `stdin` by passing the file name as `-`. Then you
> pipe the actual file into the container with `<` or equivalent. This will
> cause the file to be redirected into the container and be read by k6.
>
> **Note**: If your script imports other files (JS modules), piping like this
> will not work since the extra files will not be visible inside the container.
> To use modules you need to first mount your host/local directory into the
> Docker container, see [Modules with Docker](https://docs.k6.io/v1.0/docs/modules#section-using-local-modules-with-docker)."

And you'll get a fine quote block:

internal-images/Untitled%204.png

The <Blockquote> component

It is also possible to adjust your admonition theme using custom Blockquote wrapper. This wrapper accepts the following props:

  • mod, one of [note, warning, attention, default]. Optional, default value is default. Passing any non-default value will display corresponding kicker with an icon.
  • title. Optional. If passed, will replace default text in the kicker. Title is getting wrapped with h4 tag and beas id attribute to be able to be anchored to. ⚠️ Make sure title is unique across the page
<Blockquote mod="Attention" title="An attention title">

Here's what it looks like.

</Blockquote>   

image

More examples

Pay attention to those empty lines between md block and a wrapper, they are required to correctly parsing.

Also pay attention, that usage of Blockquote requires omitting native md blockquote syntax, so you just put your content inside without any > and you are good to go.

Description list

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.

The usage is pretty straightforward:

<!-- other content here -->

<DescriptionList>
<!-- required new line -->
Scenario executor
: First definition
: Second definition

Soak test
: First and only definition

Smoke test
Another term for smoke test
: First definition for both terms
: Second definition for both terms
: ...n definition for both terms

[Stress test](/)
: First and **only** definition for both terms with additional markup <br/> Read more: [link](/)

<!-- required new line -->
</DescriptionList>

<!-- other content here -->

Acceptable markup for term

  • *italic*
  • [link](/)
  • **strong** - but that doesn't make sense, by default terms appearance is already bold
  • inlineCode - but it doesn't alter it's change in this context

Batteries

DefinitionList is backward-compatible with the old way of representing terms and definitions, via h3 tag and custom content. h3 tag by default had an anchor icon and a id attribute, similar to how it works on GitHub.

So our dt (term) has an id att and the same anchor as well!

⚠️ Beware of the contstrainst though:

  • using emojis in dt is prohibited, as it potentially can mess up with id attribute, and href at anchor. We can not be sure which range will be used to display a particular symbol (depends on editor OS) and if it is going to be stripped.
  • if there are multiple terms for a given set of descriptions, only the first one will have an id and an anchor
  • make absolutely sure your dt text content is unique across the page to avoid id collisions

Acceptable markup for description

  • everything for term
  • emojis
  • any inline html
  • line breaks <br/> (recommended way to separate visually something inside a single description)
Examples

Code blocks

So, there are basically three types of code blocks, small ones, headerless ones and headerfull ones,

that last two have one possible modification - line numbers.

Small

No hardwork required, just wrap your small stuff like keywords in backticks:

`API_VARIABLE` should be stored under a pillow

and you are good to go!

internal-images/Untitled%206.png

If your code contains backticks, use <CodeInline> wrapper instead:

Hide a field with <CodeInline>`js: "-"`</CodeInline>

Headerless

We are going to write them a bit differently, half-native md:

<!-- some other content -->

    ```javascript
    for (var id = 1; id <= 100; id++) {
       http.get(http.url`http://example.com/posts/${id}`)
    }

    // tags.name="http://example.com/posts/${}",
    // tags.name="http://example.com/posts/${}"
    ```

<!-- some other content -->

And, as a result:

internal-images/Untitled%207.png

If we want line numbers to be rendered, we shall add the wrapper and adjust our props to:

<CodeGroup labels={[]} lineNumbers={[true]}>

```javascript
for (var id = 1; id <= 100; id++) {
 http.get(http.url`http://example.com/posts/${id}`)
}

// tags.name="http://example.com/posts/${}",
// tags.name="http://example.com/posts/${}"
```

</CodeGroup>

Here you go:

internal-images/Untitled%208.png

Headerfull

Pretty much the same routine as with headerless ones, but with one difference in props, labels field, but I bet, you already got that:

<CodeGroup labels={["Nice code!"]} lineNumbers={[true]}>

```javascript
for (var id = 1; id <= 100; id++) {
 http.get(http.url`http://example.com/posts/${id}`)
}

// tags.name="http://example.com/posts/${}",
// tags.name="http://example.com/posts/${}"
```

</CodeGroup>

internal-images/Untitled%209.png

Multiple tabs

To be able to switch between different code tabs, we have to repeat the headerfull routine, but extend labels and md code blocks:

<CodeGroup labels={["Nice code!", "This one is better", "Oh my.."]} lineNumbers={[true, true, true]}>

```javascript
for (var id = 1; id <= 100; id++) {
 http.get(http.url`http://example.com/posts/${id}`)
}

// tags.name="http://example.com/posts/${}",
// tags.name="http://example.com/posts/${}"
```

```javascript
for (var id = 1; id <= 100; id++) {
 http.get(http.url`http://example.com/posts/${id}`)
}

// tags.name="http://example.com/posts/${}",
// tags.name="http://example.com/posts/${}"
```

```javascript
for (var id = 1; id <= 100; id++) {
 http.get(http.url`http://example.com/posts/${id}`)
}

// tags.name="http://example.com/posts/${}",
// tags.name="http://example.com/posts/${}"
```


</CodeGroup>

internal-images/Untitled%2010.png

Notes on code blocks

Languages

There is a curated list of available languages that you should use when working with code blocks:

  1. bash covers all terminal code
  2. javascript for blocks with JS code
  3. json for JSON structures
  4. diff for showing diffs
  5. markup covers html and xml
  6. go for Go code
  7. plain for everything else, plain unhighlighted text

Every other language, including languages from list but with grammar or case mistakes will be rendered as a plain by default.

Let us know if there is necessity to bring highlight support for another language.

Copy button

'<CodeGroup labels={["CLI", "Docker"]} showCopyButton={[false, true]}>'

showCopyButton: whether to show or hide the copy button. Default is true.

Line numbers

'{"labels": ["Nice code!", "This one is better", "Oh my.."], "lineNumbers": [true, true, true]}'

Line numbers are optional not for the whole code block, but for each tab. That is why here we have an array of bool.

Text in-between tabs

See 'Then do this?' text line between tabs? You can not do that. Put nothing in code-group except code blocks, or you'll broke the page.

<CodeGroup labels={["Nice code!"]} lineNumbers={[true]}>

```javascript
for (var id = 1; id <= 100; id++) {
 http.get(http.url`http://example.com/posts/${id}`)
}

```

Then do this:

```javascript
for (var id = 1; id <= 100; id++) {
http.get(http.url`http://example.com/posts/${id}`)
}

```

</CodeGroup>

Height control

You can provide large code blocks (>400px, ~20 LoC) with expand/collapse toggler that will allow users to control code block's height.

Code Block States

Prop heightTogglers passed to CodeGroup component makes it possible, which works very similar to labels and lineNumbers props:

<CodeGroup labels={["Nice code!", "This one is better", "Oh my.."]} lineNumbers={[true, true, true]} heightTogglers={[true, false, false]}>

```javascript
// a lot of lines of code,
// maxHeight of this code block will be set to `400px`
// and a toggler will appear
```

```javascript
// a lot of lines of code, default behavior
```

```javascript
// a lot of lines of code, default behavior
```


</CodeGroup>

Table data

In md file it should look like this to be formatted as a table. You could use online markdown tables generator to simplify the process – https://www.tablesgenerator.com/text_tables

|                                     |                                     |
|-------------------------------------|-------------------------------------|
|[batch()](https://docs.k6.io/docs/batch-requests) | Issue multiple HTTP requests in parallel (like e.g. browsers tend to do) |
|[del()](https://docs.k6.io/docs/del-url-body-params) | Issue an HTTP DELETE request. |
|[get()](https://docs.k6.io/docs/get-url-body-params) | Issue an HTTP GET request. |
|[options()](https://docs.k6.io/docs/options-url-body-params) | Issue an HTTP OPTIONS request. |
|[patch()](https://docs.k6.io/docs/patch-url-body-params) | Issue an HTTP PATCH request. |
|[post()](https://docs.k6.io/docs/post-url-body-params) | Issue an HTTP POST request. |
|[put()](https://docs.k6.io/docs/put-url-body-params) | Issue an HTTP PUT request. |
|[request()](https://docs.k6.io/docs/request-method-url-body-params) | Issue any type of HTTP request. |

Result:

internal-images/Untitled%2011.png

Table with nested rows

An invaluable tool in API documentation! We have <TableWithNestedRows> custom component that will do all the magic, all you need to do is to wrap your table with this tag and make sure you follow the rules:

  1. Only 2 levels of nesting is permitted
  2. You can not omit any intermediary keys in the first column (more in example below)
  3. You can use inlineCode, links and tooltips in the first column, but keep as little content as possible to prevent malfunctioning or UI distortion.
  4. Prefer having tooltips <BWIPT/>, <BNIT/> at the righmost side to avoid colliding with toggler icon.
  5. If you see one of the rows displaying Invalid row markup, something fishy is going on with your first column value in this row

A perfect example:

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| location  | object | Location object |
| location.langitude  | number | Desc |
| location.longitude  | number | Desc |
| location.id <BWIPT/>  | number | Desc |
| [location.address](/link)  | object | Desc |
| location.address.street  | string | Desc |
| location.address.apt  | string | Desc |
Result

Table with nested rows

A bad example:

  1. Missed location.address property
  2. First row has tooltip at leftmost side
  3. Second row contains too much elements, confuses the parser
  4. Last row contains 2 dots, confuses the parser
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| <BWIPT/> location  | object | Location object |
| location.langitude (currently unavailable) <BWIPT/>  | number | Desc |
| location.longitude  | number | Desc |
| location.id <BWNIT/>  | number | Desc |
| location.address.street  | string | Desc |
| location.address..apt  | string | Desc |

LdScript

LdScript is used to deliver JSON-LD content on a certain page, you can use it this way:

<LdScript script='{"@context": "https://schema.org"}'>

As you can see, the LdScript expects a sole prop script of type string of JSON-LD data, which it will render appropriately on its own.

Collapsible

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:

<!-- other content -->

<Collapsible title="Collapsible title">
<!-- the content that will expand/collapse -->
</Collapsible>

<!-- other content -->

The result: collapsible-collapsed

After clicking on the + button the content becomes visible: collapsible-expanded

The Collapsible 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: <Collapsible title="Collapsible title" isOpen="true">.

If you want the component title to be displayed in the Table of Contents, please set tag prop to h2: <Collapsible title="Collapsible title added to ToC" tag="h2">.

Glossary

The Glossary component takes lists and presents them in multi-columnar format. The recommended use is also the simplest: an unordered list. The columns break at different places on different screens, and nested lists and description lists can become incoherent if their elements are spread across multiple columns.

<Glossary>

- so
- we
- beat on
  - boats against
  - the current
- borne back
- ceaselessly into the
- past

</Glossary>

The result:

External Link Card (Blog only)

This is a component that represents a common pattern of external link decoration. Here is how you would use it:

  1. Find a place in your article where you'd like to see the card
  2. Write down the following snippet:
<!-- other content -->

<ExternalCardLink title="Card title" description="Card description" link="https://card-link.com">
<!-- note empty line -->
![image](./path/to-image.png)
<!-- note empty line -->
</ExternalCardLink>

<!-- other content -->
  1. Replace title, description, link and image inside with your data. Note, that title and link are required, while description field and image inside are optional, though without an image it will look much less appealing.

  2. Result will be something like that:

external-card-result

Currently, this component is absent in docs repo, though could be added anytime the need arises.

Custom

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 copypast generated html into md file: we are using gatsby-plugin-mdx, so please, just import the component you need right into md exactly the way you would import it on any react page and provide necessary props.

See example how it is done with IntegrationsCiIconBlock in Using k6/Testing Guides/Automated Performance Testing

The rest

The rest of elements you could write as you would in native md. It includes p, ul, ol, em, strong etc.

Additional information

Check out the project Wiki for additional information.