<div id="root"></div>
body {
  height: 100vh;
  margin: 0;
  display: grid;
  place-items: center;
}

.link {
  color: #666;

  .wrapper {
    display: flex;
    flex-direction: row;
    max-height: 160px;
    width: 40vw;
    min-width: 500px;
    max-width: 760px;
    border: 1px solid #CCC;
    border-radius: 5px;
    box-shadow: 2px 2px 2px #CCC;
    overflow: hidden;

    .text {
      display: flex;
      flex-direction: column;
      padding: 20px;
      flex: 7;
      gap: 10px;

      .title {
        font-size: 20px;
        margin: 0;
      }

      .description {
        overflow: hidden;
        width: 100%;
        flex: 1;
        text-overflow: ellipsis; 
      }

      .favicon_wrapper {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 10px;
        color: #AAA;

        .favicon {
          width: 16px;
          height: 16px;
        }
      }  
    }

    .thumbnail {
      flex: 5;

      .img {
        height: 100%;
        object-fit: cover;
      }
    } 
  }
}
View Compiled
import confetti from "https://cdn.skypack.dev/canvas-confetti";
//import ogs from "https://cdn.skypack.dev/open-graph-scraper";

const App = () => {
  // TODO: Retrieve this information from an open graph request.
  // There are npm packages to do this like `open-graph` or `open-graph-scraper`.
  // We can also implement a custom DOMParser a set of xpaths to retrieve this information. We need to take in account that Obsidian has to disable CORS for this kind of requests.
  // You can play with open graph here: https://www.opengraph.xyz
  
  const title = "Three.js Journey"
  const description = "Subscribing to Three.js Journey will give you a lifetime access to a complete and easy to access course of 32 lessons. Want to see what's included?"
  const favicon = "https://threejs-journey.xyz/assets/favicons/favicon-16x16.png"
  const url = "https://threejs-journey.xyz"
  const thumbnail = "https://threejs-journey.xyz/assets/social/open-graph-image-1200x630.png"
  
  return(   
    <a className="link" href={url} target="_blank" rel="noreferrer noopener nofollow">
      <div className="wrapper">
        <div className="text">
          <h1 className="title">{title}</h1>
          <p className="description">{description}</p>
          <div className="favicon_wrapper">
            {Boolean(favicon) && (
              <img className="favicon" src={favicon} alt={title} />
            )} 
            {url}
          </div>
        </div>
        {Boolean(thumbnail) && (
        <div className="thumbnail">
          <img className="img" src={thumbnail} alt={title} />
        </div>
        )}
      </div>
    </a>
  );
}

ReactDOM.render(<App />, document.getElementById("root"))
View Compiled
Run Pen

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css

External JavaScript

  1. https://unpkg.com/react@16.7.0-alpha.0/umd/react.production.min.js
  2. https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.production.min.js