This site runs best with JavaScript enabled.

Creating a Pinned Articles Component in Gatsby

First Published: May 28th, 2020


I wanted an easy way to pin articles to the front page of my website. It turns out Gatsby and GraphiQL make this process much easier than you'd think!

First, I added a new pinned field to the frontmatter of the articles I wanted to put on the front page and set it equal to true. Frontmatter fields are great for splicing, dicing, and sorting your content however you'd like.

I then fired up Gatsby's built-in GraphiQL tool and built the following query:

1query {
2 allMdx(
3 sort: { fields: [frontmatter___date], order: DESC }
4 limit: 10
5 filter: {
6 frontmatter: { published: { ne: false }, pinned: { eq: true } }
7 fileAbsolutePath: { regex: "//content/writing//" }
8 }
9 ) {
10 edges {
11 node {
12 id
13 fields {
14 title
15 slug
16 }
17 }
18 }
19 }
20}

This query finds the 10 most recent pinned articles and sorts them by date descending.

What's cool about using a filter of pinned: { eq: true } is that I don't have to go back and add this field to every single article. If I were to change the filter to ne: false like the filter for published, it would include articles that didn't include that field at all. This is because the filter will treat that null reference as a "truthy" value. I'm using the exact same principle in reverse with the published field: I can explicitly set it to false on articles I don't want published, but I don't have to remember to go back and flip that value to true to get them to show up.

I then created a PinnedArticles component and used my query with the useStaticQuery hook that Gatsby provides. Here's the finished component:

1// src/components/PinnedArticles.js
2const PinnedArticles = () => {
3 const data = useStaticQuery(graphql`
4 query {
5 allMdx(
6 sort: { fields: [frontmatter___date], order: DESC }
7 limit: 10
8 filter: {
9 frontmatter: { published: { ne: false }, pinned: { eq: true } }
10 fileAbsolutePath: { regex: "//content/writing//" }
11 }
12 ) {
13 edges {
14 node {
15 id
16 fields {
17 title
18 slug
19 }
20 }
21 }
22 }
23 }
24 `)
25
26 return (
27 <ul>
28 {data.allMdx.edges.map(edge => (
29 <li key={edge.node.id}>
30 <Link to={`/${edge.node.fields.slug}`}>{edge.node.fields.title}</Link>
31 </li>
32 ))}
33 </ul>
34 )
35}
36
37export default PinnedArticles

All that was left was to replace my hardcoded list of articles in index.mdx with my new <PinnedArticles /> component:

1<!-- pages/index.mdx -->
2
3## Some Favorites
4
5These are what I'd considered my "foundational articles." They reflect some of the major lessons I've learned so far on my journey. If you're just getting to know me, start with these:
6
7<PinnedArticles />

And that's it! Now any time I want to pin a new article to the front page, I just set that frontmatter field and I'm on my way.

If you like these Gatsby tips, hop on to my newsletter below. If you're new to Gatsby and want to get started from scratch, check out my Thinkster course Up and Running with Gatsby.


← Back to writing
Share article

I send emails about getting better at coding and life.

I'm on a path to become a better human and developer and I want to bring as many friends with me as possible. Want to join me? Sign up below. 👇



Sam Julien © 2020