How I publish Nuggets directly from RoamResearch to

Jan 22

Fun Fact This article has been written entirely in RoamResearch in order to test the efficacy of my setup ✌🏻 SO META πŸ€“

RoamResearch is the best tool I have discovered in the last year. Over time, it has been the main driver for improving my productivity (or at least perceived productivity πŸ˜…). I use it for note-taking, project management, planning, journaling, habit tracking (still need to figure out a good system for this, suggestions welcome πŸ™πŸ»), and thanks to an awesome chrome extension, I am already tweeting from it 🀩

One of my goals in 2021 is to share my knowledge and engage with online communities. Since I am already accumulating knowledge in RoamResearch, and to reduce context switching, whenever I have an idea for a Nugget, I want to write it down immediately. My roam DB is open at all times, so it feels like the most natural and fastest way for me to write my idea down before I get distracted or lose focus. πŸ€“

Furthermore, The notes I write in Roam have backlinks, which helps me with discoverability and serendipity. I then have a SmartBlock that takes advantage of roam42 converter [1] to convert the text to markdown and strip the links from it. For example, for this article, here is how it looks from inside RoamResearch (Again, SO META πŸ€“)

Finally, I like carving out my own solutions to already solved problems. This Is Cool GIF by MOODMAN

Inspired by David Bieber Snippets [0], I wanted to create a system that allows me to share any bit of knowledge from RoamResearch to Why call them Nuggets? Well, I didn't want to also call them Snippets 😈 But most importantly, take a look at the definition of a golden nugget in Wikipedia

A gold nugget is a naturally occurring piece of native gold. Watercourses often concentrate nuggets and finer gold in placers. Nuggets are recovered by placer mining, but they are also found in residual deposits where the gold-bearing veins or lodes are weathered. Nuggets are also found in the tailings piles of previous mining operations, especially those left by gold mining dredges.

For me, a Nugget is a raw piece of knowledge, rough and unedited. Either newly discovered or formed and synthesised as a residue from my previously collected knowledge

I chose for two reasons:

  • is a great online community geared towards developers, it is very fitting for the content I want to produce which is going to be mainly technical.
  • It has an awesome API that allows me to post articles to the platform. I also have a personal website that syncs with my published articles in using a webhook (still work in progress. I will publish an article about the process once I am done with it ✌🏻)

Here is now an explanation of how my process works

Create a Smart Block to generate a Nugget

This is a simple smart block that does the following

  • Add tag reference to Nugget pages. this is important for me in order to keep track of all the published Nuggets inside my graph
  • Use the --- separator to create a section for the Front-matter attributes
  • For the title and the tags, I use the <%INPUT%> SmartBlock
  • I then place the cursor after the separator to signify the start of the Nuggets body
  • Note: because of some limitations and gotchas in the syntax (which I will talk about later), I am not yet confident to directly publish the article so I create it as a draft (published: false)

Create a SmartBlock to publish my article to

This SmartBlock is mainly in javascript, it gets the children blocks and takes advantage of roam42 helper functions to convert it to Github markdown

  • Github flavoured markdown has differences with the syntax uses, so I had to do the following changes
    • Change Twitter, Youtube, StackOverflow and StackExchange links from markdown to LiquidTags syntax [2]
    • I learned that highlights denoted by ^^ is not part of markdown syntax [3] So I had to change them to HTML <mark>
  • One other "limitation" I noticed is that If you don't have an empty line at the end of a code block, it will not render properly.
  • One last thing, does not allow to publish from the frontend due to CORS issues, you need to create a proxy server to the api. I created a simple node.js server you can see here

I have created an issue with the SmartBlock if you want to use it πŸ™πŸ»

Publish Roam page to #191


