-
Notifications
You must be signed in to change notification settings - Fork 4
Written Style Guide
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.
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.
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.
All images should be wrapped in <figure>
HTML tags and should use alt text.
Follow WCAG Alt Text guidelines.
<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>
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.
Refer to these unlisted showcase and reference pages for information and sample code for the following components:
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.
Product | Stylized as | Notes |
---|---|---|
RELAY | Always style as "RELAY". For example: "RELAY REST", "RELAY v4". Do not style as " |
Not an acronym. |
SignalWire Space | Always capitalize "Space" as a proper noun. | |
FreeSWITCH | Always style as "FreeSWITCH®️". Never style as " |
Refer to this issue in freeswitch-docs for more info. |
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.
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.
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.
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.
- 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.
Import Markdown snippets as components for easy reuse.
- 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.
- Add an underscore (
_
) to the beginning of the snippet's file name.- For example,
_python-example.mdx
.
- For example,
- 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.
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.
---
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
...
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.
- For example,
-
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.
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.
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:
- Remove the page slug. This step is optional, but recommended if you are trying to isolate the URL issue.
-
Build the site using
npm run build
. -
Serve the site using
npm run serve
. - 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.)
-
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.
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
...
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.
Avoid using links in headers, since they will highlight in the Table of Contents.
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).
:::
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
.
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>
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
See the relevant doc on admonitions for more information.
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.
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)
- start with
- 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)
- start with
<!-- 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
.
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
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.
Guidelines for images. In general, make sure that your article includes correlated images (when relevant).
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 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.
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.
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.
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).
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.
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' }}>
Use code blocks to display multi-line code.
All code examples should also be hosted on the SignalWire Examples Repository.
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>
-
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.
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.
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>
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