Ethan Ong

Obsidian Auto Embed build process

Obsidian Auto Embed build process thumbnail

Date: 24 March 2024 - Ongoing

Introduction

This post is just my process on building the plugin. After writing this post, I realized it’s very long and plan to shorten it in the future.

Other links:

Why I wanted to build the plugin

I was exploring for new note taking apps and found Obsidian.

Not related but a list of reasons on why I like Obsidian:
  • Gives the user full control of my notes
    • Allows me to view my notes offline
    • Even if Obsidian suddenly disappears, I’ll still have my notes
  • Gives access to users to make plugins and themes
    • Since I know some web development, this really makes me use my skills and customize a lot of things. (Which lead to this plugin)
  • Other great things like Tags, Properties and many other features.

While exploring the app, found that they support embedding websites but it’s only limited to YouTube and Twitter. The only way to embed unsupported websites is to use <iframe>. My main use case was trying to embed CodePen links. I felt that it was troublesome to constantly use iframe to embed, and it was messy when seeing the raw markdown.

My process building the plugin

Checking if there is an existing plugin

Tried to search the web and didn’t find anything that does it.

Similar projects:
  • Simple Embed - Might have worked but repo is archived, isn’t in Obsidian’s plugin directory, and couldn’t get it to work even after downloading it.
  • Obsidian Link Embed - Partly worked. It converts the link into title, thumbnail and description. Similar to Twitter/Discord. It also takes quite a while since it’s using a third-party API to get the info. Might be more useful than my plugin if you want to view it offline but I want to embed the website’s content. So this doesn’t work for me.

Starting to build the project

Since this my first plugin I made, and I just started Obsidian, I had a lot to learn. Spend quite a long time just reading the documentation.

Then I created the GitHub repo on 5th March 2024.

Surprisingly got the MVP working pretty fast, mostly thanks to Obsidian’s simple API on the docs and my previous experience in web development.

Replacing the url to embed

Learnt that many of the popular websites like YouTube, Twitter, CodePen, has unique urls to indicate that it should be embedded. This removes other elements like header, footer and any other element that isn’t the main content. I also learnt basic Regex to identify which websites to embed and how to get the related info (like post id) from the url to transform the url to the embedded version.

Problems with resizing

Many websites either:

  • Change their own content layout based on the space their are given like YouTube and Spotify.
  • Provide scripts to help to resize and do other processing. Example: Twitter
  • Put the size in the html the user copies. Example: Reddit

Since none of these can be done in Obsidian for websites that need to be resized dynamically (Twitter and Reddit for example), I had to find another way. Tried searching and all solutions had the same problem: websites not allowing to get the size due to CORS. Some solutions required an external server to prerender the content and get the content, but I can’t do it Obsidian. Or I can make my own server and make an API call to it, but it was a lot of work.

Eventually I was trying to various methods and one of them required sending messages and listening to them. To my surprise, I saw Twitter sending it’s own message to resize, with the width, height and tweet id. I quickly used that info and it worked!

Later found out that it doesn’t work for Reddit when there are multiple posts since there isn’t any id sent in the resize message. To partly “fix” it:

  • Embeds are loaded lazily
  • Only set the size if it doesn’t have a size.

This doesn’t really solve it when the embeds are close together but at least it solves when the embed don’t appear together in the same viewport.

Implementing Live Preview

All the work done above only works on Reading Mode and not Live Preview - Documentation. Basically, Reading Mode shows the fully rendered HTML and the user can’t edit while Live Preview shows the HTML but the user can edit.

Obsidian uses a different system, Editor Extensions, for Live Preview. It uses CodeMirror as a base. This results in the information I’m required to understand to greatly increase as I needed to learn CodeMirror too. Personally, I Obsidian’s documentation on Editor Extensions is very little and the community devs using Editor Extensions is small. But I would eventually implement it through a lot of searching and asking the Discord.

Submitting to Obsidian plugin directory

Not much to say but I got accepted! Here’s the link: https://obsidian.md/plugins?id=auto-embed