Greenhouse jobs board
How to create a client-side Greenhouse jobs board inside a Gatsby site.
Brightcove’s talent acquisition team needed a way to update the open positions page on brightcove.com automatically any time they made changes in Greenhouse. I technically could have set up a build webhook in Netlify that watched Greenhouse for changes and built the site as things were published, but there are like 12 people in Greenhouse making updates at any one time, and Netlify bills per build minute so…
Client route setup
Client side routes IT IS. Gatsby makes it pretty easy to handle this with @reach/router
. @reach/router
is similar to react-router
is similar to the Nuxt file directory structure this site is built on. Below is a screenshot of the directory structure to generate https://brightcove.com/en/company/careers/open-positions, where [lang]
is one of 6 we serve the site in, and [...].jsx
acts as the index file for /open-positions, as well as a wildcard for anything that may follow that route (like the job listing IDs!).
And this is how the router is set up to account for that, an OpenPositions
component at the basepath
, and a Job
component watching for any job ID number that gets appended to the basepath.
Getting the jobs from Greenhouse
This axios
call is basically it, chief; then we update the allJobs
state value. Is this web development?
Mapping the jobs to a component
There’s some global context management going on in the brightcove Gatsby app around setting and updating our filtered content (as this job board has filters for job department, location, etc), which while cool is not the point of this page - essentially a rambling way of saying for all intents and purposes filteredContent
in this code === allJobs
.
Essentially I’m just mapping each job to a Col
. We use react-grid-system
throughout brightcove.com, so I place the ContentList
in a Row
and auto-magically things are mostly responsive (even though these Col
’s are all set to 12 🤦). The built-in Gatsby Link
component is used to point to the deeper individual job’s page. The departments and offices come back from Greenhouse as an array of objects, so I’m accessing the name of each and .join()
ing them all together with commas if there’s more than 1. The component above ends up rendering this:
For reference here’s the component markup for the entire OpenPositions
page:
The Hero
is a component used throughout our site, it’s exactly what it sounds like. ContentFilter
again is a component used in several places that’s relying on a more global context provider, but essentially it takes an array of items to sort and an array of filterConfig
containing the values to filter the items by, and sets filteredContent
based on those parameters. The following Container
, Row
, and Col
components are tied to the react-grid-system
pacakge I mentioned before, within which you can see the <ContentList />
component I described above.
Bada-bing thats how you make a job board and get paid for it.
Last updated: 12/9/2021