Editor widget/decoration for custom file wikilink embed?

I’m writing a plugin to add support for a new filetype in Obsidian, one which I’d like to be able to embed in markdown files. A user should be able to create a wikilink to this new file (e.g. “![[folder/myfile.custom]]”), and have it render using the custom CM6 decorator I’m writing.

I’m having more trouble finding a way to do this than I expected. I was hoping for some Obsidian API that would let me define a custom renderer for certain filetypes or link formats, but it seems like almost all the plugins that embed content into your document use codeblocks, and I definitely don’t want to do that. I know I can write CM6 decorators for Obsidian, but I’m worried that writing a decorator for a span of text that Obsidian already registers a decorator for could lead to unexpected behavior.

Does Obsidian supply an API for registering custom embed decorators for links/wikilinks? Or do I have to try something more invasive?

Yes, Obsidian has an API for custom embed point decoration, but this API is not public API:

class CustomEmbed extends Component{
    containerEl: HTMLElement;
    app: App;
    file: TFile;
    constructor(config: Config, file: TFile, subpath: string) {
        super()
        this.containerEl = config.containerEl;
        this.app = config.app;
        this.file = file;
    }

    async loadFile() {
        const content = await this.app.vault.read(this.file);
        this.containerEl.innerHTML = `
            <div style="border: 2px solid cyan; padding: 30px;">
                <h1> This is a CUSTOM embed view </h1>
                <p> Content is: </p>
                <pre>
                    ${content}
                </pre>
            </div>
            `
    }
}

export default class CustomPlugin extends Plugin {
    async onload() {
        // @ts-ignore
        this.app.embedRegistry.registerExtension("custom", (...args) => new CustomEmbed(...args));
    }

    async onunload() {
        // @ts-ignore
        this.app.embedRegistry.unregisterExtension("custom");
    }
}

The effect is like:

Content of file.custom:

With great power comes great responsibility.

In Editor:

Hello,

What is the best strategy for ensuring a custom CodeMirror 6 ViewPlugin decoration successfully overrides Obsidian’s default embed rendering for ![[file.custom]] links?

I believe the approach mentioned above is the simplest and most stable solution, as it fully leverages Obsidian’s existing code and only requires writing the rendering logic yourself.

Otherwise, you’ll need to write a plugin that matches all ![[xxxx]], ![[xxx#yyyy]], ![[xxx#yyy|zzz]]], as well as regular ![xxx](yyy), and manually handle the parsing of file links.
Then you can use Prec.high to give this plugin a higher priority, thereby overriding the original decorator.

@the_tree this worked very well, thanks for the help!