Gatsby and Graphql - How to filter allMarkdownRemark by folder
Asked Answered
S

2

15

I'm using Gatsby and MarkdownRemark.

I want to query the markdown files and then filter them down to the files contained within a sub-directory. My folder structure looks like this:

- src
 - pages
   -index.md
   -about.md
   - team
    - team_member_1.md
    - team_member_2.md
    - team_member_3.md

So far I can query all the markdown pages in the directory but I'm having trouble trying to filter down path. There must be a way to do it with a graphQL query.

Instead what I do is map all the results and then check if the slug string includes 'team' this tells me that its in the 'team' folder. And then it makes the component.

import React from 'react'
import { useStaticQuery, graphql } from 'gatsby'
import TeamMember from '../components/TeamMember.js'
const Team = () => {
  const data = useStaticQuery(graphql`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields{
              slug
            }
            frontmatter {
              name
              position
              image
            }
          }
        }
      }
    }
  `)

  return (
    <div>
      {data.allMarkdownRemark.edges.map( (item, index) => {
        if(item.node.fields.slug.includes('team')){
          return <TeamMember key={`team_member_${index}`}{...item.node.frontmatter}/>
        }
      } )}
    </div>
  )
}
export default Team

This works fine. But I thought the whole point of graphQl is to query and filter to return the exact data I need. Instead I'm back at writing my own filter code in javascript:

if(item.node.fields.slug.includes('team'))

Is there a Gatsby plugin or a way to filter a query to contain items in a folder?

Sheeb answered 19/9, 2019 at 18:1 Comment(0)
C
26

Have a look at the gatsby graphql reference for filter and make sure you are using graphiql to explore what is available within your schema.

query MyQuery {
  allMarkdownRemark(filter: {fileAbsolutePath: {regex: "/(team)/"  }}) {
    nodes {
      id
    }
  }
}
Copula answered 19/9, 2019 at 22:47 Comment(2)
Thank you ksav, This is exactly what I was looking for. I knew there had to be a way to do it. I'm going to read through that filter documentation that you linked. I was having trouble articulating my searches to find this. Thanks.Sheeb
For new people, and since no one here has mentioned it: filtering with regex and fileAbsolutePath is really, really slow. So if you can help it, filter with eq and frontmatter instead. My build times went from 11–12 minutes down to 3–4 minutes after changing. Read more about it here.Thermion
S
2

@ksav's answer works but it is important to note that regex: "/(team)/" also matches C:\user\gatsby\src\team2\other.md.

So I recommend using allMarkdownRemark(filter: {fileAbsolutePath: {regex: "/(/team/)/" }}) { instead.

Strasbourg answered 8/11, 2021 at 21:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.