diff --git a/platform/new-ui-onboarding/BUILD.bazel b/platform/new-ui-onboarding/BUILD.bazel
index 05559302a13c..a773bcee40ea 100644
--- a/platform/new-ui-onboarding/BUILD.bazel
+++ b/platform/new-ui-onboarding/BUILD.bazel
@@ -34,7 +34,6 @@ jvm_library(
"//libraries/kotlinx/serialization/json",
"//platform/projectModel-api:projectModel",
"//platform/statistics",
- "//libraries/jcef",
"//platform/util:util-ui",
],
)
@@ -64,7 +63,6 @@ jvm_library(
"//libraries/kotlinx/serialization/json:json_test_lib",
"//platform/projectModel-api:projectModel_test_lib",
"//platform/statistics:statistics_test_lib",
- "//libraries/jcef:jcef_test_lib",
"//platform/util:util-ui_test_lib",
],
)
diff --git a/platform/new-ui-onboarding/intellij.platform.ide.newUiOnboarding.iml b/platform/new-ui-onboarding/intellij.platform.ide.newUiOnboarding.iml
index 9458f23af8a1..960b8066127d 100644
--- a/platform/new-ui-onboarding/intellij.platform.ide.newUiOnboarding.iml
+++ b/platform/new-ui-onboarding/intellij.platform.ide.newUiOnboarding.iml
@@ -43,7 +43,6 @@
-
\ No newline at end of file
diff --git a/platform/new-ui-onboarding/jcef/BUILD.bazel b/platform/new-ui-onboarding/jcef/BUILD.bazel
new file mode 100644
index 000000000000..5b3e99e28019
--- /dev/null
+++ b/platform/new-ui-onboarding/jcef/BUILD.bazel
@@ -0,0 +1,62 @@
+load("@rules_jvm//:jvm.bzl", "jvm_library")
+
+### auto-generated section `build intellij.platform.ide.newUiOnboarding.jcef` start
+
+jvm_library(
+ name = "jcef",
+ srcs = glob(
+ [
+ "src/**/*.kt",
+ "src/**/*.java",
+ "src/**/*.form",
+ ],
+ allow_empty = True,
+ ),
+ module_name = "intellij.platform.ide.newUiOnboarding.jcef",
+ resource_strip_prefix = "resources",
+ resources = glob(
+ ["resources/**/*"],
+ ),
+ visibility = ["//visibility:public"],
+ deps = [
+ # do not sort,
+ "@lib//:jetbrains-annotations",
+ "//platform/core-api:core",
+ "//platform/core-impl",
+ "//platform/platform-api:ide",
+ "//platform/new-ui-onboarding",
+ "//platform/ui.jcef",
+ "//platform/util:util-ui",
+ ],
+)
+
+jvm_library(
+ name = "jcef_test_lib",
+ testonly = True,
+ srcs = glob(
+ [],
+ allow_empty = True,
+ ),
+ module_name = "intellij.platform.ide.newUiOnboarding.jcef",
+ visibility = ["//visibility:public"],
+ runtime_deps = [
+ # do not sort,
+ ":jcef",
+ "//platform/core-api:core_test_lib",
+ "//platform/core-impl:core-impl_test_lib",
+ "//platform/platform-api:ide_test_lib",
+ "//platform/new-ui-onboarding:new-ui-onboarding_test_lib",
+ "//platform/ui.jcef:ui.jcef_test_lib",
+ "//platform/util:util-ui_test_lib",
+ ],
+)
+### auto-generated section `build intellij.platform.ide.newUiOnboarding.jcef` end
+
+### auto-generated section `iml intellij.platform.ide.newUiOnboarding.jcef` start
+exports_files(
+ [
+ "intellij.platform.ide.newUiOnboarding.jcef.iml",
+ ],
+ visibility = ["//visibility:public"],
+)
+### auto-generated section `iml intellij.platform.ide.newUiOnboarding.jcef` end
diff --git a/platform/new-ui-onboarding/jcef/intellij.platform.ide.newUiOnboarding.jcef.iml b/platform/new-ui-onboarding/jcef/intellij.platform.ide.newUiOnboarding.jcef.iml
new file mode 100644
index 000000000000..78486d9dd6aa
--- /dev/null
+++ b/platform/new-ui-onboarding/jcef/intellij.platform.ide.newUiOnboarding.jcef.iml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/new-ui-onboarding/jcef/module-content.yaml b/platform/new-ui-onboarding/jcef/module-content.yaml
new file mode 100644
index 000000000000..547cda59fa2a
--- /dev/null
+++ b/platform/new-ui-onboarding/jcef/module-content.yaml
@@ -0,0 +1,3 @@
+- name: dist.all/lib/intellij.platform.ide.newUiOnboarding.jcef.jar
+ modules:
+ - name: intellij.platform.ide.newUiOnboarding.jcef
diff --git a/platform/new-ui-onboarding/jcef/resources/intellij.platform.ide.newUiOnboarding.jcef.xml b/platform/new-ui-onboarding/jcef/resources/intellij.platform.ide.newUiOnboarding.jcef.xml
new file mode 100644
index 000000000000..cf600798dda9
--- /dev/null
+++ b/platform/new-ui-onboarding/jcef/resources/intellij.platform.ide.newUiOnboarding.jcef.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/new-ui-onboarding/jcef/src/com/intellij/platform/ide/newUiOnboarding/jcef/JcefNewUiOnboardingBrowserPageRenderer.kt b/platform/new-ui-onboarding/jcef/src/com/intellij/platform/ide/newUiOnboarding/jcef/JcefNewUiOnboardingBrowserPageRenderer.kt
new file mode 100644
index 000000000000..ab9a44ad0f93
--- /dev/null
+++ b/platform/new-ui-onboarding/jcef/src/com/intellij/platform/ide/newUiOnboarding/jcef/JcefNewUiOnboardingBrowserPageRenderer.kt
@@ -0,0 +1,35 @@
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.platform.ide.newUiOnboarding.jcef
+
+import com.intellij.platform.ide.newUiOnboarding.NewUiOnboardingBrowserPageRenderer
+import com.intellij.ui.components.panels.Wrapper
+import com.intellij.ui.jcef.JBCefApp
+import com.intellij.ui.jcef.JBCefBrowser
+import com.intellij.util.ui.UIUtil
+import org.jetbrains.annotations.ApiStatus
+import java.awt.Dimension
+import java.awt.Graphics
+import javax.swing.JComponent
+
+@ApiStatus.Internal
+class JcefNewUiOnboardingBrowserPageRenderer : NewUiOnboardingBrowserPageRenderer {
+ override fun createBrowserPageComponent(htmlText: String, size: Dimension): JComponent? {
+ if (!JBCefApp.isSupported()) {
+ return null
+ }
+
+ val browser = JBCefBrowser.createBuilder().setMouseWheelEventEnable(false).build()
+ browser.loadHTML(htmlText)
+ return object : Wrapper(browser.component) {
+ override fun paint(g: Graphics?) {
+ super.paint(g)
+ super.paintBorder(g)
+ }
+ }.also {
+ UIUtil.setNotOpaqueRecursively(it)
+ val adjustedSize = Dimension(size.width + 2, size.height + 2)
+ it.minimumSize = adjustedSize
+ it.preferredSize = adjustedSize
+ }
+ }
+}
diff --git a/platform/new-ui-onboarding/resources/intellij.platform.ide.newUiOnboarding.xml b/platform/new-ui-onboarding/resources/intellij.platform.ide.newUiOnboarding.xml
index a047e546d2a0..5d4dd530d4da 100644
--- a/platform/new-ui-onboarding/resources/intellij.platform.ide.newUiOnboarding.xml
+++ b/platform/new-ui-onboarding/resources/intellij.platform.ide.newUiOnboarding.xml
@@ -26,6 +26,9 @@
beanClass="com.intellij.platform.ide.newUiOnboarding.newUi.NewUiOnboardingBean"
dynamic="true">
+
diff --git a/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/NewUiOnboardingBrowserPageRenderer.kt b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/NewUiOnboardingBrowserPageRenderer.kt
new file mode 100644
index 000000000000..c91e84198a1a
--- /dev/null
+++ b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/NewUiOnboardingBrowserPageRenderer.kt
@@ -0,0 +1,19 @@
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.platform.ide.newUiOnboarding
+
+import com.intellij.openapi.extensions.ExtensionPointName
+import org.jetbrains.annotations.ApiStatus
+import java.awt.Dimension
+import javax.swing.JComponent
+
+@ApiStatus.Internal
+interface NewUiOnboardingBrowserPageRenderer {
+ fun createBrowserPageComponent(htmlText: String, size: Dimension): JComponent?
+
+ companion object {
+ private val EP_NAME = ExtensionPointName("com.intellij.ide.newUiOnboarding.browserPageRenderer")
+
+ fun createComponent(htmlText: String, size: Dimension): JComponent? =
+ EP_NAME.extensionList.firstNotNullOfOrNull { it.createBrowserPageComponent(htmlText, size) }
+ }
+}
diff --git a/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/NewUiOnboardingUtil.kt b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/NewUiOnboardingUtil.kt
index bd3f1e8780e2..d29fc6e9195b 100644
--- a/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/NewUiOnboardingUtil.kt
+++ b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/NewUiOnboardingUtil.kt
@@ -59,6 +59,7 @@ import java.awt.Component
import java.awt.Dimension
import java.awt.Point
import java.awt.Rectangle
+import javax.swing.JComponent
import javax.swing.Icon
import javax.swing.SwingUtilities
@@ -242,6 +243,9 @@ object NewUiOnboardingUtil {
return htmlPage to size
}
+ fun createBrowserPageComponent(htmlText: String, size: Dimension): JComponent? =
+ NewUiOnboardingBrowserPageRenderer.createComponent(htmlText, size)
+
suspend fun createSettingsEntryPointPopup(project: Project, disposable: CheckedDisposable): JBPopup? {
val settingsButton = UiComponentsSearchUtil.findUiComponent(project) { button: ActionButton ->
button.action is SettingsEntryPointAction
diff --git a/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/RunWidgetStep.kt b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/RunWidgetStep.kt
index cd7955d69eb1..c9e1b30915eb 100644
--- a/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/RunWidgetStep.kt
+++ b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/RunWidgetStep.kt
@@ -57,7 +57,9 @@ open class RunWidgetStep : NewUiOnboardingStep {
NewUiOnboardingUtil.createLottieAnimationPage(animationPath, animationClassLoader)
}
lottiePageData?.let { (html, size) ->
- builder.withBrowserPage(html, size, withBorder = true)
+ NewUiOnboardingUtil.createBrowserPageComponent(html, size)?.let {
+ builder.withCustomComponentPromo(it, withBorder = true)
+ }
}
val point = NewUiOnboardingUtil.convertPointToFrame(project, runPopup.content, JBPoint(-4, 27)) ?: return null
diff --git a/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/ToolWindowLayoutsStep.kt b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/ToolWindowLayoutsStep.kt
index b5571f4a93a6..7195473235e5 100644
--- a/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/ToolWindowLayoutsStep.kt
+++ b/platform/new-ui-onboarding/src/com/intellij/platform/ide/newUiOnboarding/steps/ToolWindowLayoutsStep.kt
@@ -35,7 +35,9 @@ open class ToolWindowLayoutsStep : NewUiOnboardingStep {
NewUiOnboardingUtil.createLottieAnimationPage(LOTTIE_JSON_PATH, ToolWindowLayoutsStep::class.java.classLoader)
}
lottiePageData?.let { (html, size) ->
- builder.withBrowserPage(html, size, withBorder = true)
+ NewUiOnboardingUtil.createBrowserPageComponent(html, size)?.let {
+ builder.withCustomComponentPromo(it, withBorder = true)
+ }
}
return NewUiOnboardingStepData(builder, RelativePoint(ideFrame.rootPane, Point(0, 0)), position = null) // show in the center
}
diff --git a/platform/new-users-onboarding/src/com/intellij/platform/ide/newUsersOnboarding/SearchEverywhereStep.kt b/platform/new-users-onboarding/src/com/intellij/platform/ide/newUsersOnboarding/SearchEverywhereStep.kt
index c6058a1898a5..bc78258d84ef 100644
--- a/platform/new-users-onboarding/src/com/intellij/platform/ide/newUsersOnboarding/SearchEverywhereStep.kt
+++ b/platform/new-users-onboarding/src/com/intellij/platform/ide/newUsersOnboarding/SearchEverywhereStep.kt
@@ -35,7 +35,9 @@ internal class SearchEverywhereStep : NewUiOnboardingStep {
NewUiOnboardingUtil.createLottieAnimationPage(LOTTIE_JSON_PATH, SearchEverywhereStep::class.java.classLoader)
}
lottiePageData?.let { (html, size) ->
- builder.withBrowserPage(html, size, withBorder = true)
+ NewUiOnboardingUtil.createBrowserPageComponent(html, size)?.let {
+ builder.withCustomComponentPromo(it, withBorder = true)
+ }
}
val point = Point(searchEverywhereButton.width / 2, searchEverywhereButton.height + JBUI.scale(3))