Contributing to the Docs

Thank you for wanting to help us make the docs better. Every contribution is appreciated.


The Viam documentation aims to:

  • Educate users (explain concepts, provide an overview of what is possible)
  • Help users accomplish tasks (performing an action, building a thing)

We do that by providing concise and well-structured documentation to users. When users stumble, we provide avenues for feedback, so we can take action and prevent other users from running into similar issues.


We aim to be friendly but not colloquial, direct, and concise.

Here are a few additional pointers:

Emoji ✨No
Exclamation marksUse sparingly
Rhetorical questionsNo


We write for a technical audience that spans from entry-level to expert. However, common tools and concepts such as version control, moving files with ssh, JSON are beyond the scope of our docs. To make the content as accessible as possible we will, where possible, include actions to be taken and text that guides the user as to what they are achieving when performing these actions.

For example, when copying a file to another machine with ssh, we would describe the action with words like “Use ssh to move the file onto the other machine” alongside the command to move the file. Explaining ssh goes beyond the scope of our docs. Where needed, we will link to supporting documentation but not provide supporting documentation ourselves where it would duplicate existing external documentation. Use your judgment to determine when we need to explain more and when we need to link to supporting content. When in doubt, ask during review.

Project structure

All documentation is in the docs folder. For information about Hugo and how to develop locally, see the README.

Content types

When creating a new piece of content, decide which one of the four content types the content should be. Note this in a comment in the frontmatter of the file.

The docs use the Diátaxis Framework as the basis of the content structure with the following four content types:

  • Explanation (conceptual): An understanding-oriented piece of content. This content provides background knowledge on a topic and tends to be referenced in how-to guides and tutorials. For example the Robot Development Kit page or the Registry page. It’s useful to have a real or imagined “Why?” question to serve as a prompt.

    Click to view template
  • How-to Guide (procedural): A task-oriented piece of content that directs a reader to perform actions step by step to complete a task, like a recipe. Generally starts with a description of the task and things to consider, and then provides a set of numbered steps to follow. For example, the Installation page or the Find module page.

    Click to view template
  • Tutorial: A learning-oriented piece of content that functions as a lesson for the reader. A tutorial helps readers to learn and apply skills by doing something meaningful and attainable.

    Click to view template
  • Reference: A concise, information-oriented piece of content that generally starts with an overview/introduction and then a list of some kind (configuration options, API methods, etc.). Examples include the API pages as well as component and service pages.

    Example template: Component template.

    Click to view template

Style guide

All docs are written in Hugo Markdown. Most Markdown formatting is supported. For a brief introduction to Markdown, check out this Markdown Cheatsheet. Some additional formatting options are supported with Hugo Shortcodes.

We follow the Rackspace Style Guide with many rules encoded in Vale rules.

Vale linting

When you open a PR, your changes will be checked against a few style rules. To run this check locally, follow the instructions in the Vale Readme.


We recommend you work in Visual Studio Code and install the markdownlint extension.

UI elements

Use bold text for UI elements, such as tabs and buttons.

Example values

Use examples that resemble real data. For emails this could be

When using placeholders in code examples, follow the Google developer documentation style guide’s rules for formatting placeholders.

Images and screenshots

Use screenshots in introductory materials and where the surrounding text is not enough to direct the reader. Be aware that screenshots tend to get outdated quickly and come with a maintenance burden.

Rules for images:

  • Place images in the assets folder. The folder uses the same content structure as the docs. Your images should be in the folder the page that uses it is in. However, there is no need to duplicate an image into multiple places if you use it in multiple pages.
  • All images require alt text.
  • All images should be smaller than 1MB. Hugo throws a warning during local builds (such as make serve-prod) if an image exceeds this size. Use an image compressor like TinyPNG. This is to reduce the overall page and repo size.

Remove EXIF data automatically

Image markup

If the image is supposed to take up the full width of the page use the regular markdown syntax: ![alt text](path).

![Raspberry Pi](/get-started/installation/thumbnails/raspberry-pi-4-b-2gb.png)

If the image is smaller use the imgproc shortcode with an appropriate resize value.

<!-- Remove space between curly braces -->

{ {<imgproc src="PATH/TO/IMAGE.png" resize="300x" declaredimensions=true alt="ALT">} }

{ {<imgproc src="/get-started/installation/thumbnails/raspberry-pi-4-b-2gb.png" resize="x60" declaredimensions=true alt="Raspberry Pi">} }

