How to add support for multiple authors per page on GatsbyJS

While working on a Gatsby site, we have a requirement to provide support for multiple authors/contributors per page. We got this working by following the excellent Gatsby documentation [Mapping node types](https://www.gatsbyjs.org/docs/gatsby-config/#mapping-node-types). In this post, I will be describing the steps we followed. ### Adding gatsby-transformer-yaml dependency using npm Run this on your Gatsby project within the root directory. ```bash npm install --save gatsby-transformer-yaml ``` ### Configuring the plugins For this example, we are going to have a `contributor.yaml` file located at src/data. ```yaml - id: jane_doe name: Jane Doe twitter: jane_doe github: //github.com/jane_doe drupal: //www.drupal.org/u/jane_doe wordpress: //profiles.wordpress.org/jane_doe linkedin: //www.linkedin.com/in/jane_doe bio: CEO - id: john_doe name: John Doe twitter: john_doe linkedin: //www.linkedin.com/in/john_doe github: //github.com/john_doe bio: Technical Manager, Training and Certification ``` To make sure Gatsby can read this file, we need to have the `gatsby-source-filesystem` installed and configured to point to a path where our YAML files are. ```javascript plugins: [ { resolve: `gatsby-source-filesystem`, options: { path: `${__dirname}/src/data`, name: `data`, }, }, `gatsby-transformer-yaml`, ] ``` Adding a map between the author field in frontmatter to the id in the `contributor.yaml` objects by adding to your gatsby-config.js: ```javascript mapping: { "Mdx.frontmatter.author": "ContributorYaml", }, ``` ### Fetching the data After implementing this, we can fetch get all the linked authors per page using this GraphQL query. ```json export const pageQuery = graphql` query DocBySlug($slug: String!) { mdx(fields: { slug: { eq: $slug } }) { id code { body } fields { slug } frontmatter { title description getfeedbackform contributors { id name twitter bio avatar url } featuredcontributor } fileAbsolutePath } } ` ``` As you can see on this query, the property contributors within frontmatter contain each one the properties of the contributor relation even when is saved as an array of string values on the markdown file. ```yaml contributors: ['contributor-id'] ``` ### Showing the contributor data We created the `Contributors` component to render the data on the page template. ```javascript ``` this is the content of that component. ```javascript import React from 'react'; import { Link } from 'gatsby'; const Contributors = ({ contributors }) => { if (contributors == null || contributors.length < 1) { return null; } return (

Contributors:{' '} {contributors.map((contributor, i, arr) => { let lastCharacter = '.'; if (arr.length - 1 !== i) { lastCharacter = ', '; } return ( {contributor.name} {lastCharacter} ); })}

); }; export default Contributors; ``` ### Display all the posts by a contributor Create a page template at `src/templates/contributor.js` and add the following GraphQL query to pull all of the posts by contributor/author. Theme as desired. ```javascript export const pageQuery = graphql` query ContributorById($id: String!) { contributorYaml(id: { eq: $id }) { id name avatar url github drupal wordpress twitter linkedin } allDocs: allMdx( filter: { frontmatter: { contributors: { elemMatch: { id: { eq: $id } } } } } ) { edges { node { id frontmatter { title } fields { slug } } } } } ``` In those queries, we are filtering the data using the `id` context variable. Filtering the `contributorYaml` query by the contributor equal to the id ```javascript  contributorYaml(id: { eq: $id })  ``` Filtering `allDocs` when the `contributors` frontmatter field matches and contains `id` in one of then values. ```javascript allDocs: allMdx( filter: { frontmatter: { contributors: { elemMatch: { id: { eq: $id } } } } } ) ``` Add a GraphQL query on `create-node.js` to pull all of the contributors ```javascript  allContributorYaml {     edges {          node {              id          }      } } ``` Create the contributor pages and passing the contributor `id` as a context variable. ```javascript const contributors = result.data.allContributorYaml.edges contributors.forEach(contributor => {      createPage({          path: `contributors/${contributor.node.id}`,         component: path.resolve(`./src/templates/contributor.js`),          context: {              id: contributor.node.id,          },      }) }) ``` ### Are you interested in knowing more about GatsbyJS? This series does not end here, so we invite you to visit our site frequently as we continue. We will be sharing some nice tips & tricks that we have learned during the development of this project. We will be sharing with you: - How to load templates based on your front-matter field. - How to create page navigation based on directory structure. How to use the parent directory as the base. Finally, how to show all of the children files as clickable links to separate pages. So stay tuned and keep on learning with us. If you want to learn more about what we do and how we may help your business, don't think about it twice and reach out to us!

 

Related
articles

How to create a text/markdown node to process content using Gatsby

read moreright arrow

How to embed React components in markdown using Gatsby, MDX, and short-codes

read moreright arrow