# HTMLEditorProvider.openEditor() that just creates the FileEditor and doesn't open it?

**URL:** <https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249>\
**Category:** IntelliJ Platform\
**Created:** [October 14, 2026, 4:49pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249 "2026-10-14T16:49:32Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![illuminatedcloud](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/illuminatedcloud/32/55_2.png) [@illuminatedcloud](https://platform.jetbrains.com/u/illuminatedcloud)\
**Post date:** [October 14, 2026, 4:49pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/1 "2026-10-14T16:49:32Z")

</div>

I’m adding a new feature to my plugin that integrates an external HTML-based visualization in a `TextEditorWithPreview`-based file editor. The issue I’m running into is that I can’t find a sanctioned way to create the `HTMLFileEditor` for the resulting visualization to use as the preview editor.

The only path I’m finding to create one is via `HTMLEditorProvider.openEditor()`, but that both creates the editor and opens it, so I end up with an unnecessary tab containing what should only be used as the preview editor.

The following works perfectly, but it uses internal APIs:

```java
HTMLVirtualFile previewFile = HTMLVirtualFile.Companion.createFile(
    project,
    MetadataVisualizerUtil.getMetadataName(project, metadataFile),
    HTMLEditorProvider.Request.Companion.url(visualizationFile.getUrl()),
    WebPreviewFileType.INSTANCE,
    false
);
List<FileEditorProvider> previewEditorProviders = FileEditorProviderManager.getInstance().getProviderList(project, previewFile);
FileEditorProvider previewEditorProvider = ContainerUtil.getFirstItem(previewEditorProviders);
FileEditor previewEditor = previewEditorProvider != null ? previewEditorProvider.createEditor(project, previewFile) : null;

```

That yields the exact result that I want:

 ![image](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/2X/2/2611e08d594c91470d665ea58419094afd21dbf7.png)

Is there a public/sanctioned API that I can use to do this but have perhaps missed/overlooked? If not, could one be added, and in the interim, could I use `HTMLVirtualFile.createFile()` and `WebPreviewFileType.INSTANCE` so I can move forward with this feature integration?

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [October 14, 2026, 5:09pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/2 "2026-10-14T17:09:59Z")

</div>

`HTMLFileEditor` is not really big implementation, probably you can just copy what is necessary

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [October 14, 2026, 5:15pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/3 "2026-10-14T17:15:25Z")

</div>

Also `JcefHtmlEditorProvider` has `html-editor` value for `getEditorTypeId()` if you can find it in `com.intellij.openapi.fileEditor.FileEditorProvider#EP_FILE_EDITOR_PROVIDER` extensions.

So you can ask it for `createEditor(project, VirtualFile)`

---

<div class="post-metadata">

**Author:** ![illuminatedcloud](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/illuminatedcloud/32/55_2.png) [@illuminatedcloud](https://platform.jetbrains.com/u/illuminatedcloud)\
**Post date:** [October 14, 2026, 5:43pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/4 "2026-10-14T17:43:21Z")

</div>

Unfortunately clone-and-own doesn’t look like it’s going to work – or at least be slim – because, ultimately, it needs to create `HTMLFileEditorImpl` which is also internal. I could keep cloning the dependency graph, but I stopped when I reached that point because it felt like it was getting a bit too large.

I tried the option of finding the correct file editor provider by ID, and I can find it that way, but if I just pass in a `VirtualFile` with file type `HtmlFileType` and not an `HTMLVirtualFile`, it throws an exception:

```auto
java.lang.IllegalArgumentException: cannot create html editor for non-html file, actual file:///path/to/visualizationFile.html
	at com.intellij.openapi.fileEditor.impl.JcefHtmlEditorProvider.createEditor(JcefHtmlEditorProvider.kt:16)

```

due to:

```kotlin
  override fun createEditor(project: Project, file: VirtualFile): FileEditor {
    require(file is HTMLVirtualFile) {
      "cannot create html editor for non-html file, actual $file"
    }

```

It looks like I’m going to have to create an `HTMLVirtualFile` to get this to work properly.

Can I just log an enhancement request in YT for a new `HTMLEditorProvider.createEditor()` (basically the first part of `openEditor()` that just creates but then doesn’t open the HTML file editor), then go ahead and use the code included above until that new method is available?

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [October 14, 2026, 6:59pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/5 "2026-10-14T18:59:46Z")

</div>

Unfortunately. it only works with `HTMLVirtualFile` which is in-memory file. It is not ready to use physical files on disk. That is why integrating JCEF would be more correct for you, you can check how Markdown plugin does this.

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [October 14, 2026, 7:01pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/6 "2026-10-14T19:01:25Z")

</div>

A simple preview for HTML should be something like:

```kotlin
internal class HtmlPreviewFileEditor(private val previewFile: VirtualFile) : FileEditor, UserDataHolderBase() {
  private val myCefBrowser: JBCefBrowser = JBCefBrowser.createBuilder()
    .setUrl("about:blank")
    .setClient(JBCefApp.getInstance().createClient())
    .build()

  init {
    myCefBrowser.loadHTML(VfsUtil.loadText(file))
  }

  override fun dispose() {
    Disposer.dispose(myCefBrowser)
  }

  override fun getFile(): VirtualFile {
    return previewFile
  }

  override fun getComponent(): JComponent {
    return myCefBrowser.component
  }

  override fun getPreferredFocusedComponent(): JComponent? {
    return null
  }

  override fun getName(): String = "Show Preview"

  override fun setState(state: FileEditorState) {}
  override fun isModified(): Boolean { return false }
  override fun isValid(): Boolean { return true }
  override fun addPropertyChangeListener(listener: PropertyChangeListener) {}
  override fun removePropertyChangeListener(listener: PropertyChangeListener) {}
}

```

---

<div class="post-metadata">

**Author:** ![illuminatedcloud](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/illuminatedcloud/32/55_2.png) [@illuminatedcloud](https://platform.jetbrains.com/u/illuminatedcloud)\
**Post date:** [October 14, 2026, 7:08pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/7 "2026-10-14T19:08:59Z")

</div>

> [@yuriy.artamonov](#):
>
> Unfortunately. it only works with `HTMLVirtualFile` which is in-memory file. It is not ready to use physical files on disk. That is why integrating JCEF would be more correct for you, you can check how Markdown plugin does this.

It actually does work very well with on-disk files if you use `Request.url()` with `VirtualFile.getUrl()`: e.g.:

```auto
HTMLVirtualFile previewFile = HTMLVirtualFile.Companion.createFile(
    project,
    MetadataVisualizerUtil.getMetadataName(project, metadataFile),
    HTMLEditorProvider.Request.Companion.url(visualizationFile.getUrl()),
    WebPreviewFileType.INSTANCE,
    false
);

```

That works perfectly.

Is there any reason that `HTMLEditorProvider.createEditor()` shouldn’t exist? It seems like being able to create a `FileEditor` for a JCEF view of an HTML file that can be used in composite editors is quite useful, no?

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [October 14, 2026, 7:23pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/8 "2026-10-14T19:23:55Z")

</div>

> [@illuminatedcloud](#):
>
> `HTMLEditorProvider`

Yes, but it is not what you are looking for. It was implemented to show What’s New page in the past and still mostly used like this. With a rare exception to show preview ad-hoc by action.

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [October 14, 2026, 7:27pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/9 "2026-10-14T19:27:03Z")

</div>

My point is here is that you do not need a special API here, it is rather minimal code that does this and it is all about JCEF browser, no magic in `WebPreviewFileType` or `HTMLVirtualFile`

---

<div class="post-metadata">

**Author:** ![illuminatedcloud](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/illuminatedcloud/32/55_2.png) [@illuminatedcloud](https://platform.jetbrains.com/u/illuminatedcloud)\
**Post date:** [October 14, 2026, 8:08pm UTC](https://platform.jetbrains.com/t/htmleditorprovider-openeditor-that-just-creates-the-fileeditor-and-doesnt-open-it/5249/10 "2026-10-14T20:08:21Z")

</div>

Gotcha. And thanks for the taking the time to provide the concrete example. With just a very minor tweak, it works perfectly! Basically instead of:

```kotlin
  private val myCefBrowser: JBCefBrowser = JBCefBrowser.createBuilder()
    .setUrl("about:blank")
    .setClient(JBCefApp.getInstance().createClient())
    .build()

  init {
    myCefBrowser.loadHTML(VfsUtil.loadText(file))
  }

```

I used:

```kotlin
  private val myCefBrowser: JBCefBrowser = JBCefBrowser.createBuilder()
    .setUrl(previewFile.url)
    .setClient(JBCefApp.getInstance().createClient())
    .build()

```

and it properly binds the JCEF browser to the on-disk file.

Again, much appreciated!
