1

I have a bunch of markdown files like below where I reference a path to an image in the project at src/images:

---
title: "Test"
picture: "images/image.png"
subtitle: "Hello friends"
---
this is a testing markdown file

and a gatsby-config entry which the image paths are based upon:

{
    resolve: `gatsby-source-filesystem`,
    options: {
        name: `images`,
        path: `${__dirname}/src/images`,
    },
},

I then query for these markdown files which are all in the same directory:

const query = useStaticQuery(graphql`
        query MyQuery {
            allMarkdownRemark(filter: {fileAbsolutePath: {regex: "/markdown-content/"}}, sort: {order: DESC, fields: [frontmatter___date]}) {
            edges {
                node {
                    frontmatter {
                        title
                        picture
                        subtitle
                    }
                    excerpt
                }
            }
            }
        }
    `);

and generate a TestComponent like below for each markdown file by mapping over the nodes and passing the data as a prop


const TestComponent = ({ data: { frontmatter: { title, picture, subtitle }, excerpt } }) => (
    <Container>
        <img src={picture} />
        <h1>{title}</h1>
        <h2>{maintext}</h2>
        <p>{excerpt}</p>
    </Container>
);

The issue is that Gatsby doesn't pick up the images in the build or develop passes so the images are broken. The only solution in the docs for this use case seems to be the static directory, but I'd like to keep the images in src/images. Is this possible?

Bradley
  • 1,234
  • 1
  • 12
  • 24

1 Answers1

0

First: Lets be clear on why you need to put files in the static directory vs the src directory. Only files in the static directory get copied to the public directory for the static website. Therefore you can't reference the file that is in your src directory since that file will not be available in the final static build of your site. Static Folder Gatsby

Second: Its recommended that you import all assets with javascript. Described here

Recommendation: So to achieve your dynamic image load by specifying the picture in the frontmatter, I would suggest using a key vs. an image path. This way you can use that key then to load the image you need and import all your images using javascript.

What I would also recommend is using Gatsby's image optimization. gatsby-image This would allow you to leverage optimizations and import your assets using javascript.

So here is how I would implement your strategy.

  1. Create a component for each image using gatsby-image plugin for optimization.
import React from 'react'
import { useStaticQuery, graphql } from 'gatsby'
import Img from 'gatsby-image'
/*
 * This component is built using `gatsby-image` to automatically serve optimized
 * images with lazy loading and reduced file sizes. The image is loaded using a
 * `useStaticQuery`, which allows us to load the image from directly within this
 * component, rather than having to pass the image data down from pages.
 *
 * For more information, see the docs:
 * - `gatsby-image`: https://gatsby.dev/gatsby-image
 * - `useStaticQuery`: https://www.gatsbyjs.org/docs/use-static-query/
 */

export default ({ alt, ...rest }) => {
  const data = useStaticQuery(graphql`
  query {
      imageSharp(fixed: {originalName: {eq: "image-name.png"}}) {
        fluid {
          ...GatsbyImageSharpFluid
        }
      }
    }
  `)

  return (
    <>
      {data.imageSharp &&
        <Img fluid={data.imageSharp.fluid} alt={alt || 'Default alt text'} {...rest} />
      }
    </>
  )
}
  1. Use the name of the component as the key in your frontmatter and create the image component dynamically from that frontmatter property.
import * as Images from '../images'

const TestComponent = ({ data: { frontmatter: { title, picture, subtitle }, excerpt } }) => {
  const ImageComponent = Images[key]
  return(
    <Container>
        <ImageComponent />
        <h1>{title}</h1>
        <h2>{maintext}</h2>
        <p>{excerpt}</p>
    </Container>
  );
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Master12
  • 46
  • 4