mdash
mdash

Reputation: 153

How can I use inline images with rich text in Gatsby?

I'm trying to recreate a text with small inline images inside.

Something like this: enter image description here

I've set a content model in Contentful with a Rich Text but the only way I can insert the images is as a block.

enter image description here

Than in Gatsby I query the data:

const data = useStaticQuery(graphql`
  query { 
    contentfulHomepage {
      breaks {
        id
        shout {
          json
        }
      }
    }
  }
`)

Here is the way I'm fetching the rich text with gatsby:

const options = {
  renderNode: {
    'embedded-asset-block': node => {
      const alt = node.data.target.fields.title['en-US']
      const url = node.data.target.fields.file['en-US'].url
      return <img src={url} alt={alt} />
    },
  },
}

const breaks = data.contentfulHomepage.breaks.map(element => (
  <Break
    key={element.id}
    shout={documentToReactComponents(element.shout.json, options)}
  />
))

I get the data correctly but the way the node is rendered is with several paragraph and images in between. Something like this:

<p>If you are </p>
<img alt...>
<p>already intrigued</p>
<img alt...>
...

Is there a way to get images as inline spans (or other) inside a paragraph block? Something like: <p>Some text<span><img></img></span> and other <span><img></img></span> text </p>

thanks

Upvotes: 3

Views: 1219

Answers (1)

kennethormandy
kennethormandy

Reputation: 2150

It sounds like you already have the React and Gatsby portions of this figured out, and unless you’re set on modifying the markup, you can solve this with CSS.

Would something like this work? https://codesandbox.io/s/throbbing-leftpad-rlsh3?file=/src/styles.css

.Shout p {
  display: inline;
}

.Shout img {
  display: inline;

  /* Setting the max height of the image
     in ems, so it will scale with the font
     size set in the `.Shout` CSS class.
       You’ll probably want to adjust this
     to roughtly match the x-height or cap height
     of the font you are using. */
  max-height: 0.85em;

  /* If there aren’t spaces in the phrases,
     you might add margins around the images.
     Asjust as you see fit. */
  margin-left: 0.25em;
  margin-right: 0.25em;
}

…where Shout is a CSS class on the React component containing the node (or as in the CodeSandbox example).

const Shout = props => {
  return (
    <div className="Shout">
      <p>If you are</p>
      <img src="https://source.unsplash.com/random/400x300" />
      <p>already intrigued</p>
      <img src="https://source.unsplash.com/random/500x200" />
      <p>and also think about</p>
      <img src="https://source.unsplash.com/random/250x250" />
      <p>while remembering to</p>
      <img src="https://source.unsplash.com/random/400x300" />
    </div>
  );
};

Screenshot showing phrases and images styled using example code

You may need to build on it from here if you have more strict requirements about how the images wrap with the text, but hopefully this helps to get started.

Upvotes: 1

Related Questions