βœ‚οΈ Copy of your #42SmartBlock from Roam

  • #42SmartBlock Publish Nugget
    • <%JAVASCRIPTASYNC:```javascript
      // Get the page block uid 
      const pageUid = window.location.href.split('/').reverse()[0];
      // Walk the blocks tree and generate markdown using roam42 helper functions
      let md = await roam42.formatConverter.iterateThroughTree(pageUid, roam42.formatConverter.formatter.markdownGithub);
      // Modify generated markdown to be conform with 
      md = md
        // convert links to liquid tags
        .replaceAll(/https:\/\/twitter\.com\/.+\/status\/(\d+)[?]?.*/gmi, "{% twitter $1 %}" )
        .replaceAll(/https:\/\/stackoverflow\.com\/questions\/(\d+)\/.*[?]?.*/gmi, "{% stackoverflow $1 %}")
        .replaceAll(/https:\/\/stackoverflow\.com\/a\/(\d+)\/.*[?]?.*/gmi, "{% stackoverflow $1 %}")
        .replaceAll(/https:\/\/(.*).stackexchange\.com\/questions\/(\d+)\/.*[?]?.*/gmi, "{% stackexchange $2 $1 %}")
        .replaceAll(/(https:\/\/[\w\.]\/wiki\/[\w]+)/gmi, "{% wikipedia $1 %}")
        .replaceAll(/https:\/\/\/([\w-]+\/[\w-]+)\/?/gmi, "{% github $1 %}")
        .replaceAll(/(https:\/\/\/[\w-]+\/[\w-]+\/issues\/\d+)/gmi, "{% github $1 %}")
        .replaceAll(/https:\/\/\/edit\/#!\/([\w-]+)[?]?(?:path=)?([\w.]+)?/gmi, "{% glitch $1 file=$2 %}")
        .replaceAll(/https:\/\/\/edit\/#!\/([\w-]+)/gmi, "{% glitch $1 %}")
        .replaceAll(/{{video: (.+)}}/gmi, (v, url) => {
          // Neat trick to get the id of youtube video
          const id = new URL(url).searchParams.get('v');
          return "{% youtube " + id + " %}";
        .replaceAll(/\^\^(.*)\^\^\s/gmi, "<mark>$1</mark> ");
      // Delete the text from markdown that is above the frontmatter marker
      md = md.split('---');
      md.splice(0, 1, ' ');
      md = md.join('---').trim();
      // Make a post request with the markdown to glitch reverse proxy server 
      await fetch('', {
          method: 'POST',
          headers: {
            "Content-Type": "application/json"
          body: JSON.stringify(
            {"markdown": md})
      return "#published";```%>

πŸ“‹ Describe the SmartBlock

SmartBlock to convert page content to markdown and format it to conform with article syntax and then publish it.

βœ… Describe any prerequisites or dependencies that are required for this SmartBlock

You need two things: 1. a certain page structure, I have a simple SmartBlock that helps me create this structure

  • #42SmartBlock Nugget
    • #Nugget {{Publish:42smartblock:Publish Nugget}}
      • ---
      • title: <%INPUT:title of the nugget%>
      • tags: nugget, <%INPUT:add max 3 tags%>
      • published: false
      • canonical_url: <%CONCAT:https,://,,<%INPUT:enter slug%>%>
      • cover_image:
      • ---
      • <%CURSOR%>
      1. does not allow to publish from the frontend due to CORS issues, you need to create a proxy server to the api. I personally use a simple node.js server in you can copy from here!/roam-to-dev?path=server.js

πŸ“· Screenshot of your #42SmartBlock workflow/template from Roam

πŸ’‘ Additional Info

And that is it, I now have a system that allows me to publish content from RoamResearch to Thanks to RoamResearch for being so extensible, and also to the awesome community and especially RoamHacker for coming up with SmartBlocks (If you want to a deep dive into the internals of SmartBlocks, make sure to watch this awesome, and long πŸ˜…, video ;) )






text highlight in markdown


Within a Markdown editor I want to support text highlight, not in the sense of code highlighting, but the type of highlighting people do on books.

In code oriented sites people can use backquotes for a grey background, normally inline code within a paragraph. However on books there is the…