Add external javascript to support custom webcomponents

I want to add custom webcomponents to add fancy web-app like things to my markdown notes.

To do this, the Markdown preview should support displaying custom webcomponents, and I should be able to load an external javascript file which will register the web components.

Alternative use cases for adding external javascript (of CSS) is to add custom styling, interactivity, embeds, etc.

While this can be done with the regular Obsidian Plugin API, this is not portable to other environments, for example when you export your vault as a static html website. Using webcomponents would allow me to create a uniform experience between the obsidian preview and my static generated website.

1 Like

Did it!

Using the “Javascript Init” plugin, I added the following script:

DOMPurify.setConfig({
   ALLOW_UNKNOWN_PROTOCOLS: !0,
   RETURN_DOM_FRAGMENT: !0,
   FORBID_TAGS: ["style"],
   ADD_TAGS: ["iframe","tag-list"],
   ADD_ATTR: ["frameborder", "allowfullscreen", "allow", "aria-label-position", "tag"]
});
var s= document.createElement('script');
s.setAttribute('src','http://localhost:8080/zettelkasten-components.mjs');
s.setAttribute("type","module");
document.head.appendChild(s);

Note that I added “tag-list” as allowed tag and “tag” as an allowed attribute. Furthermore, I dynamically load as script which defines the custom components (e.g. “tag-list”).

2 Likes

What an inspired solution. In an effort to keep learning stuff, let me try to see if I understand what you did.
You have a local script/module (NodeJS?) hosted on localhost:8080.
Loading this in a markdown file does some form of manipulation/adds data to the file?
Maybe you could upload a screenshot of the result if possible/non-sensitive.
Following things like this helps broaden the scope of my understanding what is possible with Obsidian should the need arise for new solutions/innovations of my workflow.
CU!
Paul

Yes, you are correct.

Let me explain what is happening.

First, the reason why I ask this. These are my wishes:

  1. No vendor lock-in, just plain and simple markdown files.
  2. A great editing experience: Obsidian (or Visual Code Studio)
  3. Publish part of my notes as website.
  4. Enhance my personal knowledge management with my tools.

I ran into a problem: while Obsidian is a great editor, it is not open source. It uses a proprietary indexing, as well as plugins that can only be used with the indexing and rendering of Obsidian.

While dataview is a great plugin, suddenly my markdown files were not portable anymore. I could not render HTML files myself, like I used to do.

Enter the solution: Web Components. Markdown fully supports HTML elements! And it takes only one scripts (and possibly stylesheet) to add support for custom webcomponents to HTML. This is a very portable and elegant solution.

When I want to embed youtube-video’s or image gallaries, this is super easy. Things get a bit harder when I want to engage in my markdown notes: I have to to the indexing myself.

So, I have created a “markdown rendering pipeline” that does the following:

  • give it a directory of markdown files
  • index the files and extract information (YAML frontmatter, title, tags, etc)
  • render it however you like (*.html files, *.json, etc)
  • create a server to render on-demand.

So one way to use this, is to index the files, filter for my website (which is only my public notes), then render to HTML.

While I am taking notes, I spin up a local server, which watches the files and renders the HTML files on demand (giving me information that is always up-to-date, without rebuilding the entire website).

The localhost:8080/zettelkasten-component.mjs points to a javascript files that contains custom Web Components. (I have build library this using Vue & Vite). My local zettelkasten server, the one who watches my markdown files and serves them on demand, is able to also serve this file.

In addition, my local zettelkasten server also servers a “data.json” which contains an index of all my files (including title, tags and content).

My webcomponents download this index and use it for searching, listing tags, etc, etc.

You could try the script yourself if you load https://markmarijnissen.com/zettelkasten-components.mjs. However, this will also load the https://markmarijnissen.com/zettelkasten-data.json file, which is of course the index of my personal website, and not your vault.

For you to load your vault, you would to edit the javascript to load a different data.json, and you would need to generate that data.json.

I could open source the scripts, but this will take me some time (to write a readme, cleanup the code, etc).

You can read a bit more about my setup here: My Zettelkasten Setup - Mark Marijnissen

Haha, I’ve studied for months to understand what you did :sweat_smile:. (had to/was building a foundation of understanding about JavaScript, NodeJS, API’s et al. from scratch, not a programmer, just a geek)

A belated but big thank you for your elaboration. I’ll try to showcase a bit about some of the things I made in/for Obsidian. Mostly based on the same premises as you discuss: interoperability (no lock-in), autonomy etc.

Will take me some time to publish but hopefully we can stay in touch/follow up based on this exchange :grin: