Skip to content

Written Style Guide

August edited this page Feb 7, 2025 · 4 revisions

This document defines the style guide for the documentation in the docs and freeswitch-docs repositories.

Important

The guidelines set out below reflect style decisions made based on the unique aspects of SignalWire's products and documentations. For style rules not specified here, our documentation generally follows the Google Developer Documentation Style Guide.

Commonly-used pages in Google's style guide

Glossary

For clarity, please observe the following conventions for types, categories, purposes, and definitions related to documentation.

  • file: A generic term referring to any file in the documentation repo, whether .md, .mdx, .webp, or other.
  • document: This is a generic term referring to a .md or .mdx document.
  • doc: Docusaurus defines docs as documents within the /docs/ directory. The behavior of docs is governed by the docs plugin. Docs are the default and primary type of document.
  • page: Docusaurus defines Pages as separate documents outside the /docs/ directory, whose behavior is governed by the pages plugin.
  • guide: A Guide is a type of doc which is organized by tags in the Guide Showcase.
  • article, example, demo, explainer, how-to: These are content descriptors without structural implications.

♿️ Accessibility

Most contributors to SignalWire or FreeSWITCH documentation will only need to follow a few key practices to ensure an acceptable base level of content accessibility.

Images and Alt Text

All images should be wrapped in <figure> HTML tags and should use alt text.

Alt Text

Follow WCAG Alt Text guidelines.

Example of correct image syntax

<figure>
  <img src={require("./4e31aa1-rtaImage.webP").default} alt="A screenshot of the TryIt JS SIP interface. In the 'Your Name' input field, the user has entered 'jssip1'. There is a gear icon and a button labeled 'Reset'." />
</figure>

WCAG

We attempt to adhere to version 2.1 of the Web Content Accessibility Guidelines (WCAG), which is a widely recognized and globally accepted standard for web accessibility published by W3.

WCAG guidelines are organized under four principles, stating that content must be perceivable, operable, understandable, and robust (POUR). W3 provides specific criteria for making web content more accessible to a wider range of people with disabilities, including blindness and low vision, deafness and hearing loss, limited movement, speech disabilities, photosensitivity, and combinations of these.

WCAG guidelines have three levels of compliance: A (the least strict), AA, and AAA (the most strict). Most legal requirements and best practices aim for at least AA compliance.


🔧 Custom components

Refer to these unlisted showcase and reference pages for information and sample code for the following components:


✍️ Written Style

We aim to maintain a conversational / semiformal writing style that goes straight to the point. In particular:

  • Avoid vague/fluffy platitudes and buzzwords.
  • Give the reader what they want, with a language that is as concise/direct/straightforward as possible.
  • Less is more. Write for clarity and brevity.
  • Don't use exclamation points, unless what is written needs to be shouted.

Brand Capitalization

Product Stylized as Notes
RELAY Always style as "RELAY". For example: "RELAY REST", "RELAY v4". Do not style as "Relay". Not an acronym.
SignalWire Space Always capitalize "Space" as a proper noun.
FreeSWITCH Always style as "FreeSWITCH®️". Never style as "freeswitch", "FreeSwitch", or otherwise. Refer to this issue in freeswitch-docs for more info.

Semantic Line Breaks

Follow Semantic Line Breaks for written text.

This means that each sentence gets its own line.
For prose content, this is preferable to a strict column limit for several reasons:
 - Text is more readable in the editor.
 - Diffs are cleaner.

🦕 Docusaurus

Markdown React is a markup syntax based on Markdown and adding JSX (a syntax extension for JavaScript, mostly used with React, that allows developers to write HTML elements and components directly within JavaScript code). MDX, which is supported by Docusaurus, allows you to write JSX in your Markdown documents.

Since Markdown content is static, MDX allows us to add dynamic, interactive, and programmable React components to the SignalWire docs.

Tabs

Tab functionality is provided by a Docusaurus plugin. Tabs are easy to use, and enable documentation to efficiently show the user only the information relevant to their use case.

Tabs in Docusaurus.

Implement tabs by first importing the relevant plugins. This can be done at the start of the page, or directly above the tab section.

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

Next, create opening and closing Tabs HTML tags. Inside these tags, the contents of each tab is defined by a TabItem element.

<Tabs groupId="article-title">

<TabItem value="macos" label="MacOS">

Tab content goes here.

</TabItem>

<TabItem value="linux" label="Linux">

Tab content goes here.

</TabItem>

<TabItem value="windows" label="Windows">

Tab content goes here.

</TabItem>

</Tabs>

Select a tab by default by including default in the TabItem element, as such: <TabItem value="macos" label="MacOS" default>

Don't indent content within tabs. It isn't necessary and causes some elements to behave unexpectedly.

FAQ

  • Should my page be .md or .mdx?

New pages can be plain Markdown to start. It's perfectly OK to have a mix of .MD and .MDX files in any part of the docs repo.

If you're sure that you'll need MDX features for your new page, create it as .MDX so that you don't have to update links later.

Reuse content

Import Markdown snippets as components for easy reuse.

  1. Create a new markdown file for your content snippet.
    • Locate it in the same directory as the parent doc.
    • If using multiple snippets, consider locating them in a subfolder.
  2. Add an underscore (_) to the beginning of the snippet's file name.
    • For example, _python-example.mdx.
  3. Import and use the snippet as a React component:
...
import PythonExample from './snippets/_python-example.mdx';

<PythonExample />

Consult the Importing Markdown guide for more information.

Front Matter

Docusaurus supports adding YAML metadata, known as "front matter", to the beginning of any Markdown document. Front matter is demarcated by three dashes (---) at the start and end, and individual metadata attributes end in a colon (:).

See this reference for a comprehensive list of fields recognized by the docs plugin.

Example

---
slug: /guides/video/sharing-the-screen
title: Sharing the Screen
description: The SignalWire Video API allows you to host real-time video calls and conferences on your website. In this guide, we'll learn to add screen sharing ability in your video call interface.
image: ./screenshot.webp
sidebar_position: 3
x-custom:
  author: Neil Armstrong
---

# Title
...

Required Front Matter

While most of the metadata is optional, you should always include at these items:

title: Short, Descriptive Title
description: A text description of the page contents, generally less than 200 characters.

For documents that include images, you should also include this item:

image: ./path-to-representative-image.webp

Behind the scenes, Docusaurus converts these front matter items into OpenGraph tags which are used by social media sites to display previews. Without these items, shared links will not include useful context.

  • title: This item is used to generate the label of the tab (or window), in conjunction with the docs-wide title, which is “SignalWire Developer Portal”.
    • For example, title: Sharing your Screen produces this tab label: “Sharing your Screen | SignalWire Developer Portal”. This is also used as the title for previews on social.
  • description: This text is shown beneath the title in social previews, space permitting.
  • image: This is the image that will be included with the social preview.

Slugs

Caution

Avoid changing slugs for existing articles whenever possible. When slugs unavoidably must be changed, follow the procedures in the Slugs Best Practices guide. Changing slugs without completing those steps will break links to the site and may result in long-term search engine deprioritization.

Docusaurus generates URLs automatically based on the document path, per its documentation. Should you wish to set a slug manually, use the slug front matter item demonstrated in the example above.

Troubleshooting Slugs

At times, especially when working outside the /docs/ directory, Docusaurus can generate URLs unpredictably or not observe slugs set in front matter. If you are having trouble figuring out the URL that Docusaurus is assigning to a page, follow these steps:

  1. Remove the page slug. This step is optional, but recommended if you are trying to isolate the URL issue.
  2. Build the site using npm run build.
  3. Serve the site using npm run serve.
  4. Review the sitemap by navigating to http://localhost:3000/sitemap.xml. (If you have multiple local builds, you may have to adjust this url to 3001, 3002, etc.)
  5. Search the page title. If you have removed the custom slug, Docusaurus will generate a url for the page that follows this pattern: [rootURL]/path/to/document.md.

Note that slugs work differently in the src/pages/page directory. This is because Docusaurus handles files in that directory according to the Pages plugin. The current workaround for this is to avoid custom slugs when working outside of the /docs/ directory.

Headers

