JS solution for hiding an Obsidian Publish Sidebar
Essays and updates on product, engineering, and AI by Chase Adams.
3 minute read
This snippet should be added to your publish.js.
Info
If this is the first part of your
publish.js, I recommend uncommenting the commented out(function() {and})();lines so that you isolate the scope of this function
JS Snippet for publish.js
//(function () {
function maybeSetFocusMode() {
const noteContainer = document.getElementsByClassName("markdown-rendered")[0];
const hideSidebarClassname = "focus";
const rightSidebarClassname = "site-body-right-column";
const rightSidebar = document.getElementsByClassName(
rightSidebarClassname
)[0];
// if you want to also do the left sidebar, uncomment all of the commented out code that starts with leftSidebar
const leftSidebarClassname = "site-body-left-column";
const leftSidebar = document.getElementsByClassName(leftSidebarClassname)[0];
if (noteContainer.className.includes(hideSidebarClassname)) {
rightSidebar.style = "visibility: hidden; flex: 0; width: 0;";
leftSidebar.style = "visibility: hidden; flex: 0; width: 0;";
} else {
rightSidebar.style = "";
leftSidebar.style = "";
}
}
function initializeRendererObserver() {
// run on page transition
new MutationObserver(maybeSetFocusMode).observe(
document.getElementsByClassName("markdown-rendered")[0],
{
attributes: true,
}
);
// run on page render
maybeSetFocusMode();
}
initializeRendererObserver();
//})();
This sets up a MutationObserver that observes the element with the markdown-renderer class of your site. Anytime that element changes (ie, when you visit a different page), it runs the callback function (the first argument passed to MutationObserver).
The function...
- gets the
markdown-rendereragain so that it has a non-stale instance to check from - ❗
hideSidebarClassnameshould be whatever your classname needs to be based on thecssclassproperty in your metadata of the filei - gets the sidebar by classname
- if the
cssclassyou want to use to hide the sidebar is present, it will hide the sidebar - if it's not present, it will make it visible
An alternative based on frontmatter
It's possible you want to use frontmatter instead of the cssclass to decide whether to do something in this observer. 1
Here's an alternative script that you can use to check the .frontmatter element for the presence of a field (in this example, I'll use mode: focus):
//(function () {
function maybeSetFocusMode() {
const noteContainer = document.getElementsByClassName("markdown-rendered")[0];
const rightSidebarClassname = "site-body-right-column";
const rightSidebar = document.getElementsByClassName(
rightSidebarClassname
)[0];
// if you want to also do the left sidebar, uncomment all of the commented out code that starts with leftSidebar
const leftSidebarClassname = "site-body-left-column";
const leftSidebar = document.getElementsByClassName(leftSidebarClassname)[0];
if (meetsCriteria()) {
rightSidebar.style = "visibility: hidden; flex: 0; width: 0;";
leftSidebar.style = "visibility: hidden; flex: 0; width: 0;";
} else {
rightSidebar.style = "";
leftSidebar.style = "";
}
}
function meetsCriteria() {
var yamlContainer = document.querySelector(".frontmatter.language-yaml");
if (!yamlContainer) return false;
return yamlContainer.textContent.includes("mode: focus");
}
function initializeRendererObserver() {
// run on page transition
new MutationObserver(maybeSetFocusMode).observe(
document.getElementsByClassName("markdown-rendered")[0],
{
childList: true,
subtree: true,
}
);
// run on page render
maybeSetFocusMode();
}
initializeRendererObserver();
//})();
Some important distinctions about what changed...
- In the
MutationObserver, instead of only running onattributeschange, we need to check an element that's a child of themarkdown-renderedelement, so we setchildListandsubtreetotrue. - Instead of checking that the
classNameincludes something, we need to get the.frontmatterelement and if it exists, check if it containsmode: focus(which we verify by running themeetsCriteriafunction), then we set the styles.
A loom walking through how it works...
Final Notes
- This solution is not durable. What I mean by that is that if either of the two classes we use to select the renderer or the sidebar change, they'll need to be updated accordingly.
Footnotes
-
(thanks to Jenna of polyrain.dev for the tip on finding the
.frontmatter, I had no idea that element was present!) ↩
Build Your Website with AI—No Code Required
Learn to create and deploy professional websites using ChatGPT and Claude. Go from complete beginner to confident website builder.
