Dojo from the Blocks

Dojo blocks

One of the low-key features that was released in Dojo 5 was the introduction of Blocks. Blocks go hand-in-hand with Dojo build time rendering.

What Blocks allow you to do is run some arbitrary code in a node environment during the build process.

Build time rendering is a great tool you can use to generate static content without having to worry about any server side component to generate pages as requested.

For example, you could use Blocks to preprocess images that you might want loaded into your page, or maybe a more common use case of converting markdown to use for you blog or site. Blocks give you the flexibility to run code you might normally run in the server environment during your build process.

Building a block

Maybe I want to build my blog on top of Dojo, and I want to just write my articles in markdown. I can use a library like showdown to parse my markdown files to HTML. Here is a very basic module that can do this.

// src/blocks/markdown.block.ts
import * as fs from 'fs';
import { resolve } from 'path';

import { Converter } from 'showdown';

const mdConverter = new Converter();

export default function (path: string) {
  path = resolve(__dirname, path);
  const file = fs.readFileSync(path, 'utf8');
  // convert Markdown to HTML
  const html = mdConverter.makeHtml(file);
  return html

Blocks are types of metas you can use in your widgets. I can use my block by calling the meta, and running it with with the needed arguments, like the path to the markdown file I want to parse.

import WidgetBase from "@dojo/framework/widget-core/WidgetBase";
import { dom } from "@dojo/framework/widget-core/d";
import Block from "@dojo/framework/widget-core/meta/Block";
import { tsx } from "@dojo/framework/widget-core/tsx";

import fromMarkdown from "../blocks/markdown.block";

import * as css from "./styles/About.m.css";

export default class About extends WidgetBase {
  protected render() {
    const node = document.createElement("div");
    // Use my block
    const message = this.meta(Block).run(fromMarkdown)(
    node.innerHTML = message;
    // Create a vnode to inject my HTML
    const vnode = dom({ node });
    return (
        <h1 classes={css.root}>About Page</h1>

I can now naively inject my parsed markdown as HTML into my page. Ideally, I would like to convert that HTML into real virtual dom nodes, but I haven’t gotten that far yet.

You can quickly see how useful this would be during build time to process files, maybe pull in some external files and use them in an app.

Image processing

In my app, I might have some images that I want to convert to base64 strings so I can embed them. I can use a tool like sharp to resize my images. When I do, I can go ahead create the virtual dom nodes and return them in my block.

// src/blocks/imagebase64.block.ts
import { resolve } from 'path';
import { v } from '@dojo/framework/widget-core/d';
import * as sharp from 'sharp';

export default async function (path: string) {
  path = resolve(__dirname, path);
  // resize my images
  const images = [
    await sharp(path).resize(200).toBuffer(),
    await sharp(path).resize(300).toBuffer(),
    await sharp(path).resize(400).toBuffer(),
    await sharp(path).resize(500).toBuffer()

  return =>
    v('img', { src: `data:image/jpeg;base64, ${a.toString('base64')}`, alt: 'sally' })

You might notice, that I’m able to run asynchronous tasks inside my block. This allows me to do some more interesting things like image processing, fetching data, or maybe run some sort of analysis on a dataset to create formatted json that can be used by a charting library! I’m just throwing out some ideas here!


You can view the source code for this sample here, and you can view a live demo here.

Dojo Blocks are really interesting, and I think they provide a whole new level of functionality for developers taking advantage of build time rendering with Dojo. I don’t see a reason not to use build time rendering, and Blocks offer you a whole new opportunity to get crazy about it. I’m currently looking at a rewrite of my blog with Dojo using them!

Build Time Rendering in Dojo

Dojo Build Time Rendering

You may have worked with other frameworks that support server side rendering. What it basically does is render the HTML of your page and pass it down to the client as it would look when the initial JavaScript loads and then you can interact with it and the JavaScript stuff works its magic to make a cool interactive application.

The Dojo method of doing this is much simpler. Instead of rendering the pages on the server, you can create your pages during the build process, and then you can just upload it anywhere.

You can find some information about Build Time Rendering on the github page for dojo/cli-build-app. You can get started by using the dojo/cli to quickly scaffold an application and modify it a bit.

Once you have your template application ready to go, let’s make some modifications. First thing we need to do in src/index.html is add a root div that the build time rendering tools can work with.

<!DOCTYPE html>
<html lang="en-us">
  <meta name="theme-color" content="#222127">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <div id="root"></div> <!-- Add this element -->

Now we can set up the configuration for build time rendering. One thing to note is that by default, the template application uses hash routing, meaning that routes look like myapp/#about. This will generate a single index.html file in your build that will quickly load those routes. If you use a different history manager, it will create an index.html for each route.

  "build-app": {
    "build-time-render": {
      "root": "root",
      "paths": [

Note that I have prefixed my paths with a # so that the BTR can generate the pages correctly. The output of this is pretty interesting. Each route is stored in an array as strings, and as you change your route at runtime, it will load the HTML of that route as needed.

The benefit here is that your HTML is ready to go and the JavaScript parts just do their thing without having to do an initial render of your page. It makes for a very responsive experience. You get a lot of benefit from Build Time Rendering with some simple configuration, so take advantage of it!

You can see a sample of how this looks in a sample application I put together here. I also have it running live here.