Skip to main content

How Widgets run

A Widget looks like an ordinary React component, but it never runs on the Frame. Blotch runs it on its own servers, takes a picture of it and sends the picture to the Frame. Knowing how that works explains most of the rules for writing Widgets.

From code to e-ink​

Shortly before a Page is due on a Frame, Blotch prepares it:

  1. Each Widget on the Page is opened in its own browser window, sized exactly to its box on the Page.
  2. The Widget fetches its data and draws itself.
  3. Once everything has loaded, Blotch takes a screenshot of it.
  4. The screenshot is turned into black and white, with patterns of dots standing in for shades of grey, and sent to the Frame.

The Frame then shows the picture until the next refresh. In Standard Mode, it sleeps in between.

What that means for your code​

A Widget is a still picture. Nobody can tap it, scroll it or watch it animate. Timers, transitions and click handlers do nothing useful. Draw everything you want seen in the first render.

There is no loading state. Blotch waits until your Widget has its data before taking the picture, so the useFetch hook simply gives you the data. You never draw a spinner.

Errors are shown for you. If your Widget throws, for example because an API is down, the Frame shows the error in your Widget's place. You don't need an error boundary of your own. To show a friendlier message for an error you expect, check for it and draw something else.

Requests go through Blotch. useFetch sends every request through Blotch's servers. That's why APIs that block requests from browsers still work, and why responses can be cached and shared between Frames. It also means a Widget can't reach a server on someone's home network.

Data is fetched a little early. Pages are prepared minutes before they go on screen, so the data is that much older by the time someone sees it. That rarely matters, but it does around midnight. See Show the right date and time.

The clock is moved forward. So that a Widget shows the right time, new Date() gives you the moment the Page goes on screen, not the moment it was prepared. In the Widget Studio preview, it's simply the current time.

Time zones must be asked for. The browser that draws your Widget isn't in the Frame's time zone. Get the Frame's zone from useTimeZone and pass it whenever you format a time. Your Widget can look right in the preview, which uses your computer's zone, and still be wrong on the Frame if you don't.

Dates and numbers follow the Frame's language. Formatting functions such as toLocaleDateString use the language the Frame's owner chose, unless you name one. See Show text in the Frame's language.

Everything comes from hooks​

Your Widget component receives no props. Everything it knows about where it's running comes from the Blotch Library's hooks:

HookGives you
useInputsThe settings the person installing it chose
useAssetsThe images you uploaded
useLayoutShapeThe size and shape of its box
useTimeZoneThe Frame's time zone
usePreferredLanguageThe Frame's language
useThemeWhether the Frame is in its light or dark theme
useBatteryLevelThe Frame's battery level

Black and white​

The screen shows two colors: black and white. Widgets are styled with Tailwind CSS, set up with only two colors, foreground and background, which swap when the Frame uses its dark theme. Other color classes do nothing.

Shades come from patterns of dots, which work well for large areas such as a filled bar, but make thin lines and small text look speckled. Keep text and lines in full text-foreground, and use tints only for backgrounds.

The Blotch Library's components already follow these rules, so building from them is the easiest way to look right.

Sizes​

The whole screen is 960 by 680 pixels, and a Widget can be given any part of it, from a small square to the full screen, landscape or portrait. The Frame owner also adds a border and padding around it. A Widget has to look good at every size. See Design for every size.

Hidden Widgets aren't drawn​

If a Widget is completely covered by other Widgets on the Page, Blotch doesn't draw it at all.