{ {<imgproc src="/get-started/installation/thumbnails/raspberry-pi-4-b-2gb.png" resize="x200" declaredimensions=true alt="Raspberry Pi">} }

Raspberry Pi

Raspberry Pi Raspberry Pi

The imgproc shortcode will:

  • convert the image into the webp format (which is more efficient) and resize the image
  • resize the image in the current format and set that image as a backup in case webp is not supported. This does reduce file size when the website is being served. However, the source file should still be smaller than 1MB to minimize overall page and repo size. For more information on the resize options see Image Processing.

Only specify declaredimensions if the image is not responsive (if it doesn’t resize). The only images that you’d want to use declaredimensions on are the ones that take up the same space on mobile as on desktop.

An example of this are the small board icons on the front page which should never be a different size than they are. The pictures in cards, however, need to resize because they change size based on the available screen space.

Screenshot should most often be added with normal markdown syntax. Then they’ll take up the max size they can on a big screen but be smaller on mobile. If you want to resize a large image, use the largest size the image can take up as the image to resize the image to.

GIFs and videos

We encourage the use of GIFs and Videos. Our docs have two kinds of videos:

  • Regular videos with video controls and audio
  • GIF-like videos that do not have video controls or audio and function like GIFs

Regular videos

For regular videos that should use the video shortcode as follows:

<!-- remove space -->

{ {<video webm_src="/heart.webm" mp4_src="/heart.mp4" alt="A robot drawing a heart" poster="/general/heart.jpg">} }

We use webm and mp4 source files for videos because they are generally smaller. The poster is an image that gets loaded as a preview.

Click to see the commands for converting videos to these formats

GIF-like videos

GIF-like videos on our pages are generally used to show robot actions. We do not use the GIF file format because it uses a lot of bandwidth - more than videos - and the best practice is to not use them.

Instead, we use a video div with two sources:

<!-- remove space -->

{ {<gif webm_src="/heart.webm" mp4_src="/heart.mp4" alt="A robot drawing a heart">}}

Place the files into the static directory.

Click to see instructions for creating the video files
Click to see instructions for creating video commands for your terminal

Formatting guide

Front matter

Each file that generates a page in Hugo starts with front matter that looks like this:

title: "Build a line-following robot with only a rover and a webcam"
linkTitle: "Line Follower"
weight: 90
type: "docs"
description: "Instructions for building a line-following robot that uses a webcam to track lines."
# SME: "SME Name"
  • The description gets used for previews.
  • The weight determines the ordering of pages in the side navigation bar.

Prod/Draft/Future pages

Add draft: true to the Front Matter to set a page to Draft. You can commit and push the page and it won’t display in production. Add future: true to the Front Matter to begin building a page to production on a certain date (for example, a release date).

File names

File names are kebab-case, with hyphens, such as

One sentence per line

To make reviews easier, each new sentence should begin on a new line.

Where related resources would be helpful to a reader, link them. However:

  • Links are an opportunity for a reader to get lost or get distracted. If that happens, a link is not helpful. Placing links near the end of a section/page can help avoid this.
  • Avoid a page becoming a sea of blue hyperlinks. Excessive linking can make a page harder to view and read.

When linking to an image or another page within the docs please use relative links (appendix/contributing/) or (/appendix/contributing/).


We have built a glossary into our docs. Jargon and product-specific concepts should have an entry in the appendix/glossary folder. You can use a glossary entry on any page like this:

<!-- Remove spaces between curly braces -->

This text will have additional information on hover for the
word { {< glossary_tooltip term_id="smart-machine" text="smart machine" >} }.

Reusable text snippets

If you need to use the same text in multiple locations, for example when cautioning users to disconnect power before changing connections or providing a commonly used instruction set or procedure, you can use reusable snippets.

The following is an example of the alert added using the snippet shortcode:

Figure: Snippet Shortcode Usage
Snippet shortcode usage.

Including another file

This is a Heading in the Sample File

This entire section was added to the current topic using the readfile shortcode.

Heading 2

  • bullet 1
  • bullet 2

Heading 3

This Markdown code:

Markdown Table
| id | name    |
| 1  | Roberta |
| 2  | Oliver  |
| 3  | Shayna  |
| 4  | Fechin  |

Renders like so:

Markdown Table


This HTML code:

<h3>HTML Table</h3>


Renders like so:

HTML Table


This is the last line of the included file.

Section content before this line is contained in an included file: /static/include/

