# JS solution for hiding an Obsidian Publish Sidebar

> How to hide the Obsidian Publish sidebar with JavaScript.

Source: https://curiouslychase.com/engineering/js-solution-for-hiding-an-obsidian-publish-sidebar/

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`

```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-renderer` again so that it has a non-stale instance to check from
- ❗ `hideSidebarClassname` should be whatever your classname needs to be based on the `cssclass` property in your metadata of the filei
- gets the sidebar by classname
- if the `cssclass` you 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`):

```js
//(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 on `attributes` change, we need to check an element that's a _child_ of the `markdown-rendered` element, so we set `childList` and `subtree` to `true`.
- Instead of checking that the `className` includes something, we need to get the `.frontmatter` element and _if it exists_, check if it contains `mode: focus` (which we verify by running the `meetsCriteria` function), then we set the styles.

# A loom walking through how it works...
<div className="iframe-wrapper">
<iframe width="640" height="712" src="https://www.loom.com/embed/7deed8eee54444f6bd6979d314e7dc82" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>

# 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.

[^1]: (thanks to [Jenna of polyrain.dev](https://polyrain.dev/blogs/2021/Getting+comments+on+my+Obsidian+Publish+site) for the tip on finding the `.frontmatter`, I had no idea that element was present!)
