Roam Research Docs · Developer documentation
{{[[roam/js]]}}, then nest a javascript code block underneath it.
console.log("hello from roam/js");
{{[[roam/js]]}} blocks can live on any page, and the code applies to the whole app, not just the page the block is on.
{{[[roam/js]]}} block links to roam/js, so this page's linked references list every script in your graph.
window object, as well as the Available Libraries Roam exports.
javascript, jsx, and clojure. See roam/cljs for clojure.
window.React.
{{[[roam/cljs]]}} works too and behaves identically — same warning, same approval.
{{[[roam/js]]}} block counts, not just direct children.
Roam Depot extensions -> roam/js (or roam/cljs) -> roam/render components.
var and function declarations land on window and are visible to every other code block.
let and const declarations stay inside their own code block.
?disablejs=true to the URL to load with all roam/js, roam/render, and Roam Depot extensions turned off until the next refresh.
window.roamAlphaAPI.ui.commandPalette.addCommand({
label: "Open random page",
callback: async () => {
const uids = window.roamAlphaAPI.q(
"[:find [?uid ...] :where [?e :node/title] [?e :block/uid ?uid]]");
const uid = uids[Math.floor(Math.random() * uids.length)];
await window.roamAlphaAPI.ui.mainWindow.openPage({page: {uid}});
}
});
window.roamAlphaAPI.ui.commandPalette.addCommand({
label: "Open Reading List in sidebar",
"default-hotkey": "ctrl-shift-7",
callback: () => {
const uid = window.roamAlphaAPI.q(
"[:find ?uid . :in $ ?title :where [?e :node/title ?title] [?e :block/uid ?uid]]",
"Reading List");
window.roamAlphaAPI.ui.rightSidebar.addWindow(
{window: {type: "outline", "block-uid": uid}});
}
});
async function ensureTodayHasJournal() {
const api = window.roamAlphaAPI;
const todayUid = api.util.dateToPageUid(new Date());
if (!api.q("[:find ?p . :in $ ?uid :where [?p :block/uid ?uid]]", todayUid)) {
await api.data.page.create(
{page: {title: api.util.dateToPageTitle(new Date())}});
}
const existing = api.q(
"[:find ?c . :in $ ?uid ?text :where [?p :block/uid ?uid] [?p :block/children ?c] [?c :block/string ?text]]",
todayUid, "Journal");
if (!existing) {
await api.data.block.create(
{location: {"parent-uid": todayUid, order: 0}, block: {string: "Journal"}});
}
}
ensureTodayHasJournal();
function getPageUid(title) {
return window.roamAlphaAPI.q(
"[:find ?uid . :in $ ?title :where [?e :node/title ?title] [?e :block/uid ?uid]]",
title);
}
function getChildUids(parentUid) {
return window.roamAlphaAPI.q(
"[:find [?uid ...] :in $ ?parent :where [?p :block/uid ?parent] [?p :block/children ?c] [?c :block/uid ?uid]]",
parentUid);
}
{{[[roam/js]]}} block so you can turn them on and off individually.
console.log output and script errors both land there.