One of the main features that we have in OpenSauced is the highlights, which enables the users to share their latest contributions that they made in open source on our website.
This allows them to have impact-focused stories around their work, more visibility, and an opportunity to inspire and connect with other contributors. While having the highlights on our website was great, we wanted to enable the users to share them on social media, which let us work on implementing the open graph for our website.
In the open graph repo, we used Vercel/Satori library to provide the needed social card images. This implementation got us into an issue with emojis, which were shown as black lines instead of rendered correctly, as shown in the image below.
Those blocks meant that we needed to change our implementation to fix the issue. When we started to investigate the issue, we thought that it was related to our code and that we just needed to implement some library to render the emojis, but we were wrong with that assumption.
Understanding the Issue
To figure out what we need to do, we investigated the issue by:
- Checking what we had,
- Creating a hypothesis,
- Checking if anyone else reported the same issue before or reported on a solution,
- Testing the hypothesis and working on a solution.
Whenever a hypothesis was not working, we moved on and worked on another solution.
Testing Our Hypothesis
We assumed at the beginning that we needed to implement an emoji rendering frame to our implementation, which did not work. Because that didn’t work, we checked Vercel/Satori documentation since we rely on them. Once there, we noticed they had that document on the readme, which we did not see!
The only issue is that they mention how to find an emoji on a page, but they do not mention how to render that emoji. Because there wasn’t an explanation, we checked to see if they had an example.
We went to their repository and checked their examples to see if we could figure out if they had implemented the same logic before or not. We found that they have an open-source example using emojis, and we implemented this example in our project.
When we checked the example, we noticed that it's not only open source, but the Vercel team has modified Twitter's open-source code to implement their solution, which is a great example showing how open source can help companies to be more innovative.
To add emoji support, we converted the string to code point, a number representation of the string in the character systems. Then, we used a third library, Tweemoji, to request and return the SVG code of that emoji.
Before adding the utility functions we used to get the SVG image of the emojis, we only called the Satori function.
const svg = await satori(template, {
width: 1200,
height: 627,
fonts: [
{
name: "Inter",
data: interArrayBuffer,
weight: 400,
style: "normal",
},
{
name: "Inter",
data: interArrayBufferMedium,
weight: 500,
style: "normal",
},
],
tailwindConfig,
);
With emoji implementation, we added the load assets function, a built-in function for satori, to the call and updated it with util functions.
loadAdditionalAsset: async (code: string, segment: string) => {
if (code === "emoji") {
// if segment is an emoji
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
return `data:image/svg+xml;base64,${btoa(await loadEmoji("twemoji", getIconCode(segment)))}`;
}
// if segment is normal text
return code;
},
}
If you are curious about the full code. Feel free to check this PR with the full code.
A few months later, Biodrop, another open-source project, followed the same implementation that we used in our project to enable the embedding of their cards on other websites.
A social card with emojis after the implementation of this feature.
Do you know any other open-source projects that enabled people to be more innovative and faster?
Top comments (3)
Nice one @a0m0rajab!
Thanks Nick 🤗
hi!
I am trying to use satori directly within the next 14 API route, but the emoji is not output properly. Do you happen to know the cause?