Migrate to Netlify Today

Netlify announces the next evolution of Gatsby Cloud. Learn more

ContactSign Up

Bottoms Up: Gatsby File System Route API + Bums = BumHub

Paul Scanlon
January 28th, 2021

Hello I’m Paul 👋and for my Silly Site Challenge I created BumHub, “The cheekiest way to explore GitHub.” I developed this site in public and kept a dev diary of my progress throughout the challenge. For those of you who weren’t following along at home, here is a condensed rundown of how the project grew.  

Concept

Prior to the Silly Site Challenge I’d seen Gatsby’s announcement regarding the new and improved Routes API, along with Tweets and posts from folks explaining how it works. However (and this isn’t to knock anyone’s hard work) these explanations all seemed to reiterate the Gatsby docs…And because I like to make my life difficult, I started to think about ways to make my own explanation of the Routes API a bit different. 

Then it hit me. There’s a section in the Gatsby docs that states,

Use the File System Route API when you want to programmatically create pages from your GraphQL data, e.g. to create individual blog post pages for your blog. With this API you can control the file path and queried data by adding some extra notation to the names of your files without touching or creating gatsby-node.js whatsoever.

The key bit being Without touching or creating gatsby-node.js whatsoever

This statement is 100% accurate but it only applies if you already have the nodes in the GraphQL layer. This would be possible if you had a load of pages as actual files on disk, eg. .js, | .tsx | .md | .mdx.

But: What if your site content doesn’t pre-exist on disk? What if your site content comes from a remote source — like (totally common instance) a CMS? In this scenario you will absolutely need `gatsby-node.js`… and there was the angle for my silly site idea.

All I needed now was a suitably silly site content source to drive the page creation. Just out of curiosity I looked on GitHub to see if there were any repositories that contained the word bum or bums…and joy of joys there were loads. 

(Why bums, I hear you ask? Well, regardless of our differences as humans, the one thing we all have is a bum. And, really, what’s sillier than a bum?)

Is this even possible????

So a super silly idea, but first I needed to investigate the GitHub API and to work out if and how I could query GitHub and retrieve all repositories that contained the word bum in either the name or description. Was it even possible?

After a bit of tinkering, this was the query I constructed. (It’s paginated because, as mentioned, there’s loads of bums on GitHub 🙃).

The response data is an array of repository names, together with information about the owner, the programming language used, issues, PR’s and stargazer count. By fetching this data at build time using sourceNodes within gatsby-node.js and combining it with createNode I’m able to inject the GitHub response data into Gatsby’s GraphQL layer. Once the data is inside Gatsby world, you can leverage the new Routes API by using a GraphQL node name as part of the page template file name — e.g, {{bums.name}}.js .

When I first saw this I thought Holy double curly brackets Batman, does that really work?!?

It really does! 

This method, which I can only assume is some kind of NASA level regex, is how the Gatsby engineers allow us to create pages from GraphQL nodes, or in my case nodes that are actually repository names sourced from GitHub. 

Bum Search interface

Thanks Gatsby engineers, this is some top shelf tekkers! 🙏

Now what?

The Jsx in the page template is populated by using a good old fashioned Gatsby page query plus the node $id. (That part is actually old school Gatsby, but I do really like the new Routes API, using createPages in gatsby-node.js was always a bit of faff IMO).

So I have data and I have a name… now what?

I wanted to build this project in public. Also, by using the #SillySiteChallenge hashtag, I was hoping to raise awareness and meet like minded folk. By incrementally enhancing the site as the challenge progressed, I hoped to keep users intrigued and coming back for return visits. Given that the #SillySiteChallenge took place in the month of December it seemed appropriate to create an advent calendar. The plan was to, ahem, expose a new bum for each day of Christmas without me needing to do any development work.

Merry Christmass

I have in the past created advent calendars for the web and had always struggled with how to manage the current date. As you may already know, changing your system clock will trick any browser based date logic into thinking that today is whatever day you say it is in your system preferences. I wanted to prevent this and ensure that today was always todays’ date.

