Building The Collab Lab's website using 11ty and GraphCMS
Tags: 11ty, graphcms, netlify, zapier
Published: 2020-12-21 21:10:42

## What is TCL

The Collab Lab is a U.S. nonprofit that provides remote, collaborative project practice for early-career developers. We focus on teaching how professional software teams work by working through a structured project over the course of 8 weeks under the guidance of mentors who are professionals in the field. Collab Lab is volunteer-driven and free for participants. More information about the program is available on [our website](https://the-collab-lab.codes).

## What is GraphCMS

GraphCMS is a hosted system for managing content. It is what’s called a “headless” CMS, meaning it is not concerned with the presentation of the content, just the structure of and relationships among the various bits.

As the name implies, GraphCMS was built from the ground up on [GraphQL](https://graphql.org). GraphQL is a developer-friendly alternative to [REST](https://restfulapi.net/) as a way of structuring and serving APIs. How to work with GraphQL itself is outside the scope of this article, but know that GraphCMS fully integrates [GraphQL playgrounds](https://blog.logrocket.com/complete-guide-to-graphql-playground/), making it simple to experiment with queries until you get your endpoints serving just what you need.

## Migrating from a fully static site to 11ty

At The Collab Lab we decided that it was time to step up our website game and start using something other than just plain HTML, CSS and Javascript. We started looking for tools that match our current stack, and that’s where [EJ](https://twitter.com/codeability) introduced us to [Eleventy (11ty)](https://www.11ty.dev/). 11ty is a static site generator that emphasizes simplicity. It doesn't use any JavaScript framework (e.g., Next.js, Gatsby or Nuxt). With 11ty, you can use different template engines as it supports [Handlebars, Liquid, HTML, Nunjucks, Mustache, EJS, Haml, Pug and Markdown](https://www.11ty.dev/docs/), the fun thing is that you can chose to use one, or all of them at the same time 😱. As any other Static Site Generator, its lifecycle is about grabbing data from a datasource — GraphCMS in this case — pass that data to the templates, generate the HTML and then build the site as static HTML.

![Untitled](https://dev-to-uploads.s3.amazonaws.com/i/otsz3p19zo9jh1kny2bz.png) 

A good thing about using 11ty is that the migration was painless, as I said above, our site was just HTML, CSS and JS files, the approach we took, was to keep the old site around and use 11ty to build it and then incrementally start creating new pages with templates and dynamic data. Here you can see the structure before and after for our migration:

![Untitled 1](https://dev-to-uploads.s3.amazonaws.com/i/yfpg19ag6hjpl1pgp0bn.png)

You'll notice two things happened:

1. We use `/build` as our output/build directory before and after the migration.
2. We moved everything inside the `build` directory to the `pages` directory

We can tell 11ty to treat the `pages` directory as its input, and `build` as its output in the `.eleventy.js` config file. From then on, we treated the `pages` directory as our working directory.

{% gist https://gist.github.com/alejandronanez/bf0a47bb158583a51320346ce81402a5 file=.eleventy.js %}

Now it was time to start [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)ing things, so we created a layout file and several other templates (or “components” if you wish) that reduced the file sizes of our pages a lot and made things easier to reason about.

But that’s just half of the story. Now we wanted to make the site dynamic. We were tired of making manual updates to change the content of our site. This is where **GraphCMS** came in.

## Adding Dynamic Content

We wanted to give dynamic content a try in our **[Who We Are page](https://the-collab-lab.codes/who-we-are/)** as it’s the page that we update most often. It roughly looks like the following:

![Untitled 2](https://dev-to-uploads.s3.amazonaws.com/i/6plg5by7ntcwkih0ejte.png)
 

For what it's worth, we didn't migrate the whole page at once, we started out with the **Developers Sub Section**. The steps we followed to make this change were roughly as follows:

1. Created a model in GraphCMS that represents the Developers
2. Added content for that model in GraphCMS
3. Explored the GraphQL API using GraphCMS API Playground
4. Started consuming the data in 11ty.

### Create a model in GraphCMS that represents the Participants'

This step was pretty straightforward, we just modeled the data we needed in our page, and that’s it. For instance, we added the participant's **Firstname** and **Fullname** among other data.

![https://cdn.zappy.app/2ed70ae7107844472dd2901d6f490ca3.png](https://cdn.zappy.app/2ed70ae7107844472dd2901d6f490ca3.png)

### Add content for the Participants model

Again, this was straightforward. You just click the **Content** icon on the left hand side of the sidebar, and then start adding the data you need

![https://cdn.zappy.app/24864c602305a9ddc4cc37bd89922dce.png](https://cdn.zappy.app/24864c602305a9ddc4cc37bd89922dce.png)

### Explore the GraphQL API using GraphCMS' API Playground

One really useful thing that GraphCMS provides, is a playground that you can use to build your queries and try things without any limitation. Once you have the queries in place, you can move them to your development environment and start using them to get real data.

![https://cdn.zappy.app/a2d706e475a11b67b6750033b16934e8.png](https://cdn.zappy.app/a2d706e475a11b67b6750033b16934e8.png)

### Start consuming the data in 11ty.

Inside our `pages` folder, we created a `graphql` folder which acts as our data layer and it contains both, the **requests to GraphCMS** and the **GraphQL Queries**, our folder structure looks like this:

![Untitled 3](https://dev-to-uploads.s3.amazonaws.com/i/zhv5yhlgo0a0wilieq0e.png) 

We started out by writing the query to get the teams. We **don’t get the Developers directly** as our **Developers** section is made of **teams that contain developers.**

![https://cdn.zappy.app/f456ddfd3cb07de7ecea580e5c886188.png](https://cdn.zappy.app/f456ddfd3cb07de7ecea580e5c886188.png)

Here’s the query to get the the teams, and then the collection of developers that participated in that team.

{% gist https://gist.github.com/alejandronanez/de2877144d8d0cf13a2707f6987540fe %}

Then, we import that GraphQL Query  and we call the GraphCMS endpoint using `graphql-request`. For what is worth, you can use anything you want to call a GraphQL endpoint (e.g., Axios, Apollo, Urql), but I recommend `graphql-request` as it gives you just what you need, nothing less, nothing more.

{% gist https://gist.github.com/alejandronanez/fb38180ea1ba870e2fa2f7d3b786ce59 %}

Up to this point, we have a function called `getTeams` that will get all the teams ordered by `startDate` and its respective developers ordered by `firstName`.

How you connect the data layer (`data` folder) with the view layer (any `.html` file) is to create a `[template-file].11tydata.js` file with the same name as the `.html` where we want to use the data. In our case, we have a `who-we-are.html` file, which means that we have to create a `who-we-are.11tydata.js` file to get dynamic data.

{% gist https://gist.github.com/alejandronanez/e8160c79b78a42726272900208e217b3 %}

From there we can use the `teams` object in `who-we-are.html`

{% gist https://gist.github.com/alejandronanez/fde5a5e22b783b0c031a94666c3049b1 %}

And that’s it — our Developers section is now fully powered by GraphCMS! 😎

### Bonus: Automate deployments

Since we use Netlify to host our site, we use [Zapier](https://zapier.com) to schedule deployments everyday at a certain time. Our workflow to update our site now is this:

1. Make a change in GraphCMS
2. Trigger an automatic deployment at 12am PST

Unless we need to deploy any new feature or fix a bug, we no longer need to trigger a manual build! 🎉

For those times when we do need a manual build, we have installed [the official Netlify/GraphCMS integration](https://graphcms.com/blog/graphcms-netlify-integration). This gives us the ability to kick off a build and deploy of the site at the click of a button from within the content editing interface.

## Conclusion

**GraphCMS** is a great tool, easy and fun to use that has helped us greatly since now we’re able to iterate faster.

**11ty** is a fun tool to use, too! I like its simplicity and the fact that it goes back to the basics, HTML, CSS and JS. No need for anything fancy or with a steeper learning curve such as React or VUE.

## Useful Links

- [GraphCMS](https://graphcms.com/)
- [The Collab Lab repository](https://github.com/the-collab-lab/website)
- [The Collab Lab Website](https://the-collab-lab.codes/)
- [Eleventy (11ty)](https://www.11ty.dev/)