Contentful logo

Contentful Community

Embed Youtube or Vimeo video directly into Rich Text Content Type

Is it possible to embed a Youtube or Vimeo video directly into the Rich Text Content Type? If not, what is the best practice for allowing a user of Contentful to add videos to blog posts for example.

Thanks!

1 Like

Hi @james.barber,

You could, for example, create a content type called Video that has a field URL where the uses inserts the URL of a Youtube or Video video. After that you need to write a rich text renderer in your front-end application that prints out the necessary embed HTML code for respective video platform.

I.e. you would be embedding the Video content type to another content type that has a Rich Text field.

Thanks for that! Your example inspired the solution I came to. Instead of creating a seperate Content Type the user just needs to add a hyperlink of the video’s embed url.

Now in my blog post template file I check my hyperlinks and if one includes youtube.com/embed (or player.vimeo.com/video from Vimeo embeds - I imagine these checks could possible be better) return an iframe with the embed URL.

import { INLINES } from '@contentful/rich-text-types'
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'

export const query = graphql`
  query {
    contentfulResource {
      resourceContent {
        json
      }
   }
}`

const Post = (props) => {
  const options = {
    renderNode: {
      [INLINES.HYPERLINK]: (node) => {
        if((node.data.uri).includes("player.vimeo.com/video")){
          return <IframeContainer><iframe title="Unique Title 001" src={node.data.uri} frameBorder="0" allowFullScreen></iframe></IframeContainer>
        } else if((node.data.uri).includes("youtube.com/embed")) {
          return <IframeContainer><iframe title="Unique Title 002" src={node.data.uri} allow="accelerometer; encrypted-media; gyroscope; picture-in-picture" frameBorder="0" allowFullScreen></iframe></IframeContainer>
        }
      }
    }
  }

 return(
  <div>
     {documentToReactComponents(props.data.contentfulResource.resourceContent.json, options)}
  </div>
 )
}

export default Post

The <IframeContainer> is a component created to ensure the iframes retain their aspect ratio and are responsive. Bonus code below.

const IframeContainer = styled.span`
  padding-bottom: 56.25%; 
  position: relative; 
  display: block; 
  width: 100%;

  > iframe {
    height: 100%;
    width: 100%;
    position: absolute; 
    top: 0; 
    left: 0;
  }`

I’m using styled-components but you can re create this by replacing <IframeContainer> with <span class="ClassNameToReplaceIframeContainer"> (the reason it’s a span is to adhere to best practice as these iframes will be rendered within p tags)

If something here doesn’t make sense let me know :slightly_smiling_face:

Cheers!

@james.barber Glad to hear I was able to help! :slight_smile:

Yeah, your implementation is certainly better and simpler if you only need to embed the video and no additional data is needed.