To achieve this I planned on retrieving today’s date from a server endpoint provided by a Netlify Function. This way, regardless of what date your system preferences say it is, the actual date will always be returned correctly by the Serverless Function. 

Once I knew I could prevent date hacking, I had the basis for the condition to determine when to activate, disable or highlight a link for each of the bum pages created by the Routes API.

At this point I had an abundance of bum data and had devised a solid way to conditionally render a list of page links. I could have stopped here but thought to myself, No, Paul, that’s not good enough, build an entire application.

(As already mentioned, I do like to make my own life difficult).

Bonus feature 1: Bum Search

Now that I had data I wanted to demonstrate what I would refer to as “app like” functionality.

I wanted to do this purely because I regularly see comments on Twitter suggesting that “Gatsby is just for blogs.” I’ve never understood this. From the very start of my love affair with Gatsby It was clear to me that Gatsby is React. I’m not sure how or why this isn’t immediately understood, but creating Bum Search is my way of showing that if you can do it with React, you can do it with Gatsby!

The Bum Search page would feature a fully functioning search table with inputs, selects and column sorting functionality so users could explore the full data set returned by GitHub in a number of different ways.

Arguably, in the context of BumHub, this kind of functionality might not be that useful. More important is the proof of concept, that it’s possible to do such things with Gatsby. (As a side benefit, it also demonstrates my ability to use array methods…Which hopefully might allow me to swerve pointless tech tests when applying for future contracts. 😜)

Bonus feature 2: EcoBum

Because Gatsby is predominantly a static site generator — though it can do so much more! — it is fundamentally eco-friendly. Since the lion’s share of the work is handled server side at build time, rather than by each and every browser that visits your site at run time, much less of the world’s power gets used up. Much less power means much less CO2, and much less CO2 makes for a healthier planet. I planned to surface some of this Eco-Friendliness by leveraging statistics provided by EcoPing.

Of course, what better way to visually represent this than by using farts?

EcoBum interface

Bonus feature 3: Bum UI

I wanted to make a bit more of a fuss about Theme UI and If you haven’t tried it already, i’d highly recommend giving it a go. 

Theme UI comes with a bunch of built-in components that can be used for all the usual user interface elements, buttons, loaders, headings, inputs etc and best of all it’s quite easy to re-style using the theme object. And clearly the world lacked a bum-centric version. 

THeme UI with bums

Now I just had to make all these bums look good. 

Art Direction

This is normally my least favorite part of any project. I’ve known for many years that when it comes to illustration and logo design I quickly run out of talent. To ensure BumHub was correctly positioned as something light hearted and silly (rather than offensive and tawdry) I knew I needed something that looked and felt fun… just like a bum.

Researching illustrators on dribbble, I found some wonderfully cheeky little ghosts by the wonderful Miss_ChatZ . I had a pretty clear idea of my vision for all this bum stuff, but communicating that to someone I’ve never met over email is no easy task. Luckily for me, Miss Chatz is a pro and an absolute sweetheart and we immediately clicked. When I emailed my list of deliverables that explained the bigger picture of how I wanted the logo and each ancillary character to look she just ran with it. I’m so, so pleased with her vision.

We worked through a few rounds of initial ideas for the logo before arriving at one that I felt would fit in with the design of the site…Which at that time only existed in my head.

iterative logo designs for BumHub

We followed a similar process to create the cartoon bums themselves. I really liked the way Miss Chatz worked, starting with grey sketches then introducing color before arriving at a point where we were both happy. 

design iterations of cartoon butts

The final colours changed a bit from what you see here. This was somewhat influenced by accessibility and color contrast requirements. Another thing to love about Gatsby is how accessibility is a core component of the framework.

Design

It’s been quite some time since I was officially a “web designer” but, following the tried and tested approach of boxes on a page that stack on top of one another on smaller screen sizes, this is the page layout design  for BumHub 🤷‍♂️.  Essentially, a single page app approach. 

