Iframe no longer loading local html files

Iframe used to be able to display locally hosted html files (e.g. plotly graphs) but with a recent update all these frames are now blank.

For example this previously worked to display an interactive plotly graph (c.7mb) saved in html.
iframe
id=“inlineFrameExample”
title=“Inline Frame Example”
width=“700”
height=“550”
src=“file:///Users/Study/Desktop/Obsidian/Python/HTML/field/map_graph_field.html”>

</iframe

Now it appears as a blank 700x550 area.

Please follow and include the bug report template when submitting bug reports. Thanks.

Do you remember the version of Obsidian you were using before you updated?

It could be this:

  • Removed support for app://local URLs. These were reported as a potential vulnerability when using iframes.

https://obsidian.md/changelog/2023-05-03-desktop-v1.2.8/

Hello, I am encountering a similar situation. Here is my setup so far:

On Obsidian 1.5.8, I have a plugin that alters the iframe src so that it’s convenient to modify the (relative) path and so that it works on my phone as well:

import { MarkdownPostProcessorContext, Plugin, TFile } from "obsidian";

console.log("Running obsidian-local-html-plugin");

export default class LocalHTMLSrcPlugin extends Plugin {
	async onload() {
		this.registerMarkdownPostProcessor(
			(el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
				// get active file
				const activeFile: TFile | null =
					this.app.workspace.getActiveFile();
				if (activeFile === null) {
					return;
				}

				// get active file directory
				const activeFilePath: string =
					this.app.vault.getResourcePath(activeFile);
				const activeFileDir: string = activeFilePath.substring(
					0,
					activeFilePath.lastIndexOf("/")
				);

				// remove system-specific prefix for assets
				const prefixes = [
					"app://obsidian.md/",
					"capacitor://localhost/",
				];

				// search active file for any iframes
				const iframes: HTMLIFrameElement[] = Array.from(
					el.querySelectorAll("iframe")
				).filter((el: HTMLIFrameElement) =>
					prefixes
						.map((prefix: string) => el.src.startsWith(prefix))
						.some((el: boolean) => el)
				);
				for (const iframe of iframes) {
					let iframeSrcIsRelative = false;

					let relPath: string = iframe.src;
					for (const prefix of prefixes) {
						if (relPath.startsWith(prefix)) {
							relPath = relPath.replace(prefix, "");
							iframeSrcIsRelative = true;
							break;
						}
					}

					if (iframeSrcIsRelative) {
						iframe.src = `${activeFileDir}/${relPath}`;
						// console.log(iframe.src);
						// app://some-sort-of-id/C:/path/to/test.html
					}
				}
			}
		);
	}
}

that’s transpiled to js and copied to the plugins folder locally.

I also have a test.md file with the following:

<iframe src="./test.html" height=500 width=500></iframe>

as well as a test.html file:

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<title>Test</title>
	</head>
	<body>
		<p>test</p>
	</body>
</html>

in the same folder as test.md.

When the plugin runs, the iframe’s src is like app://some-sort-of-id/C:/path/to/test.html; this had worked in the past (I do not know the Obsidian version specifically, but it must have been more than a year ago). When I went back to open the markdown file with the iframe, it no longer shows the iframe, and instead showed a blank space. I’m not sure what could have changed since then; localhost isn’t being used (at least, I don’t think so…).