So I've written a blog site in Gatsby and Remark. I've structured my posts like this:
Library/
-- category-name/
---- article-name/
------ index.md
This has worked really well and results in me being able to make paths like /category-name/article-name
.
What I also would like to do is to be able to drop an image in there called 'hero.jpg' and for it to be automatically picked up by Gatsby without having to add a frontmatter reference to it.
I've managed to get so far by adding the following to 'gatsby-node.js':
const hero = (fs.existsSync(path.resolve(__dirname, `src/library/pages/${slug}hero.jpg`))) ? `${slug}hero.jpg` : ''
createNodeField({
node,
name: 'hero',
value: hero,
})
This works as far as the graphql data goes and I now see the following:
{
"node": {
"id": "3190922a-2207-5621-a7be-e02be9e8da24",
"fields": {
"hero": "/category-name/article-name/hero.jpg"
},
},
However on the actual page, the image link /category-name/article-name/hero.jpg
doesn't exist so I get a dead image. I know this is because my image path is being transformed by gatsby-transformer-sharp
but I don't know how to work out what it is being transformed to.
I believe I need to do something akin to the answers on this SO question but that seems to expect you to know that the relativePath
is at the time you are writing your query but I won't have that information until after the query has returned the first time.
OnCreateNode hook added for claarity
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
// Add slug to MarkdownRemark node
if (node.internal.type === 'MarkdownRemark') {
const slug = createFilePath({ node, getNode, basePath: 'library' })
const hero = (fs.existsSync(path.resolve(__dirname, `src/library/pages/${slug}hero.jpg`))) ? './hero.jpg' : ''
createNodeField({
node,
name: 'slug',
value: slug,
})
createNodeField({
node,
name: 'hero',
value: hero,
})
}
}
I realized my previous answer was incorrect & overly complicated (It relies on node creation order, also there's no need to add fields to imageSharp nodes. Here's the link if someone's interested.). Here's the better answer:
Querying image of
hero
name in the same folder with mardownSince the hero image is always at the same directory as the markdown file, we can simply query it based on its directory.
Graphql query:
The only modification you need to make to your
gatsby-node.js
is to add thisdir
field to your page'scontext
so we can use it as a variable. We can get thisdir
by doingpath.parse(node.fileAbsolutePath).dir
, or get thedir
field from remark's parent nodegetNode(node.parent.id).dir
And query it like so:
And use it:
Here's the gist for
article.js
andgatsby-node.js
.