3

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

isherwood
  • 58,414
  • 16
  • 114
  • 157
mdash
  • 153
  • 2
  • 12

1 Answers1

1

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.

kennethormandy
  • 2,080
  • 14
  • 16
  • 1
    Thanks for your answer! I think that solving by css will be the final solution. By the way, I was wandering if I am missing something, perhaps a "more semantic" solution achievable directly from Contentful. There is a way of placing inline blocks inside rich text but than I have to create a content model named "Inline Image" with just an image inside... Sounds weird... – mdash May 18 '20 at 10:30
  • I'm having myself the same struggle. Sadly, that makes Contentful a not-so-ideal solution to deliver a project for clients with no coding experience... – Tedds May 07 '22 at 17:50