Introduction#
gatsby-starter-blog comes with out of the box support for a single author blog. But what happens when you want to support multiple authors writing in your blog?
Gatsby actually makes it very easy to do so but for people getting started with Gatsby it might be a bit of challenge putting all the parts together.
This post hopes to show how to solve this problem holistically.
This blog is actually a real life implementation of the multi author blog. Check our source!
Setting multiple author support#
The highest level interface that authors writing posts will use will still be the frontmatter yaml on top of each postās markdown file.
By specifying an author id, we are going to be able to retrieve the rest of the author data we have stored in our codebase.
---
title: My Post!
author: author1
---
For this to work we need to setup Gatsby to:
- use the filesystem as a valid source of data. In this case we used
src/data
but it can be anything you like. - use a yaml transformer because we will store our authors data inside a yaml but you could use JSON or any other format.
- map frontmatterās
author
attribute tosrc/data/author.yaml
.
module.exports = {
plugins: [
...otherPlugins,
// 1. use src/data as a data source
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/src/data`,
name: `data`,
},
},
// 2. enable yaml support
`gatsby-transformer-yaml`,
],
mapping: {
// 3. map author to author.yaml
"MarkdownRemark.frontmatter.author": `AuthorYaml`,
},
};
You will probably need to install the necessary dependencies: yarn add gatsby-source-filesystem gatsby-transformer-yaml
.
Important: frontmatterās author
will need to match an id
attribute in your author.yaml
, since that is
what the mapping uses as a sort of primary key.
Now lets show how the author.yaml
looks.
- id: author1
bio: I am Author 1
profilepicture: ../../content/assets/author1.png
- id: author2
bio: I am Author 2
profilepicture: ../../content/assets/author2.png
At this point Gatsby will automatically provide the entire Author data via the GraphQL interface, in your post template.
Notice that it will return the data for the author you specified in the postās frontmatter, and of course, each post can have a different author.
Letās check how the post template can use the author
data now:
export const pageQuery = graphql`
query BlogPostBySlug($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
excerpt(pruneLength: 160)
html
frontmatter {
title
author {
id
bio
profilepicture {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
`;
Inside your post component you will be able to access all author data:
export default function BlogPostTemplate(props) {
const {
id,
bio,
profilepicture,
} = props.data.markdownRemark.frontmatter.author;
//...
}
Bonus: Author profile picture#
If you look at the previous snippets you will notice we used the profilepicture
to
support authorās profile pictures. Notice how in the GraphQL query that we showed before we used the
childImageSharp
query to enable image optimization, something that the Gatbsy Starter blog
does by default in the mono-author mode.
By using this childImageSharp
and any of the other queries of gatsby-image you can
transform dynamically loaded images via the expected GraphQL interface with ease.
How to use all authors#
Weāve only covered the automagical way of mapping a frontmatter
attribute to a filesystem database i.e. author.yaml
.
But what happens when you want all the authors, lets say for a list of authors in your page or a shared about page?
Gatsby also has you covered with this by using the plugins we setup before.
Gatsby will automatically provide a way of reading the entire author.yaml
as follows:
export const pageQuery = graphql`
allAuthorYaml {
nodes {
id
bio
}
}
}
`;
Notice how author.yaml
is mapped to allAuthorYaml
, that name transformation
is significant and you should be carefully with it.
If unsure you can always go to the GraphQL explored that Gatsby provides by default and play around with the available queries.
At this point your page component will be provided with an array of authors:
export default function About(props) {
// this is an array of authors
const authors = props.allAuthorYaml.nodes;
//...
}
Bonus: Run-Time multi author support through GraphQL#
Notice that this setup also enables you do an ad-hoc manual implementation
of the multi-author support.
I will probably not recommend it for this use case but it is a possibility if you
encounter a use case that might benefit from it. Notice that by using this you donāt need
to statically know the author id like we did in the blog-post.js
before, you can
do it entirely dynamically by simply passing react props.
export default function Author(props) {
const authorId = props.author;
const authors = props.allAuthorYaml.nodes;
// manually search for the selected author
const myAuthor = authors.find((a) => a.id === authorId);
return <p>Author Bio: {myAuthor.bio}</p>;
}
export const query = graphql`
allAuthorYaml {
nodes {
id
bio
}
}
}
`;
And you can use it like:
<Author author="author1" />
This can be extrapolated to a lot of other use cases.
Bonus: Run-Time multi author support through importing files#
And if everything else fails you can always simply import the yaml (or any other format) directly from your components and display the data however you like.
The main drawback is that you donāt have some useful image transformations and some other GraphQL-only APIs but there might be very good use cases for this approach aside from supporting multiple authors:
import authors from "../data/author.yaml";
export default function Author(props) {
const authorId = props.author;
// manually search for the selected author
const myAuthor = authors.find((a) => a.id === authorId);
return <p>Author Bio: {myAuthor.bio}</p>;
}
Closing#
I hope that I have eased the entry barrier for a multi author blog with Gatbsy, and taught some extra techniques in the way.
Want to become a Javascript expert? This is nice place to start: