Robert O'Toole
Robert O'Toole

Reputation: 427

dynamically rendering svgs in gatsby

hey guys i have sime markdown (mdx) files that i want to use an svg with. i know that rendering dynamic ANYTHING in gatsby can be tricky.. with gatsby image you often have to filter out the right results. but for svgs specifically i m wondering how i render them dynamically depending on frontmatter in my markdown. i tried doing an <img src={svgpath} /> to no avail. and right now my svgs are beng imported as components using this in my config:


    "gatsby-transformer-sharp",
    {
      resolve: "gatsby-plugin-react-svg",
      options: {
        rule: {
          include: /assets/ 
        }
      }
    },

i dont know of a way to dynamically import files nor dynamically render the appropriate svg that matches the name in the markdown. here is as an example of the frontmatter in my markdown:

---
title: Pediatric Dentistry
slug: pediatric-dentistry
svgPath: '../images/assets/dental.svg'
---

how can i do something that dynamically shows the correct svg in my template file for each specific markdown file? i can dynamically render png, jpg, etc but becuase of svgs specific need to be imported as a component using transofmrer-sharp in gatsby im struggling. thanks in advance!

Upvotes: 0

Views: 566

Answers (2)

Robert O&#39;Toole
Robert O&#39;Toole

Reputation: 427

The best way I found was to use the "gatsby-plugin-svgr"...

this allows for complete control over the svg fill, width, and height so long as you remove those attributes from the original svg files. After that you would simply have to conditionally render a certain icon depending on a set of options or possibilities.

the svgs get imported like this:

import { ReactComponent as Email } from '../../images/svgs/mail.svg';

then they can be rendered like this as a component:

 <Email  />

and are then targeted with conventional css using the tag

Upvotes: 0

Ferran Buireu
Ferran Buireu

Reputation: 29335

One thing that comes to my mind is to create a kind of map, a key-value pair that imports your desired component. Something like:

import Dental from '../images/assets/dental.svg';
import OtherSvg from '../images/assets/otherSvg.svg';
import OtherLogo from '../images/assets/otherLogo.svg';

const SVGMapper = {
  'dental': Dental,
  'otherSvg': OtherSvg,
  'otherLogo': OtherLogo,
};

export default SVGMapper;

And so on...

Then, to render it from your markdown, you just need to:

  let SVGComponent = SVGMapper['dental'];

  return <SVGComponent />;

You can make it dynamic using a loop or whatever you want.

You can even change the key (dental, otherSvg and otherLogo) for the path if needed. The approach is exactly the same, you will need to change the key for your SVG path and render SVGMapper[svgPath]

Upvotes: 1

Related Questions