Your own widgets

Create a widget for Doca

A folder, a widget.json and a script that prints text. In PowerShell, Python, Node or whatever you already use, with nothing to compile and no need to restart Doca.

Ler em português

1

You write

A folder with the widget.json and the script.

2

Doca runs it

The command, every now and then, only while the widget is visible.

3

It becomes a tile

What the script prints shows up in the dock and in the panel.

Your first widget in three steps

This example counts the days left until Friday. It takes two minutes.

  1. Open your widgets folder

    In Doca, open Settings › Your dock. At the end of the Pieces box, click Open your widgets folder. The first time, Doca creates the folder with an example, exemplo-tempo-ligado, that you can copy and change.

    Each widget is a subfolder. Its name is the widget id: letters, digits, -, _ and .. Create one called friday.

  2. Describe the widget

    Inside friday, create the widget.json. Only name and command are required:

    {
      "name": "Friday yet?",
      "command": "powershell -NoProfile -ExecutionPolicy Bypass -File friday.ps1",
      "every": 600,
      "icon": "🎉",
      "color": "#B65CF0"
    }
  3. Write the script

    In the same folder, friday.ps1. The first line it prints becomes the tile's title; the second, the subtitle:

    [Console]::OutputEncoding = [Text.Encoding]::UTF8
    $left = (5 - [int](Get-Date).DayOfWeek + 7) % 7
    if ($left -eq 0) { "It's Friday!"; "Have a great weekend" }
    else { "$left day(s)"; "until Friday" }

    Back in the Pieces box, Friday yet? shows up in the Your widgets group. Click it to add it to the dock. Changed the script? Doca picks up the change on the next run.

More than two lines

To pick colors or show a progress bar, a badge, panel rows and buttons, the script prints a JSON object instead of text:

{
  "title": "$ 64,100",
  "subtitle": "+2.1% today",
  "icon": "₿",
  "color": "#F7931A",
  "color2": "#C46A00",
  "progress": 0.42,
  "badge": "3",
  "panel": [
    { "text": "24h high", "value": "$ 65,200" },
    { "text": "24h low", "value": "$ 62,300" }
  ],
  "actions": [
    { "label": "Open website", "open": "https://example.com" }
  ]
}

In the dock

₿ $ 64,100+2.1% today 3

In the panel

$ 64,100 +2.1% today

24h high$ 65,200

24h low$ 62,300

Open website

If the script prints other messages first, Doca uses the JSON that starts on a new line and runs to the end of the output.

In any language

The command runs in the widget's folder, as if you typed it in the terminal. Anything that works there works here:

Python · "command": "python disk.py"

import json, shutil
total, used, free = shutil.disk_usage("C:/")
print(json.dumps({"title": f"{free / 2**30:.0f} GB", "subtitle": "free on C:",
                  "progress": used / total}))

Node · "command": "node stars.mjs"

const repo = process.env.DOCA_OPT_REPO || "microsoft/terminal";
const r = await fetch(`https://api.github.com/repos/${repo}`);
const { stargazers_count } = await r.json();
console.log(JSON.stringify({ title: `★ ${stargazers_count}`, subtitle: repo }));

Executable · "command": "my-widget.exe --doca"

73 °F
Clear sky

In Node, the .mjs extension lets you use await outside a function. And DOCA_OPT_REPO is an option the user picks, as the next section shows.

Options the user adjusts

The options in widget.json show up in Adjust widget… (right-click the tile). The script gets each one in an environment variable:

"options": [
  { "key": "currency", "label": "Currency", "type": "choice", "choices": ["USD", "EUR"], "default": "USD" },
  { "key": "change", "label": "Show the change", "type": "bool", "default": true },
  { "key": "nickname", "label": "Nickname", "type": "text", "default": "" }
]
$currency = $env:DOCA_OPT_CURRENCY  # "USD" or "EUR"
$change = $env:DOCA_OPT_CHANGE      # "true" or "false"

Reference

The widget.json

FieldWhat it is
nameRequired. The name in the catalog and in the dock.
commandRequired. What Doca runs, in the widget's folder, through cmd.
description, authorShown in the catalog and in the panel.
everyHow often to run, in seconds: from 5 to 86400. Default: 60.
widthThe tile's width in icons, from 1 to 4. Default: 2. The user can change it in the editor.
icon, colorThe icon and the color (#RRGGBB) until the script's first output.
optionsEditor options, of the types text, bool and choice (with choices).

widget.json accepts comments (//) and trailing commas.

What the script prints

FieldWhat it is
title, subtitleThe text of the tile and the panel.
iconAn emoji or short text. For a Windows symbol (Segoe Fluent), glyph:E713.
color, color2The tile's gradient background (#RRGGBB). Without color2, the bottom is a bit darker.
progressA bar from 0 to 1 below the text, on tiles 2 icons wide or more.
badgeA red badge in the corner.
everyChanges the interval from now on, from 5 to 86400 seconds.
panelThe panel rows: text, or { text, value, icon, open }.
actionsUp to 6 buttons in the panel: { label, open } opens an address or file; { label, run } runs a command in the widget's folder.
clickWhat clicking the tile does, with { open } or { run }. Without it, the click opens the panel.

What the script receives

VariableValue
DOCA_OPT_<KEY>Each option, with the key in uppercase. Booleans arrive as true or false.
DOCA_LANGDoca's language: pt or en.
DOCA_WIDGET_IDThe id of this widget instance, handy for caching.
DOCA_WIDTHThe tile's width, in icons.

Tips