Skip to main content

Improving the Learn Section Sidebar

Travis

Travis

Front End Engineer

I promise these blog artictles won't always be about tech/software/the website, but I do feel it's appropriate to talk about updates I make to the site, issues I run in to while making changes and how I solve those issues. This will help to document common problems and how to solve them, hopefully increasing efficiency when updating the site while also sharing these solutions with others who may be using the same or similar tools.

In its current state, the site is built using Docusaurus. It's a great "Docs" tool that many larger SaaS type companies use. I personally like the structure for its built in blog and easy-to-navigate docs system. A recent update included a collapse button to the sidebar as well as autogenerating sidebar content. They've included a ton of other features as well that I will be making use of in the near future, but small changes first!

Making the Sidebar Hideable#

In the spirit of small changes first, the easiest change to make was adding the option to hide the sidebar.

Docusaurus comes with an autogenerated config.js file. This file is where you can configure your theme, navigation bar, footer, title, site metadata and more.

A simplified version of the config file will look like this:

docusaurus.config.js
module.exports = {
themeConfig: {
colorMode: {
defaultMode: 'light',
disableSwitch: false,
respectPrefersColorScheme: true,
switchConfig: {
darkIcon: '๐ŸŒ™',
lightIcon: '\u2600',
// React inline style object
// see https://reactjs.org/docs/dom-elements.html#style
darkIconStyle: {
marginLeft: '2px',
},
lightIconStyle: {
marginLeft: '1px',
},
},
},
},
};

themeConfig comes with a few options. The one we're interested in is hideableSidebar:

This is a boolean option that is set to false by default. All we have to do is make this simple change:

docusaurus.config.js
module.exports = {
themeConfig: {
hideableSidebar: true,
colorMode: {
defaultMode: 'light',
disableSwitch: false,
respectPrefersColorScheme: true,
switchConfig: {
darkIcon: '๐ŸŒ™',
lightIcon: '\u2600',
// React inline style object
// see https://reactjs.org/docs/dom-elements.html#style
darkIconStyle: {
marginLeft: '2px',
},
lightIconStyle: {
marginLeft: '1px',
},
},
},
},
};

And with that we get:

sidebar collapse button

A neat little double arrow button that collapses the menu on click!

That's all it takes. Docusaurus has a TON of other features, components, React components and Hooks and more that we'll dive in to while building and improving the site.

The more tasking challenge is in restructuring the sidebar content to autogenerate, creating a cleaner file structure as well.

Operation: Reorganize Sidebar Menu Items#

The old setup on first deploying the site was quite jenky and would be really difficult to keep up with adding new content:

sidebar.js
module.exports = {
mainSidebar: {
'Start Here': ['env1', 'env2', 'env3'],
'The Basics': ['basics',
{
'HTML': ['html1'],
'CSS': ['css1'],
'JavaScript': ['js1'],
},
],
'Advanced': ['advanced',
{
'Advanced HTML': ['forms'],
'Advanced CSS': ['flex'],
'Advanced JavaScript': ['objects'],
'React': ['r1'],
'Node': ['n1'],
},
],
'React': ['react',
{
'React': ['state'],
},
],
'Node': ['node',
{
'Node':['node1'],
},
],
'Deno': ['deno',
{
'Deno': ['deno1'],
},
],
},
};

This style cascades each section, which creates problems as you want to add more content. On top of that, you have to manually add file names by ID, which you give in the Markdown file. It looks bad with this, but imagine how much more of a mess it would be if we continued with this structure while adding on more course material, challenges and tutorials! Luckily, they have added an option to autogenerate sidebar content. It takes some effort upfront, but longterm it will save a lot of time and effort!

To do this, we also need to clean up and organize the file structure within the docs. In this old state, it currently looks like:

old docs structure

On top of the sidebar.js mess, this is going to be incredibly hard to navigate as more content is added. Instead, we want to opt for something more in line with:

new docs structure plan

As you can probably guess, this means adding folders and renaming files. It's some hefty work, but if we don't do it now, it's going to be even more difficult to do later on.

Because this is a large undertaking with the potential to break the site, I'll start by creating a new Git Branch:

git branch sidebar
git checkout sidebar
git push --set-upstream origin sidebar

This way, it's safe to make changes without potentially pushing up a broken site. We'll do this more often with other coding lessons/tutorials/challenges as well, as it's a good habit to get in to, particularly when working with teams.

I'll start by first creating the new folders that I want to be the sub-menu items:

new docs folders

From here I can start moving files to where they should live, getting rid of extra files that really don't make any sense in the process. It'll start to look a bit like this:

moving files into folders

At this point, I've run in to some errors that crash the site, which is why we do this in a separate branch! Unfortunately I did not screenshot these as I should have for reference, but here's the rundown:

We got an error stating that a property added to sidebar.js was invalid. That property happened to be the type: autogenerated property. After some quick Google-Fu and further inspection, I realized I forgot to update my version of Docusaurus. There are a few ways to do this, but I opted to go for:

yarn upgrade @docusaurus/core@2.0.0-alpha.73 @docusaurus/preset-classic@2.0.0-alpha.73

After this, I ran:

npx docusaurus --version

To confirm the update worked properly. Success there! Unfortunately, after the update, we had more errors. Fortunately, these errors better pointed out the problem.

The new error came in as:

Error: Bad sidebars file.
These sidebar document ids do not exist:
- Lessons
- Start,

This came up as I attempted to over-complicate the autogenerate setup with some unneccesary extra steps. To be clear, what I had originally done would work with some additional setup, but for now it's not neccessary. The simple fix?

{
type: 'autogenerated',
dirName: '.',
},

This cleared the error, site loaded and sidebar loaded. Unfortunately, everything is out of order! But hey, look at how small the sidebar.js file is now compared to before. So much easier to deal with!

Rename Documents and Add Category Files#

To make this work properly we need to rename our documents, and give them a sidebar position in the Markdown header. We probably don't need to do both, but I figure it's better to be safe and make sure they fit properly. I started by renaming the files to better match what topic they cover, prefixing them with a number like:

01-Setup Environment.md

And within each file itself, I added these to the header section:

sidebar_position: 1

For that file to be at the top, 2 for next, 3 for next and so on.

Now our files are listing in order after going through each one! Time consuming I tell ya! Way worse if I had waited longer to do this.

The final step is in adding a _category_.json file to each folder section to keep each subsection in their proper order. This part was easier, as all that was needed was to add a new .json file in each folder like:

{
"label": "Start Here",
"position": 1,
"collapsed": false
}

And update the label and position to match where they should live on the Sidebar. There's an added option of "collapsed" to tell Docusaurus if it should default to being open or closed.

After all this, we now have:

new structure

Much better! And, as mentioned, our sidebar file now looks like:

sidebar.js
module.exports = {
mainSidebar: [
{
type: 'autogenerated',
dirName: '.',
},
],
};

Compared to the massive rats' nest above, this is so much easier to handle. No more manually adding new files and submenus. Easier to navigate for my future self. This took time mostly on renaming files and folders, a little bit on fixing errors mentioned, but overall completely worth the time invested in to it.

That's all for this post! I'll continue sharing updates I make as they come in, particularly with errors and how to solve them. I'll be sure to grab screenshots of those issues next time too!