Skip to content

Commit

Permalink
feat: render embeds in preview on the client (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
scissorsneedfoodtoo authored May 28, 2024
1 parent 4885308 commit 6561f38
Showing 1 changed file with 99 additions and 0 deletions.
99 changes: 99 additions & 0 deletions src/templates/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -2397,6 +2397,16 @@
direction: ltr;
unicode-bidi: isolate;
}
.post-full-content .embed-wrapper {
margin-top: 1.25em;
margin-bottom: 1.25em;
}
.embed-wrapper {
display: flex;
justify-content: center;
width: 100%;
overflow-x: hidden;
}
</style>
{# END: /assets/css/screen.css #}
{# START: /assets/css/search-bar.css #}
Expand Down Expand Up @@ -2718,6 +2728,95 @@
here because we can't generate that data before building the page #}
{# END: block seo #}

{# Include Twitter script in case there are any embeded Tweets #}
<script defer src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
{# Use Hashnode's Webembeds API to render embeds on the client #}
<script>
document.addEventListener('DOMContentLoaded', async () => {
/* eslint-disable no-undef */
try {
const hashnodeEmbedAnchorEls = [...document.querySelectorAll('div.embed-wrapper a.embed-card')];
await hashnodeEmbedAnchorEls.map(async anchorEl => {
const embedURL = anchorEl.href;
const res = await fetch(`https://webembeds.com/api/embed?url=${embedURL}`);
const json = await res.json();
const embedHTML = new DOMParser().parseFromString(json?.data?.output?.html, "text/html").body;
// // This method allows script execution
// const embedHTML = document.createRange().createContextualFragment(json?.data?.output?.html);
const iframe = embedHTML.querySelector('iframe');
const script = embedHTML.querySelector('script');
const webembedWrapper = embedHTML.querySelector('div.webembed-wrapper');
// It's not possible to dynamically embed a Gist script without a
// lengthy workaround, so return early and show what Hashnode gives
// us by default
if (/https:\/\/gist\.github\.com\//.test(embedURL)) return;
if (iframe) {
if (/https:\/\/open\.spotify\.com\//.test(iframe.src)) {
const embedPath = new URL(iframe.src).pathname;
const [_, type] = embedPath.split('/').filter(Boolean);
iframe.setAttribute('height', type === 'playlist' ? 352 : 152);
iframe.setAttribute('style', type === 'playlist' ? 'aspect-ratio: 16 / 9; width: 100%; height: auto;' : '');
} else if (/https:\/\/anchor\.fm\//.test(iframe.src)) {
// Assume the podcast is an episode and use the same height as the Spotify embed
// for a single episode
iframe.setAttribute('width', '100%');
iframe.setAttribute('height', 152);
iframe.removeAttribute('style');
} else if (/https:\/\/giphy\.com\/embed\//.test(iframe.src)) {
const giphyWrapper = document.createElement('div');
giphyWrapper.setAttribute('style', 'width: 100%; height: 0; padding-bottom: 125%; position: relative;');
giphyWrapper.setAttribute('class', 'giphy-wrapper');
iframe.setAttribute('width', '100%');
iframe.setAttribute('height', '100%');
iframe.setAttribute('style', 'position: absolute');
iframe.parentElement.replaceChildren(giphyWrapper);
giphyWrapper.replaceChildren(iframe);
} else {
iframe.setAttribute('style', 'aspect-ratio: 16 / 9; width: 100%; height: auto;');
}
}
// Some embeds come with a webembed wrapper, so strip those out if they exist
anchorEl.parentElement.replaceChildren(
...(webembedWrapper ?
webembedWrapper.childNodes :
embedHTML.childNodes)
)
});
// Now that iframe embeds have possibly been added to the page,
// wrap them if necessary for spacing, then enable lazy loading
const iframes = document.getElementsByTagName('iframe');
[...iframes].forEach(iframe => {
// For iframes on Hashnode that were copy and pasted into an HTML block,
// wrap them in a div similar to how Hashnode does for links in embed blocks
if (
!['embed-wrapper', 'giphy-wrapper'].some(className =>
iframe?.parentElement?.classList.contains(className)
)
) {
const embedWrapper = document.createElement('div');
embedWrapper.classList.add('embed-wrapper');
iframe.parentElement.replaceChild(embedWrapper, iframe);
embedWrapper.appendChild(iframe);
}
iframe.setAttribute('loading', 'lazy');
});
} catch (err) {
console.log(err);
}
});
</script>
<meta name="generator" content="Eleventy"/>
</head>
<body class="home-template">
Expand Down

0 comments on commit 6561f38

Please sign in to comment.