Embedded Browser (JCEF)
Embedding of the browser component inside the IDE can be used for:
rendering HTML content
previewing generated HTML (e.g., from Markdown)
creating custom web-based components (e.g., diagrams preview, image browser, etc.)
It is recommended to implement UI in the default IntelliJ Platform UI framework, which is Swing. Consider using JCEF approach only in cases, when a plugin needs to display HTML documents or the standard approach for creating UI is insufficient.
JCEF replaces JavaFX, which was used to render web content in IDEs in the past.
JCEF is available and enabled by default since 2020.2. No additional actions are required.
Using JCEF requires using a dedicated JetBrains Runtime and enabling JCEF in the IDE Registry.
Go to the JetBrains Runtime releases list.
Download "Binaries for launching IntelliJ IDEA" matching your operating system, e.g., jbr_jcef-17.0.9-osx-x64-b1087.7.tar.gz for macOS.
Unpack the archive.
Follow the steps described in the IDEA Web Help and choose the downloaded JBR.
Invoke Registry dialog., type "Registry", and press enter to open the
Restart the IDE for changes to take effect.
Using JCEF In a Plugin
The core JCEF class exposed by IntelliJ Platform API is
JBCefApp. It is responsible for initializing JCEF context and managing its lifecycle.
Before using JCEF API, it is required to check whether JCEF is supported in the running IDE. It is done by calling
JCEF can be unsupported when:
The IDE is started with an alternative JDK that does not include JCEF.
Its version is not compatible with the running IDE.
JCEF browser is represented by
JBCefBrowser class. It is responsible for loading and rendering requested documents in the actual Chromium-based browser.
JCEF browsers can be created either by using the
JBCefBrowser class' constructors, or via
JBCefBrowserBuilder. Use constructors in the cases when a browser with the default client and default options is enough. The builder approach allows using custom clients and configuring other options.
Adding Browser to UI
JBCefBrowser.getComponent() exposes the UI component embedding the actual browser. The component is an instance of Swing
JComponent, which can be added to the plugin UI:
To load a document in the browser, use one of
JBCefBrowserBase.load*() methods. Methods loading documents can be called from both UI and non-UI threads. It is possible to set an initial URL (passed to constructor or builder) that will be loaded when browser is created and initialized.
Browser client provides an interface for setting up handlers related to various browser events, e.g.:
HTML document loaded
console message printed
browser gained focus
Handlers allow reacting to these events in plugin code and change browser's behavior. Each browser is tied to a single client and a single client can be shared with multiple browser instances.
Browser client is represented by
JBCefClient, which is a wrapper for JCEF's
JBCefClient allows registering multiple handlers of the same type, which is not possible with
CefClient. To access the underlying
CefClient and its API, call
Creating and Accessing Client
JBCefBrowser instance is created without passing a specific client, it is tied to a default client created implicitly. Implicit clients are disposed automatically, following the associated browser instance disposal.
For more advanced use cases, create a custom client by calling
JBCefApp.createClient() and register required handlers. Custom clients must be disposed explicitly in the plugin code.
To access the client associated with a browser, call
JCEF API provides various event handler interfaces that allows handling a wide set of events emitted by the browser. Example handlers:
CefDisplayHandler- handles events related to browser display state.
CefDisplayHandler.onAddressChange()to load project files in the browser when a local file link is clicked, or opening an external browser if an external link is clicked.
CefContextMenuHandler- handles context menu events.
CefContextMenuHandler.onBeforeContextMenu()to change the items of the browser context menu.
CefDownloadHandler- file download events.
CefDownloadHandler.onBeforeDownload()to enable downloading files in the embedded browser.
See org.cef.handler package for all available handlers.
Handlers should be registered with
The above snippet will be executed in the embedded browser and will display alert box with the "Hello World!" message. The
lineNumber parameters are used in the error report in the browser, if the script throws an error. Their purpose is to help debugging in case of errors, and they are not crucial for the script execution. It is common to pass
browser.getCefBrowser().getUrl() or null/empty string, and
0 as these parameters.
JBCefJSQuery. It is an object bound to a specific browser, and it holds a set of handlers that implement the required plugin behavior.
Consider a case, which requires opening local files links in the editor and external links in an external browser. Such a requirement could be implemented as follows (each step is explained under the code snippet):
JBCefQueryinstance. Make sure that the passed browser instance is of type
JBCefBrowserBase(casting may be needed).
Add a handler implementing a plugin code to be executed. Example implementation opens a link in the editor or an external browser depending on whether the link is local or external.
Handlers can optionally return
JBCefJSQuery.Responseobject, which holds information about success or error occurred on the plugin code side. It can be handled in the browser if needed.
openLinkQuerywill be invoked on each
"link"parameter of the
JBCefJSQuery.inject()method. It is the name of the
linkparameter. This value is injected to the query function call, and can be any value that is required by handler, e.g.,
aelement is clicked in the browser, the listener will invoke the
openLinkfunction defined in step 4 with the
hrefvalue of the clicked link.
Loading Resources From Plugin Distribution
Serving such resources is implemented by the Image Viewer component responsible for displaying SVG files in IntelliJ Platform-based IDEs. See
JCefImageViewer and related classes for the implementation details.
Scrollbars Look and Feel
Default browser scrollbars may be insufficient, e.g. when they stand out of the IDE scrollbars look, or specific look and behavior is required.
JBCefScrollbarsHelper that allows to customize scrollbars in two ways:
JBCefScrollbarsHelper.getOverlayScrollbarStyle(), which provides the styles adapted to the IDE scrollbars.
Using OverlayScrollbars library adapted to the IDE look and feel. For the details, see
buildScrollbarsStyle()Javadocs. It should be used when transparent scrollbars or other advanced options are required.
JBCefJSQuery classes implement
JBCefDisposable, which extends
Disposable. It means that these classes should clean up their resources according to the rules described on the Disposer and Disposable page.
For example, a custom
JBCefClient with registered handlers should remove them in the
dispose() method implementation.
JBCefTestHelper and tests in that package.
The Chrome DevTools, embedded into JCEF, can be used as a debugging and profiling tool. It is active by default, so that a Chrome DevTools client can attach to it via the default 9222 port. Default port can be changed via the registry key
ide.browser.jcef.debug.port (go to and type "Registry").
Also, JCEF provides a default Chrome DevTools frontend (similar to the one in the Chrome browser) that can be opened from the JCEF's browser component context menu via internal mode only, and since version 2021.3, the registry key
ide.browser.jcef.contextMenu.devTools.enabled must be set to
Accessing DevTools Programmatically
To access the Chrome DevTools in the plugin code, use the following API:
In order to open DevTools in a separate window, call