page layout in boxes

…And, at last…

Development

With data, art direction, “design” and Theme UI all in place, developing the site was an absolute tray of cakes 🍰.

I had a clear idea in my head of what the finished site would look like. By using elements from each of the previous process steps I was able to work on one feature at a time, which is not only better for my mental health but also allows me to clearly define what I’ll be working on and aiming to complete by e.g the end of the week. Silly Site Challenge did have a December 31st deadline — what if I missed the deadline and didn’t get to show everyone my bums??? — so it was important to gauge my progress as the time ticked by. 

theme components for BumHub

Naturally there are a number of crossover areas of the UI, eg typography and buttons etc. These were tweaked and changed with each feature release — but with Theme UI taking care of style management, updating theme styles for use in one part of the site meant the same styles automatically updated elsewhere around the site. 

There weren’t many issues with the development, and by abstracting the more complex components out of the pages allowed me to work on them in isolation. You can see all of the individual components on the Bum UI page. The most complex one was probably the Advent Card and you’ll see that I’m using a prop driven approach that kicks the Card into one of three states. I was able to develop this without needing to hook it up to the real data — which meant re-fetching data and hot-reloading when I was making changes didn’t slow me down.

advent card feature of BumHub

I took a similar approach with GitHubStat and EcoStat , but both of these components are hooked up to two different data points.

GitHubStat is powered by the page query from the {{bum.name}} as mentioned above. EcoStat, however, is powered by a special end point provided by EcoPing. So special, in fact, that to keep it a secret I make a client side GET request to my own Netlify Function endpoint, which in turn hits the EcoPing endpoint. This ensures that even if any Nosey Nellies go poking around the network tab they won’t be able to see where the EcoPing endpoint actually is. Moreover, I’ve defined the EcoPing endpoint as an envvariable so even if you locate the Netlify Function in the repo you won’t see the real endpoint…All very secret squirrel isn’t it 🐿️.

A simpler but really enjoyable component to make was the StarBurst. I hadn’t previously attempted to use CSS keyframes with Theme UI so it was a really fun piece of development. (The `src` for that component can be seen here).

Bonus bonus feature

As mentioned above, the development was an absolute breeze and I feel it’s largely due to the amount of planning and my strict rule of not writing code too early. So, thanks to past me, it was looking like I was going to finish the whole project with time to spare. But I wasn’t quite ready to quit yet!

Never being one to shy away from a challenge, I conjured up the final idea: BumBum Maker.

Contrary to my usual approach of “plan first, then code,” this feature wasn’t part of the original concept. So it’s just blind luck that all of the elements for each bum character could be interchanged with one another. 

I’m so pleased I went the extra mile and created this feature! I actually think it’s the best part of BumHub

bumbum maker interface

Bum Bum Maker really reminds me of the kind of Flash work I used to do all those years ago. Putting this together was a great deal of fun, and I’m so happy that I did indeed manage to bring back some of that creative joy I had been missing from my career in “pure tech.”

If you want to dive a little deeper into some of my technical approaches, you can find deeper details on how I made each feature, together with code snippets, on my blog.

Stay silly, everyone! 🕺

Wanna learn more cool Gatsby tricks? Register for GatsbyConf two days of speakers, workshops, and some really cool launches and announcements plus Gamer vs. Gatsby. Watch live as World Record holder Kosmic tries to beat his Super Mario Bros speed run world record while Gatsby engineer Kyle Gill races to spin up a live ecommerce site! Thrills! Chills! Free and virtual, March 2-3, see you there!

 

 

Share on TwitterShare on LinkedInShare on FacebookShare via Email

After all is said and done, structure + order = fun! Senior Software Engineer (Developer Relations) for Gatsby

Follow Paul Scanlon on Twitter

Tagged with gatsby-file-system-route-api, gatsby-silly-site-challengeView all Tags

Talk to our team of Gatsby Experts to supercharge your website performance.

Contact Gatsby Now
© 2023 Gatsby, Inc.