Make sure you use one and only one H1 header (# Like This), and that all subsequent headers are deeper than that (## Like an H2, or ### an H3, ...).

In general, the title should be specified as a markdown H1 header, not as a metadata field.

---
title: Title
slug: /guides/video/sharing-the-screen
---

<!-- ^^^ DON'T do this -->

# Section 1
...

# Section 2
...
---
slug: /guides/video/sharing-the-screen
---

<!-- ^^^ DO this -->

# Title
...

## Section 1
...

## Section 2
...

No Content Before H1 Title

Note also that any content above the H1 header will prevent the document from appearing in the Guides Showcase. An H1 header should therefore always immediately follow the front matter in a given document.

No links in headers

Avoid using links in headers, since they will highlight in the Table of Contents.

Admonitions

Docusaurus offers a custom feature known as Admonitions. These are colorful call-outs that allow contributors to easily add styling to important contextual text using the following triple-colon (:::) syntax:

:::info

Informative text here, including *formatting* and [links](/link/to/content).

:::

Custom Admonition Title Text

You can replace the default "title" text of the admonition by adding a text string after the opening admonition. For example:

:::info Additional Information

Text of Admonition

:::

The above example results in a callout styled using the info theme, but with a title reading Additional Information instead of info.

Custom Admonition title text.

You can add custom icons such as emoji to admonitions by importing the Admonition component into your Markdown (or MDX, or JSX, or HTML) document, and then invoking the JSX with an HTML tag.

import Admonition from '@theme/Admonition';
<Admonition type="tip" icon="💡" title="Did you know...">
  Use plugins to introduce shorter syntax for the most commonly used JSX
  elements in your project.
</Admonition>
Screenshot 2024-04-25 at 12 16 41 PM

See the relevant section of the Docusaurus Admonitions docs for more information on usage.

The following admonition descriptors are recognized:

  • :::note
  • :::tip
  • :::info
  • :::warning
  • :::danger

A screenshot of example Admonitions in Docusaurus

See the relevant doc on admonitions for more information.

Troubleshooting admonitions

Admonitions will break when indented more than once. You're unlikely to run into this issue unless you're putting an admonition inside nested HTML.

Links

Link to the .mdx filename whenever possible.

In short:

  • Linking between guides and SDKs reference:
    • start without a slash and end with .mdx
    • [Guide](guides/video/my-guide.mdx)
    • [Guide](../my-guide.mdx)
    • [RoomSession](sdks/reference/browser-sdk/video/video-roomsession.mdx)
  • Linking between pages and guides:
    • start with /, use the browser URL without extension
    • [Campaign Pricing](/guides/messaging/campaign-registry-pricing)
  • Linking to a different subsite (e.g. from guides to REST docs):
    • start with pathname:///, use the browser URL without extension
    • [Create a Room](pathname:///rest/create-a-room)
When linking to guides, use the markdown filename as target. Docusaurus will convert it to a proper link. For example, instead of
<!-- Don't do this -->
A link to a [guide](/guides/video/my-guide).
<!-- Do this instead (absolute file path) -->
A link to a [guide](guides/video/my-guide.mdx).

<!-- Or this (relative file path) -->
A link to a [guide](../video/my-guide.mdx).

Note: for technical limitations, this only works for files within the same "sub-site". If you need to link to a different sub-site (e.g., from a guide you need to link to a REST endpoint), you should use pathname:///. For example: pathname:///rest/create-a-room. After building, this will become https://developer.signalwire.com/rest/create-a-room. To link from within a different sub-site to a guide, you will need to use this example structure: pathname:///../../../guides/campaign-registry-all-you-need-to-know. Building this will yield https://developer.signalwire.com/guides/campaign-registry-all-you-need-to-know.

Reference-style links

Instead of the traditional link syntax - [link title](long/path/to/link/URL) - You can use a short string (such as a number) as the link inline, using square brackets [1] instead of parentheses, and then define the link at the end of the doc.

This keeps text with inline links far more readable in its raw form. You can also reuse these reference-style links throughout the doc so it improves the authoring and maintaining experience for links that we use multiple times in a doc. You can also quickly review and edit all document links in one place at the end of the file.

Check out our [developer guide][1] for more information, and our [blog][2] to keep up with development.

...

[1]: https://first.link.to/content
[2]: https://second.link.to/content

Linking to the Dashboard

Link directly to the Dashboard space you need using the following link template: my.signalwire.com?page=<page_name>

For example: https://my.signalwire.com?page=phone_numbers

You can also link directly to a form within a space with "/new" in the URL. For example, https://my.signalwire.com?page=port_requests/new.

Images

Guidelines for images. In general, make sure that your article includes correlated images (when relevant).

Directory Structure

If your article contains images, please group all the resources under a container folder. For example, if your article is called docs/first-steps.mdx and contains images, then you should change the file structure from this:

docs/
    first-steps.mdx

to this:

docs/
    first-steps/
        index.mdx
        my-image.webP
        my-other-image.webP

Use captions

Use image captions as much as you can. For each image in the article, there should generally be a caption explaining what the image is about, even if this is already described in the body of the article. To add a caption:

<figure>
    <img className="img-800" src={require("./my-image.webP").default} />
    <figcaption>This is the caption for my image.</figcaption>
</figure>

If you are using VSCode, you can use the included code snippet by typing "figure". VSCode's IntelliSense code-complete feature will populate the correct <figure> attribute. Note that you should type figure without an opening < since IntelliSense will provide that for you.

ezgif-1-28a7f4d9f3

Prefer WebP as image format

To reduce the bandwidth and to keep the size of the repository at a minimum, prefer using WebP images instead of JPG or PNG. To convert your images to WebP, run this command from the root of the repository:

node scripts/image-conversion.mjs path/to/guide/*.png path/to/guide/*.jpg

This will create WebP duplicates for each of your source images. Remember to manually delete the originals before pushing the changes.

Avoid transparency in most cases

For functional graphics, avoid transparency in areas where it would hinder usability when displayed over a dark background.

This is because the docs site may implement a "Dark Mode" in the future.

Non-functional transparent elements, such as the drop shadows generated by default when capturing a screenshot of a window on MacOS, are not a problem.


🎨 HTML and CSS

Custom HTML

Avoid the usage of custom HTML as much as possible: it usually creates an inconsistent look in the final result. As a special case, there is no harm in using HTML tags for images given that the markdown standard is too limited. (see Images).

CSS

For special pages needing some extra pop, try out some of the components and layouts in the Infima framework built into Docusaurus.

CSS should be used sparingly to maintain a consistent style, and to avoid migration issues in the event of migrating to a different docs platform or styling framework.

Custom CSS and In-Line Styling

In-line styling should be used even more sparingly. Generally, avoid it entirely on everyday docs. When it is needed, be sure your syntax follows JSX expectations:

<div className="name" style={{ maxWidth: '320px' }}>

👾 Code

Use code blocks to display multi-line code.

All code examples should also be hosted on the SignalWire Examples Repository.

Syntax

Optional Parameter / Argument Syntax

For parameters and arguments which are not mandatory to the relevant function, method, or interface, add a question mark to the end of the parameter. This is a convention in TypeScript and some other languages.

For increased clarity and usability by screen readers, add the question mark in a <sup> HTML element and use the title and aria-text attributes to tell the user the parameter is optional.

For example:

params.digits <sup aria-text="Optional parameter" title="Optional parameter">**?**</sup>

Other example types

  • Audio: SignalWire's documentation generally does not incorporate audio examples due to their size, and the difficulty in evaluating that they are up-to-date.
    • For audio examples, such as demonstrating an IVR, consider implementing an interactive, public-facing example that users can test on their own.

Images

Use the .webp image format where possible, as it combines the advantages of three common and older formats - JPEG, PNG, and GIF. WebP supports:

  • animation
  • lossy and lossless compression
  • alpha transparency

Use the cwebp tool to quickly convert other image formats to WebP from the command line.

SVG

Scalable Vector Graphics (SVGs) are great for diagrams and other visuals. A correctly embedded SVG will follow the below template:

<figure>
    <img className="img-800" src="/readme-files/f826d87-API_network_interaction.svg" alt="A diagram depicting interactions between SignalWire servers, your server, and the client."/>
    <figcaption>A diagram depicting interactions between SignalWire servers, your server, and the client.</figcaption>
</figure>

Automated formatting

To ensure a consistent look and the absence of errors, it is often advised to run an automated formatter. We support "prettier": you can use it as a VS Code plugin, or from the command line, like this:

npx prettier --write path/to/my/guide.mdx