Tab Panels


  • Markdown and HTML images
    • Images should be included with the imgproc shortcode. You cannot directly use the <img> html tag for images in the assets folder because the images, once built, are renamed. If you really need to use html directly, place the image in the static folder.
  • Alert Shortcode
  • PRISM syntax highlighting (the three backticks)
  • “codelang” highlighting (add codelang=“language” to tab element). It’s very ugly, needs css work, and is not recommended at this time.

Not supported

  • Footnotes
  • Expanders

Example usage

# remove spaces

{ {<imgproc src="/general/tabbed-panel-markdown.png" resize="300x" declaredimensions=true alt="Screen capture of Tab/Tabs Shortcode Usage" style="border:solid 1px black">} }
Screen capture of Tab/Tabs Shortcode Usage

What is Rendered?

It renders vanilla HTML and markdown, Alerts, and images. For example, these two images:

  • Markdown Image Example
    expand example

  • HTML Image Example (with border)

    Screen capture of Tab/Tabs Shortcode Usage

Code with syntax highlighting

Line numbering is off by default.

  "word": "Three backticks and the language name enables Prism syntax highlighting."

With just line 6 highlighted. See the prism line highlight extension for more info:

while (True):
    # When True, sets the LED pin to high or on.
    await led.set(True)
    print('LED is on')

    await asyncio.sleep(1)

    # When False, sets the pin to low or off.
    await led.set(False)
    print('LED is off')

    await asyncio.sleep(1)

With linked lines and lines 8-10 highlighted.

while (True):
    # When True, sets the LED pin to high or on.
    await led.set(True)
    print('LED is on')

    await asyncio.sleep(1)

    # When False, sets the pin to low or off.
    await led.set(False)
    print('LED is off')

    await asyncio.sleep(1)

Alert shortcodes

How to use notes, cautions, and warnings

Info/Tip: Use to convey helpful information or clarification. They both use the same color.

Note/Important/Stability Notice: These call attention to something important. When creating alerts about important messages, set the title attribute as title="Important". If you want to include a more detailed title or message, use title="Important: $message" to provide additional context.

Caution: Provide notice that a certain action or event could damage hardware or cause data loss.

Warning: Use to notify the reader of an issue to avoid loss of life, personal injury, and health hazards. Electrical and physical safety fall into this category.

Figure: Shortcodes for Alerts
The shortcodes used to display Alerts.

Using expanders

Expanders allow to you add long sections of code to your topic and hide them until the reader decides to view it.

Within the expander, you can still use most other shortcodes and syntax highlighting from Prism functions properly. The shortcode displays your expander’s title in a light blue bar to make it noticeable.

Screen Capture of an Expander Screen capture of the expander control rendered on a documentation page


  1. Add the shortcode tags. Make sure that the title is suitable for your use.
  2. Drop in the material you want to hide until the reader wants it.
Click to view the source


The figure shortcode enhances the existing figure and figurecaption html tags. Figure supports the standard html attributes associated with the html img and figure tags, as well as an attr element for attribution text and attrlink if you wish to add a link to the attribution text.

Figure: Figure Shortcode
The shortcode used to display an image, its caption, and its attribution.

This shortcode places the caption (that is the “title”) above the table. The title is set in 12pt italic with a green underline.

Figure styles the Attribution text as body text.


To add a footnote:

"Some completely[^f] random text."

[^f]: this is the text for the footnote

You can place the footnote text immediately beneath the paragraph where you put the marker. Hugo will place it at the bottom of the page.

Pull requests

If you are making a small change, like fixing a typo or editing a few lines of text, you do not need to create an issue. However, if you plan to make bigger changes, we ask that you create an issue and discuss the change with us in advance.

To get started:

  1. Fork the official repo into your personal GitHub.
  2. Clone the forked repo to your local system.
  3. Add the remote path for the ‘official’ repository: git remote add upstream

When you are ready to contribute changes to the docs:

  1. Make sure you are on the main branch: git switch main
  2. Sync your forked main branch with the official repo: git pull upstream main
  3. Create a new branch for your changes: git switch -c my-new-feature
  4. Edit some docs…
  5. Commit your changes: git commit -am 'Add some feature'
  6. Make sure your local branch is still up-to-date with the official repo: git pull upstream main
  7. Push to the branch: git push origin my-new-feature
  8. Submit a pull request


If you have questions or would like to chat, please find us on the Community Discord.

Have questions, or want to meet other people working on robots? Join our Community Discord.

If you notice any issues with the documentation, feel free to file an issue or edit this file.