diff --git a/airflow-core/src/airflow/ui/src/pages/ExternalView.tsx b/airflow-core/src/airflow/ui/src/pages/ExternalView.tsx
index a1c80cdf2f37c..c74d9b25a4be3 100644
--- a/airflow-core/src/airflow/ui/src/pages/ExternalView.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/ExternalView.tsx
@@ -18,7 +18,7 @@
*/
import { Box } from "@chakra-ui/react";
import { useTranslation } from "react-i18next";
-import { useParams } from "react-router-dom";
+import { useLocation, useParams } from "react-router-dom";
import { usePluginServiceGetPlugins } from "openapi/queries";
import { ProgressBar } from "src/components/ui";
@@ -32,6 +32,8 @@ export const ExternalView = () => {
const { page } = useParams();
const { data: pluginData, isLoading } = usePluginServiceGetPlugins();
+ const { pathname } = useLocation();
+
const externalView =
page === "legacy-fab-views"
? {
@@ -82,7 +84,7 @@ export const ExternalView = () => {
m={-2} // Compensate for parent padding
minHeight={0}
>
-
+
);
}
diff --git a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
index 9f43f72d90d8d..c530409a0e512 100644
--- a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
@@ -59,19 +59,29 @@ const loadPlugin = (reactApp: ReactAppResponse): Promise<{ default: PluginCompon
// eslint-disable-next-line no-console
console.error("Component failed to load:", error);
- return {
- default: ErrorPage,
- };
+ return { default: ErrorPage };
});
export const ReactPlugin = ({ reactApp }: { readonly reactApp: ReactAppResponse }) => {
const { dagId, mapIndex, runId, taskId } = useParams();
- const Plugin = lazy(() => loadPlugin(reactApp));
+ // If the plugin component was already registered on the global object by a previous load,
+ // render it directly without going through Suspense/lazy (avoids flashing the spinner).
+ const existing = (globalThis as Record)[reactApp.name];
+
+ if (typeof existing === "function") {
+ const Plugin = existing as PluginComponentType;
+
+ return ;
+ }
+
+ // Otherwise, lazy-load the bundle once. When it resolves, it must set a function component
+ // under globalThis[reactApp.name], which we then use as the default export.
+ const LazyPlugin = lazy(() => loadPlugin(reactApp));
return (
}>
-
+
);
};