From f229c492e01ac1c7bce1216089f1ef248fad5066 Mon Sep 17 00:00:00 2001
From: github-automation-metabase
 <166700802+github-automation-metabase@users.noreply.github.com>
Date: Wed, 18 Dec 2024 06:48:16 -0500
Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20backported=20"fix(sdk):=20migrat?=
 =?UTF-8?q?e=20to=20custom=20redux=20context=20to=20allow=20using=20the=20?=
 =?UTF-8?q?sdk=20on=20host=20apps=20that=20use=20redux"=20(#51414)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* step1: add MetabaseReduxProvider and make our hooks + connect fn use it

step1: add MetabaseReduxProvider and make our hooks + connect fn use it

* step 2: codemod

* step 3: manual fixes

* step 4: e2e test for sdk

---------

Co-authored-by: Nicolò Pretto <info@npretto.com>
---
 .../redux-provider-clash.cy.spec.tsx          | 99 +++++++++++++++++++
 .../private/SdkGlobalFontsStyles.tsx          |  2 +-
 .../ConnectedDashboard.tsx                    |  3 +-
 .../components/public/MetabaseProvider.tsx    |  6 +-
 .../hooks/private/use-sdk-usage-problem.ts    |  7 +-
 .../hooks/public/use-current-user.ts          |  3 +-
 .../frontend/src/embedding-sdk/store/index.ts | 22 ++---
 .../embedding-sdk/store/use-sdk-selector.ts   | 16 +--
 .../ImpersonationModal/ImpersonationModal.tsx | 12 +--
 .../ApplicationPermissionsPage.tsx            |  2 +-
 .../audit_app/containers/AuditTable.jsx       |  2 +-
 .../UnsubscribeUserModal.jsx                  |  2 +-
 .../SettingsJWTForm/SettingsJWTForm.tsx       |  2 +-
 .../SettingsSAMLForm/SettingsSAMLForm.jsx     |  2 +-
 .../containers/JwtAuthCard/JwtAuthCard.tsx    |  2 +-
 .../containers/SamlAuthCard/SamlAuthCard.tsx  |  2 +-
 .../LicenseAndBillingSettings.tsx             |  2 +-
 .../QuestionModerationSection.jsx             |  2 +-
 .../ModerationReviewIcon.tsx                  |  2 +-
 .../frontend/src/metabase-enterprise/redux.ts | 10 ++
 .../containers/EditSandboxingModal.tsx        |  2 +-
 .../components/SnippetCollectionForm.tsx      |  2 +-
 .../whitelabel/components/LogoIcon.jsx        |  2 +-
 frontend/src/metabase/App.tsx                 |  2 +-
 .../app/containers/AccountApp/AccountApp.jsx  |  2 +-
 .../ArchiveAlertModal/ArchiveAlertModal.jsx   |  2 +-
 .../ArchivePulseModal/ArchivePulseModal.jsx   |  2 +-
 .../NotificationsApp/NotificationsApp.jsx     |  2 +-
 .../UnsubscribeAlertModal.jsx                 |  2 +-
 .../UnsubscribePulseModal.jsx                 |  2 +-
 .../UserPasswordApp/UserPasswordApp.tsx       |  3 +-
 .../UserProfileApp/UserProfileApp.tsx         |  3 +-
 .../actions/components/ActionViz/Action.tsx   |  3 +-
 .../ActionViz/ActionDashcardSettings.tsx      |  2 +-
 .../ActionCreator/ActionCreator.tsx           |  2 +-
 .../ActionCreator/InlineActionSettings.tsx    |  2 +-
 .../ActionCreatorModal/ActionCreatorModal.tsx |  2 +-
 .../DeprecationNotice/DeprecationNotice.tsx   |  2 +-
 .../databases/containers/DatabaseEditApp.tsx  |  2 +-
 .../databases/containers/DatabaseListApp.jsx  |  2 +-
 .../containers/DataModelApp/DataModelApp.jsx  |  2 +-
 .../containers/RevisionHistoryApp.jsx         |  2 +-
 .../admin/datamodel/containers/SegmentApp.jsx |  2 +-
 .../datamodel/containers/SegmentListApp.jsx   |  2 +-
 .../datamodel/hoc/FilteredToUrlTable.jsx      |  2 +-
 .../FieldFormattingSettings.tsx               |  2 +-
 .../FieldGeneralSettings.tsx                  |  2 +-
 .../FieldRemappingSettings.jsx                |  2 +-
 .../MetadataFieldSettings.tsx                 |  2 +-
 .../MetadataHeader/MetadataHeader.tsx         |  2 +-
 .../MetadataSchemaList/MetadataSchemaList.tsx |  2 +-
 .../MetadataTable/MetadataTable.tsx           |  2 +-
 .../MetadataTableColumn.tsx                   |  2 +-
 .../MetadataTableColumnList.tsx               |  2 +-
 .../MetadataTableList/MetadataTableList.tsx   |  2 +-
 .../admin/people/components/GroupDetail.jsx   |  2 +-
 .../admin/people/components/PeopleList.jsx    |  2 +-
 .../people/containers/GroupsListingApp.jsx    |  2 +-
 .../people/containers/PeopleListingApp.jsx    |  2 +-
 .../people/containers/UserActivationModal.jsx |  2 +-
 .../containers/UserPasswordResetModal.jsx     |  2 +-
 .../people/containers/UserSuccessModal.jsx    |  2 +-
 .../CollectionPermissionsModal.jsx            |  2 +-
 .../ToolbarUpsell/ToolbarUpsell.tsx           |  2 +-
 .../CollectionPermissionsPage.tsx             |  2 +-
 .../DatabasesPermissionsPage.jsx              |  3 +-
 .../GroupsPermissionsPage.jsx                 |  3 +-
 .../SettingsEditor/SettingsEditor.jsx         |  2 +-
 .../GoogleAuthCard/GoogleAuthCard.tsx         |  2 +-
 .../GoogleAuthForm/GoogleAuthForm.tsx         |  3 +-
 .../containers/LdapAuthCard/LdapAuthCard.tsx  |  2 +-
 .../settings/components/SettingsLdapForm.tsx  |  2 +-
 .../SettingsLicense/SettingsLicense.tsx       |  2 +-
 .../UploadSettings/UploadSettingsForm.tsx     |  3 +-
 .../widgets/RedirectWidget/RedirectWidget.tsx |  3 +-
 .../containers/GroupMappingsWidget.tsx        |  2 +-
 .../containers/RedirectToAllowedSettings.jsx  |  2 +-
 .../SetupCheckList/SetupCheckList.jsx         |  2 +-
 .../SlackSettings/SlackSettings.tsx           |  3 +-
 .../containers/SlackSetup/SlackSetup.tsx      |  2 +-
 .../SlackSetupForm/SlackSetupForm.tsx         |  2 +-
 .../containers/SlackStatus/SlackStatus.tsx    |  3 +-
 .../SlackStatusForm/SlackStatusForm.tsx       |  3 +-
 .../ModelCacheRefreshJobModal.tsx             |  2 +-
 .../ModelCacheRefreshJobs.tsx                 |  2 +-
 .../metabase/admin/tools/containers/Tools.tsx |  2 +-
 frontend/src/metabase/admin/utils.js          |  2 +-
 frontend/src/metabase/api/api.ts              | 28 +++++-
 frontend/src/metabase/app.js                  |  6 +-
 .../containers/TableBrowser/TableBrowser.jsx  |  2 +-
 .../components/ActionMenu/ActionMenu.tsx      |  3 +-
 .../components/CollectionCopyEntityModal.tsx  |  2 +-
 .../CreateCollectionForm.tsx                  |  2 +-
 .../CollectionHeader/CollectionHeader.tsx     |  3 +-
 .../containers/CreateCollectionModal.tsx      |  2 +-
 .../AdminAwareEmptyState.jsx                  |  2 +-
 .../ArchiveCollectionModal.jsx                |  2 +-
 .../CollectionList/CollectionList.jsx         |  2 +-
 .../FieldValuesWidget/FieldValuesWidget.tsx   |  3 +-
 .../LastEditInfoLabel/LastEditInfoLabel.tsx   |  2 +-
 .../CategoryFingerprint.jsx                   |  2 +-
 .../MetadataInfo/TableInfo/TableInfo.tsx      |  2 +-
 .../components/SaveStatus/SaveStatus.jsx      |  2 +-
 .../containers/AdHocQuestionLoader.jsx        |  2 +-
 .../containers/NewItemMenu/NewItemMenu.tsx    |  2 +-
 .../containers/NotFoundFallbackPage.tsx       |  2 +-
 .../metabase/containers/SchedulePicker.tsx    |  3 +-
 .../ActionSidebar/ActionSidebar.tsx           |  2 +-
 .../dashboard/components/ClickMappings.jsx    |  2 +-
 .../ActionSettingsButton.tsx                  |  2 +-
 .../DashCardCardParameterMapper.tsx           |  2 +-
 .../components/DashboardCopyModal.jsx         |  2 +-
 .../dashboard/components/DashboardGrid.tsx    |  2 +-
 .../components/DashboardMoveModal.tsx         |  2 +-
 .../QuestionPicker/QuestionPicker.jsx         |  3 +-
 .../containers/ArchiveDashboardModal.jsx      |  2 +-
 .../containers/AutomaticDashboardApp.jsx      |  2 +-
 .../containers/CreateDashboardForm.tsx        |  2 +-
 .../containers/CreateDashboardModal.tsx       |  2 +-
 .../containers/DashboardApp/DashboardApp.tsx  |  3 +-
 .../metabase/dashboard/hoc/DashboardData.jsx  |  2 +-
 .../entities/containers/EntityListLoader.jsx  |  2 +-
 .../containers/EntityObjectLoader.jsx         |  2 +-
 .../entities/containers/EntityType.jsx        |  3 +-
 frontend/src/metabase/env.ts                  | 46 +++++++--
 frontend/src/metabase/hoc/ModalRoute.tsx      |  2 +-
 frontend/src/metabase/hoc/Remapped.jsx        |  2 +-
 frontend/src/metabase/hoc/Routeless.jsx       |  3 +-
 frontend/src/metabase/hoc/Toast.jsx           |  2 +-
 .../src/metabase/lib/redux/custom-context.tsx | 34 +++++++
 frontend/src/metabase/lib/redux/hooks.ts      | 16 +--
 frontend/src/metabase/lib/redux/index.ts      |  1 +
 .../ModelActionDetails/ModelActionDetails.tsx |  2 +-
 .../ModelDetailPage/ModelDetailPage.tsx       |  3 +-
 .../components/ProfileLink/ProfileLink.jsx    |  4 +-
 .../metabase/nav/containers/AppBar/AppBar.tsx |  2 +-
 .../nav/containers/MainNavbar/MainNavbar.tsx  |  2 +-
 .../BookmarkList/BookmarkList.tsx             |  2 +-
 .../MainNavbarContainer.tsx                   |  2 +-
 .../src/metabase/nav/containers/Navbar.tsx    |  2 +-
 .../QuestionLineage/QuestionLineage.tsx       |  3 +-
 .../ValuesSourceTypeModal.tsx                 |  3 +-
 .../PublicAction/PublicActionLoader.tsx       |  2 +-
 .../public/containers/PublicApp/PublicApp.tsx |  3 +-
 .../PublicOrEmbeddedDashboard.tsx             |  2 +-
 ...rEmbeddedDashboardView-filters.stories.tsx |  6 +-
 .../PublicOrEmbeddedDashboardView.stories.tsx |  6 +-
 .../PublicOrEmbeddedQuestionView.stories.tsx  |  6 +-
 .../AlertModals/AlertEditChannels.jsx         |  2 +-
 .../components/AlertModals/AlertEditForm.jsx  |  2 +-
 .../AlertModals/RawDataAlertTip.jsx           |  2 +-
 .../components/DataSelector/DataSelector.jsx  |  2 +-
 .../saved-entity-picker/SavedEntityPicker.jsx |  2 +-
 .../DatasetEditor/DatasetEditor.jsx           |  2 +-
 .../SemanticTypePicker/FKTargetPicker.tsx     |  2 +-
 .../NativeQueryEditor/NativeQueryEditor.tsx   |  2 +-
 .../NewDatasetModal/NewDatasetModal.jsx       |  2 +-
 .../components/dataref/TableInfoLoader.tsx    |  2 +-
 .../components/dataref/TablePane.tsx          |  2 +-
 .../ExpressionEditorTextfield.tsx             |  2 +-
 .../template_tags/SnippetForm/SnippetForm.tsx |  2 +-
 .../SnippetSidebar/SnippetSidebar.jsx         |  2 +-
 .../template_tags/TagEditorParam.tsx          |  2 +-
 .../QuestionRowCount/QuestionRowCount.tsx     |  2 +-
 .../components/view/View/View/View.jsx        |  2 +-
 .../DatasetManagementSection.jsx              |  2 +-
 .../query_builder/containers/QueryBuilder.tsx |  4 +-
 .../containers/ArchiveQuestionModal.jsx       |  2 +-
 .../reference/components/FieldsToGroupBy.jsx  |  2 +-
 .../reference/databases/DatabaseDetail.jsx    |  2 +-
 .../databases/DatabaseDetailContainer.jsx     |  2 +-
 .../reference/databases/DatabaseList.jsx      |  2 +-
 .../databases/DatabaseListContainer.jsx       |  2 +-
 .../reference/databases/FieldDetail.jsx       |  2 +-
 .../databases/FieldDetailContainer.jsx        |  2 +-
 .../reference/databases/FieldList.jsx         |  2 +-
 .../databases/FieldListContainer.jsx          |  2 +-
 .../reference/databases/TableDetail.jsx       |  2 +-
 .../databases/TableDetailContainer.jsx        |  2 +-
 .../reference/databases/TableList.jsx         |  2 +-
 .../databases/TableListContainer.jsx          |  2 +-
 .../reference/databases/TableQuestions.jsx    |  2 +-
 .../databases/TableQuestionsContainer.jsx     |  2 +-
 .../reference/segments/SegmentDetail.jsx      |  2 +-
 .../segments/SegmentDetailContainer.jsx       |  2 +-
 .../reference/segments/SegmentFieldDetail.jsx |  2 +-
 .../segments/SegmentFieldDetailContainer.jsx  |  2 +-
 .../reference/segments/SegmentFieldList.jsx   |  2 +-
 .../segments/SegmentFieldListContainer.jsx    |  2 +-
 .../segments/SegmentListContainer.jsx         |  2 +-
 .../reference/segments/SegmentQuestions.jsx   |  2 +-
 .../segments/SegmentQuestionsContainer.jsx    |  2 +-
 .../reference/segments/SegmentRevisions.jsx   |  2 +-
 .../segments/SegmentRevisionsContainer.jsx    |  2 +-
 .../AddEditSidebar/AddEditSidebar.jsx         |  3 +-
 .../sharing/components/PulsesListSidebar.jsx  |  2 +-
 .../SharingSidebar/SharingSidebar.jsx         |  2 +-
 .../DatabaseStatus/DatabaseStatus.tsx         |  2 +-
 .../DeleteEventModal/DeleteEventModal.tsx     |  2 +-
 .../DeleteTimelineModal.tsx                   |  2 +-
 .../EditEventModal/EditEventModal.tsx         |  2 +-
 .../EditTimelineModal/EditTimelineModal.tsx   |  2 +-
 .../MoveEventModal/MoveEventModal.tsx         |  2 +-
 .../MoveTimelineModal/MoveTimelineModal.tsx   |  2 +-
 .../NewEventModal/NewEventModal.tsx           |  2 +-
 .../NewEventWithTimelineModal.tsx             |  2 +-
 .../NewTimelineModal/NewTimelineModal.tsx     |  2 +-
 .../TimelineArchiveModal.tsx                  |  2 +-
 .../TimelineDetailsModal.tsx                  |  2 +-
 .../TimelineListArchiveModal.tsx              |  2 +-
 .../common/containers/EventForm/EventForm.tsx |  3 +-
 .../EditEventModal/EditEventModal.tsx         |  2 +-
 .../MoveEventModal/MoveEventModal.tsx         |  2 +-
 .../NewEventModal/NewEventModal.tsx           |  2 +-
 .../TimelinePanel/TimelinePanel.tsx           |  2 +-
 .../components/ChoroplethMap.jsx              |  2 +-
 .../ClickActions/ClickActionsPopover.tsx      |  2 +-
 .../components/ObjectDetail/ObjectDetail.tsx  |  3 +-
 .../TableInteractive/TableInteractive.jsx     |  2 +-
 .../Visualization/Visualization.jsx           |  2 +-
 .../visualizations/PivotTable/PivotTable.tsx  |  2 +-
 frontend/test/__support__/storybook.tsx       |  6 +-
 frontend/test/__support__/ui.tsx              | 10 +-
 223 files changed, 477 insertions(+), 302 deletions(-)
 create mode 100644 e2e/test-component/scenarios/embedding-sdk/redux-provider-clash.cy.spec.tsx
 create mode 100644 enterprise/frontend/src/metabase-enterprise/redux.ts
 create mode 100644 frontend/src/metabase/lib/redux/custom-context.tsx

diff --git a/e2e/test-component/scenarios/embedding-sdk/redux-provider-clash.cy.spec.tsx b/e2e/test-component/scenarios/embedding-sdk/redux-provider-clash.cy.spec.tsx
new file mode 100644
index 00000000000..e5dcdcb733a
--- /dev/null
+++ b/e2e/test-component/scenarios/embedding-sdk/redux-provider-clash.cy.spec.tsx
@@ -0,0 +1,99 @@
+import {
+  MetabaseProvider,
+  StaticDashboard,
+} from "@metabase/embedding-sdk-react";
+import { configureStore, createSlice } from "@reduxjs/toolkit";
+import { Provider, useDispatch, useSelector } from "react-redux";
+
+import { ORDERS_DASHBOARD_ID } from "e2e/support/cypress_sample_instance_data";
+import { describeEE } from "e2e/support/helpers";
+import {
+  AUTH_PROVIDER_URL,
+  METABASE_INSTANCE_URL,
+  mockAuthProviderAndJwtSignIn,
+  signInAsAdminAndEnableEmbeddingSdk,
+} from "e2e/support/helpers/component-testing-sdk";
+import { getSdkRoot } from "e2e/support/helpers/e2e-embedding-sdk-helpers";
+
+describeEE(
+  "scenarios > embedding-sdk > the redux provider context should not clash with the host app",
+  () => {
+    beforeEach(() => {
+      signInAsAdminAndEnableEmbeddingSdk();
+
+      cy.signOut();
+
+      mockAuthProviderAndJwtSignIn();
+    });
+
+    it("the host app redux logic should work normally even inside MetabaseProvider", () => {
+      cy.mount(
+        <Provider store={customerStore}>
+          <div data-testid="outside-metabase-provider">
+            <CounterButton />
+          </div>
+          <MetabaseProvider
+            authConfig={{
+              authProviderUri: AUTH_PROVIDER_URL,
+              metabaseInstanceUrl: METABASE_INSTANCE_URL,
+            }}
+          >
+            <div data-testid="inside-metabase-provider">
+              <CounterButton />
+            </div>
+            <StaticDashboard dashboardId={ORDERS_DASHBOARD_ID} withDownloads />
+          </MetabaseProvider>
+        </Provider>,
+      );
+
+      // the button should render and access the correct redux state both inside and outside the MetabaseProvider
+      cy.findByTestId("outside-metabase-provider")
+        .findByText("0")
+        .should("exist");
+      cy.findByTestId("inside-metabase-provider")
+        .findByText("0")
+        .should("exist");
+
+      // sanity check that it's actually working and actions work
+      cy.findByTestId("inside-metabase-provider").findByText("0").click();
+      cy.findByTestId("outside-metabase-provider")
+        .findByText("1")
+        .should("exist");
+      cy.findByTestId("inside-metabase-provider")
+        .findByText("1")
+        .should("exist");
+
+      // also make sure the sdk is working, most data goes through redux so if it renders
+      // it means it's working
+      getSdkRoot().findByText("Orders in a dashboard").should("exist");
+      getSdkRoot().findByText("Product ID").should("exist");
+    });
+  },
+);
+
+// sample code for customer app
+const slice = createSlice({
+  name: "counter",
+  initialState: {
+    value: 0,
+  },
+  reducers: {
+    increment: state => {
+      state.value += 1;
+    },
+  },
+});
+const { increment } = slice.actions;
+const customerStore = configureStore({
+  reducer: {
+    counter: slice.reducer,
+  },
+});
+
+const CounterButton = () => {
+  const count = useSelector(
+    (state: { counter: { value: number } }) => state.counter.value,
+  );
+  const dispatch = useDispatch();
+  return <button onClick={() => dispatch(increment())}>{count}</button>;
+};
diff --git a/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx b/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx
index 3c8f7116173..68e8d145c77 100644
--- a/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx
+++ b/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx
@@ -1,8 +1,8 @@
 import { Global, css } from "@emotion/react";
 import { useMemo } from "react";
-import { useSelector } from "react-redux";
 
 import { defaultFontFiles } from "metabase/css/core/fonts.styled";
+import { useSelector } from "metabase/lib/redux";
 import { getFontFiles } from "metabase/styled-components/selectors";
 
 /**
diff --git a/enterprise/frontend/src/embedding-sdk/components/public/InteractiveDashboard/ConnectedDashboard.tsx b/enterprise/frontend/src/embedding-sdk/components/public/InteractiveDashboard/ConnectedDashboard.tsx
index c34f45a418f..2d626e734fb 100644
--- a/enterprise/frontend/src/embedding-sdk/components/public/InteractiveDashboard/ConnectedDashboard.tsx
+++ b/enterprise/frontend/src/embedding-sdk/components/public/InteractiveDashboard/ConnectedDashboard.tsx
@@ -1,6 +1,6 @@
 import type { Query } from "history";
 import type { ComponentType, FC } from "react";
-import { type ConnectedProps, connect } from "react-redux";
+import type { ConnectedProps } from "react-redux";
 import _ from "underscore";
 
 import type { SdkPluginsConfig } from "embedding-sdk";
@@ -39,6 +39,7 @@ import type {
   DashboardRefreshPeriodControls,
 } from "metabase/dashboard/types";
 import { useValidatedEntityId } from "metabase/lib/entity-id/hooks/use-validated-entity-id";
+import { connect } from "metabase/lib/redux";
 import type { PublicOrEmbeddedDashboardEventHandlersProps } from "metabase/public/containers/PublicOrEmbeddedDashboard/types";
 import { useDashboardLoadHandlers } from "metabase/public/containers/PublicOrEmbeddedDashboard/use-dashboard-load-handlers";
 import { closeNavbar, setErrorPage } from "metabase/redux/app";
diff --git a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
index 7aebcf0a272..90d4eee2684 100644
--- a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
+++ b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
@@ -1,7 +1,6 @@
 import { Global } from "@emotion/react";
 import type { Action, Store } from "@reduxjs/toolkit";
 import { type JSX, type ReactNode, memo, useEffect, useRef } from "react";
-import { Provider } from "react-redux";
 
 import { SdkThemeProvider } from "embedding-sdk/components/private/SdkThemeProvider";
 import { EMBEDDING_SDK_ROOT_ELEMENT_ID } from "embedding-sdk/config";
@@ -22,6 +21,7 @@ import type {
 } from "embedding-sdk/store/types";
 import type { MetabaseAuthConfig } from "embedding-sdk/types";
 import type { MetabaseTheme } from "embedding-sdk/types/theme";
+import { MetabaseReduxProvider } from "metabase/lib/redux";
 import { LocaleProvider } from "metabase/public/LocaleProvider";
 import { setOptions } from "metabase/redux/embed";
 import { EmotionCacheProvider } from "metabase/styled-components/components/EmotionCacheProvider";
@@ -141,8 +141,8 @@ export const MetabaseProvider = memo(function MetabaseProvider(
   }
 
   return (
-    <Provider store={storeRef.current}>
+    <MetabaseReduxProvider store={storeRef.current}>
       <MetabaseProviderInternal store={storeRef.current} {...props} />
-    </Provider>
+    </MetabaseReduxProvider>
   );
 });
diff --git a/enterprise/frontend/src/embedding-sdk/hooks/private/use-sdk-usage-problem.ts b/enterprise/frontend/src/embedding-sdk/hooks/private/use-sdk-usage-problem.ts
index 86c575b7d24..eda6345f66d 100644
--- a/enterprise/frontend/src/embedding-sdk/hooks/private/use-sdk-usage-problem.ts
+++ b/enterprise/frontend/src/embedding-sdk/hooks/private/use-sdk-usage-problem.ts
@@ -1,12 +1,11 @@
 import { useEffect, useMemo, useRef } from "react";
-import { useDispatch } from "react-redux";
 
 import type { MetabaseAuthConfig } from "embedding-sdk";
 import { printUsageProblemToConsole } from "embedding-sdk/lib/print-usage-problem";
 import { getSdkUsageProblem } from "embedding-sdk/lib/usage-problem";
+import { useSdkDispatch, useSdkSelector } from "embedding-sdk/store";
 import { setUsageProblem } from "embedding-sdk/store/reducer";
 import { useSetting } from "metabase/common/hooks";
-import { useSelector } from "metabase/lib/redux";
 import { getTokenFeature } from "metabase/setup/selectors";
 
 export function useSdkUsageProblem({
@@ -18,7 +17,7 @@ export function useSdkUsageProblem({
 }) {
   const hasLoggedRef = useRef(false);
 
-  const dispatch = useDispatch();
+  const dispatch = useSdkDispatch();
 
   // When the setting haven't been loaded or failed to query, we assume that the
   // feature is _enabled_ first. Otherwise, when a user's instance is temporarily down,
@@ -26,7 +25,7 @@ export function useSdkUsageProblem({
   // TODO: replace this with "enable-embedding-sdk" once the settings PR landed.
   const isEnabled = useSetting("enable-embedding") ?? true;
 
-  const hasTokenFeature = useSelector(state => {
+  const hasTokenFeature = useSdkSelector(state => {
     // We also assume that the feature is enabled if the token-features are missing.
     // Same reason as above.
     if (!state.settings.values?.["token-features"]) {
diff --git a/enterprise/frontend/src/embedding-sdk/hooks/public/use-current-user.ts b/enterprise/frontend/src/embedding-sdk/hooks/public/use-current-user.ts
index 5e63607da5f..3fd865720d3 100644
--- a/enterprise/frontend/src/embedding-sdk/hooks/public/use-current-user.ts
+++ b/enterprise/frontend/src/embedding-sdk/hooks/public/use-current-user.ts
@@ -1,5 +1,4 @@
-import { useSelector } from "react-redux";
-
+import { useSelector } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 export const useCurrentUser = () => useSelector(getUser);
diff --git a/enterprise/frontend/src/embedding-sdk/store/index.ts b/enterprise/frontend/src/embedding-sdk/store/index.ts
index bce7dffdc27..cabf7521ad4 100644
--- a/enterprise/frontend/src/embedding-sdk/store/index.ts
+++ b/enterprise/frontend/src/embedding-sdk/store/index.ts
@@ -1,12 +1,12 @@
-import type {
-  AnyAction,
-  Reducer,
-  Store,
-  ThunkDispatch,
-} from "@reduxjs/toolkit";
+/* eslint-disable no-restricted-imports */
+import type { AnyAction, Reducer, Store } from "@reduxjs/toolkit";
 import { useContext } from "react";
-import { ReactReduxContext, useDispatch, useStore } from "react-redux";
 
+import {
+  MetabaseReduxContext,
+  useDispatch,
+  useStore,
+} from "metabase/lib/redux";
 import { mainReducers } from "metabase/reducers-main";
 import { getStore } from "metabase/store";
 
@@ -29,11 +29,7 @@ export const getSdkStore = () =>
     },
   }) as unknown as Store<SdkStoreState, AnyAction>;
 
-export const useSdkDispatch: () => ThunkDispatch<
-  SdkStoreState,
-  void,
-  AnyAction
-> = () => {
+export const useSdkDispatch = () => {
   useCheckSdkReduxContext();
 
   return useDispatch();
@@ -46,7 +42,7 @@ export const useSdkStore = () => {
 };
 
 const useCheckSdkReduxContext = () => {
-  const context = useContext(ReactReduxContext);
+  const context = useContext(MetabaseReduxContext);
 
   if (!context) {
     console.warn(
diff --git a/enterprise/frontend/src/embedding-sdk/store/use-sdk-selector.ts b/enterprise/frontend/src/embedding-sdk/store/use-sdk-selector.ts
index 74f03d0f7f7..3bdb1df10a8 100644
--- a/enterprise/frontend/src/embedding-sdk/store/use-sdk-selector.ts
+++ b/enterprise/frontend/src/embedding-sdk/store/use-sdk-selector.ts
@@ -1,24 +1,26 @@
 import { useContext } from "react";
-import {
-  ReactReduxContext,
-  type TypedUseSelectorHook,
-  useSelector,
-} from "react-redux";
+import type { TypedUseSelectorHook } from "react-redux";
+import { createSelectorHook } from "react-redux";
 
 import type { SdkStoreState } from "embedding-sdk/store/types";
+import { MetabaseReduxContext } from "metabase/lib/redux";
 
 // eslint-disable-next-line no-literal-metabase-strings -- this string only shows in the console.
 export const USE_OUTSIDE_OF_CONTEXT_MESSAGE = `Hooks from the Metabase Embedding SDK must be used within a component wrapped by the MetabaseProvider`;
 
+const _useSdkSelector: TypedUseSelectorHook<SdkStoreState> =
+  createSelectorHook(MetabaseReduxContext);
+
 export const useSdkSelector: TypedUseSelectorHook<SdkStoreState> = (
   selector,
   options,
 ) => {
-  const context = useContext(ReactReduxContext);
+  const context = useContext(MetabaseReduxContext);
 
   if (!context) {
     throw new Error(USE_OUTSIDE_OF_CONTEXT_MESSAGE);
   }
 
-  return useSelector(selector, options);
+  // @ts-expect-error -- weird error on the options type
+  return _useSdkSelector(selector, options);
 };
diff --git a/enterprise/frontend/src/metabase-enterprise/advanced_permissions/components/ImpersonationModal/ImpersonationModal.tsx b/enterprise/frontend/src/metabase-enterprise/advanced_permissions/components/ImpersonationModal/ImpersonationModal.tsx
index 393637073cb..06b1b92f08f 100644
--- a/enterprise/frontend/src/metabase-enterprise/advanced_permissions/components/ImpersonationModal/ImpersonationModal.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/advanced_permissions/components/ImpersonationModal/ImpersonationModal.tsx
@@ -1,5 +1,4 @@
 import { useCallback } from "react";
-import { useSelector } from "react-redux";
 import { withRouter } from "react-router";
 import { push } from "react-router-redux";
 import { useAsyncFn, useMount } from "react-use";
@@ -17,11 +16,11 @@ import { useDispatch } from "metabase/lib/redux";
 import { updateImpersonation } from "metabase-enterprise/advanced_permissions/reducer";
 import { getImpersonation } from "metabase-enterprise/advanced_permissions/selectors";
 import type {
-  AdvancedPermissionsStoreState,
   ImpersonationModalParams,
   ImpersonationParams,
 } from "metabase-enterprise/advanced_permissions/types";
 import { getImpersonatedDatabaseId } from "metabase-enterprise/advanced_permissions/utils";
+import { useEnterpriseSelector } from "metabase-enterprise/redux";
 import { ImpersonationApi } from "metabase-enterprise/services";
 import { fetchUserAttributes } from "metabase-enterprise/shared/reducer";
 import { getUserAttributes } from "metabase-enterprise/shared/selectors";
@@ -76,11 +75,10 @@ const _ImpersonationModal = ({ route, params }: ImpersonationModalProps) => {
     id: databaseId,
   });
 
-  const attributes = useSelector(getUserAttributes);
-  const draftImpersonation = useSelector<
-    AdvancedPermissionsStoreState,
-    Impersonation | undefined
-  >(getImpersonation(databaseId, groupId));
+  const attributes = useEnterpriseSelector(getUserAttributes);
+  const draftImpersonation = useEnterpriseSelector(
+    getImpersonation(databaseId, groupId),
+  );
 
   const selectedAttribute =
     draftImpersonation?.attribute ?? impersonation?.attribute;
diff --git a/enterprise/frontend/src/metabase-enterprise/application_permissions/pages/ApplicationPermissionsPage/ApplicationPermissionsPage.tsx b/enterprise/frontend/src/metabase-enterprise/application_permissions/pages/ApplicationPermissionsPage/ApplicationPermissionsPage.tsx
index ebff86fbf8d..0bd543349c2 100644
--- a/enterprise/frontend/src/metabase-enterprise/application_permissions/pages/ApplicationPermissionsPage/ApplicationPermissionsPage.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/application_permissions/pages/ApplicationPermissionsPage/ApplicationPermissionsPage.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useEffect } from "react";
-import { connect } from "react-redux";
 import type { Route } from "react-router";
 import _ from "underscore";
 
@@ -7,6 +6,7 @@ import { ApplicationPermissionsHelp } from "metabase/admin/permissions/component
 import { PermissionsEditor } from "metabase/admin/permissions/components/PermissionsEditor";
 import PermissionsPageLayout from "metabase/admin/permissions/components/PermissionsPageLayout";
 import Groups from "metabase/entities/groups";
+import { connect } from "metabase/lib/redux";
 import {
   initializeApplicationPermissions,
   saveApplicationPermissions,
diff --git a/enterprise/frontend/src/metabase-enterprise/audit_app/containers/AuditTable.jsx b/enterprise/frontend/src/metabase-enterprise/audit_app/containers/AuditTable.jsx
index bbb4c149cd0..f19ab291abf 100644
--- a/enterprise/frontend/src/metabase-enterprise/audit_app/containers/AuditTable.jsx
+++ b/enterprise/frontend/src/metabase-enterprise/audit_app/containers/AuditTable.jsx
@@ -3,13 +3,13 @@ import "../components/AuditTableVisualization";
 import { chain } from "icepick";
 import PropTypes from "prop-types";
 import { useState } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
 import { PaginationControls } from "metabase/components/PaginationControls";
 import CS from "metabase/css/core/index.css";
 import { usePagination } from "metabase/hooks/use-pagination";
+import { connect } from "metabase/lib/redux";
 import { getMetadata } from "metabase/selectors/metadata";
 import Question from "metabase-lib/v1/Question";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/audit_app/containers/UnsubscribeUserModal/UnsubscribeUserModal.jsx b/enterprise/frontend/src/metabase-enterprise/audit_app/containers/UnsubscribeUserModal/UnsubscribeUserModal.jsx
index 9e237981bd0..f0454ac55ce 100644
--- a/enterprise/frontend/src/metabase-enterprise/audit_app/containers/UnsubscribeUserModal/UnsubscribeUserModal.jsx
+++ b/enterprise/frontend/src/metabase-enterprise/audit_app/containers/UnsubscribeUserModal/UnsubscribeUserModal.jsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
 import Users from "metabase/entities/users";
+import { connect } from "metabase/lib/redux";
 import { addUndo } from "metabase/redux/undo";
 import { AuditApi } from "metabase-enterprise/services";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsJWTForm/SettingsJWTForm.tsx b/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsJWTForm/SettingsJWTForm.tsx
index 7ae1b20085b..827cbba7195 100644
--- a/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsJWTForm/SettingsJWTForm.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsJWTForm/SettingsJWTForm.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -19,6 +18,7 @@ import {
   FormSwitch,
   FormTextInput,
 } from "metabase/forms";
+import { connect } from "metabase/lib/redux";
 import { Flex, Stack, rem } from "metabase/ui";
 import type { SettingValue } from "metabase-types/api";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsSAMLForm/SettingsSAMLForm.jsx b/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsSAMLForm/SettingsSAMLForm.jsx
index 7c6d9653fdd..b19bb500eae 100644
--- a/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsSAMLForm/SettingsSAMLForm.jsx
+++ b/enterprise/frontend/src/metabase-enterprise/auth/components/SettingsSAMLForm/SettingsSAMLForm.jsx
@@ -1,7 +1,6 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { jt, t } from "ttag";
 import _ from "underscore";
 
@@ -23,6 +22,7 @@ import {
   FormTextInput,
   FormTextarea,
 } from "metabase/forms";
+import { connect } from "metabase/lib/redux";
 import { Stack } from "metabase/ui";
 
 import {
diff --git a/enterprise/frontend/src/metabase-enterprise/auth/containers/JwtAuthCard/JwtAuthCard.tsx b/enterprise/frontend/src/metabase-enterprise/auth/containers/JwtAuthCard/JwtAuthCard.tsx
index 9e33cd12404..be1e39148dc 100644
--- a/enterprise/frontend/src/metabase-enterprise/auth/containers/JwtAuthCard/JwtAuthCard.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/auth/containers/JwtAuthCard/JwtAuthCard.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import AuthCard from "metabase/admin/settings/auth/components/AuthCard";
 import { updateSettings } from "metabase/admin/settings/settings";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { Dispatch, State } from "metabase-types/store";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/auth/containers/SamlAuthCard/SamlAuthCard.tsx b/enterprise/frontend/src/metabase-enterprise/auth/containers/SamlAuthCard/SamlAuthCard.tsx
index dbd1d1073ba..36612c5c7c6 100644
--- a/enterprise/frontend/src/metabase-enterprise/auth/containers/SamlAuthCard/SamlAuthCard.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/auth/containers/SamlAuthCard/SamlAuthCard.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import AuthCard from "metabase/admin/settings/auth/components/AuthCard";
 import { updateSettings } from "metabase/admin/settings/settings";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { Dispatch, State } from "metabase-types/store";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/license/components/LicenseAndBillingSettings/LicenseAndBillingSettings.tsx b/enterprise/frontend/src/metabase-enterprise/license/components/LicenseAndBillingSettings/LicenseAndBillingSettings.tsx
index f18438427e9..71abd7f1130 100644
--- a/enterprise/frontend/src/metabase-enterprise/license/components/LicenseAndBillingSettings/LicenseAndBillingSettings.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/license/components/LicenseAndBillingSettings/LicenseAndBillingSettings.tsx
@@ -1,5 +1,4 @@
 import moment from "moment-timezone"; // eslint-disable-line no-restricted-imports -- deprecated usage
-import { connect } from "react-redux";
 import { jt, t } from "ttag";
 
 import { LicenseInput } from "metabase/admin/settings/components/LicenseInput";
@@ -13,6 +12,7 @@ import {
 import { ExplorePlansIllustration } from "metabase/admin/settings/components/SettingsLicense/ExplorePlansIllustration";
 import LoadingSpinner from "metabase/components/LoadingSpinner";
 import ExternalLink from "metabase/core/components/ExternalLink";
+import { connect } from "metabase/lib/redux";
 import { getUpgradeUrl } from "metabase/selectors/settings";
 import { useGetBillingInfoQuery } from "metabase-enterprise/api";
 import { showLicenseAcceptedToast } from "metabase-enterprise/license/actions";
diff --git a/enterprise/frontend/src/metabase-enterprise/moderation/components/QuestionModerationSection/QuestionModerationSection.jsx b/enterprise/frontend/src/metabase-enterprise/moderation/components/QuestionModerationSection/QuestionModerationSection.jsx
index 2d1db5e17ea..2e7cf651ad7 100644
--- a/enterprise/frontend/src/metabase-enterprise/moderation/components/QuestionModerationSection/QuestionModerationSection.jsx
+++ b/enterprise/frontend/src/metabase-enterprise/moderation/components/QuestionModerationSection/QuestionModerationSection.jsx
@@ -1,8 +1,8 @@
 import PropTypes from "prop-types";
 import { Fragment } from "react";
-import { connect } from "react-redux";
 
 import { useEditItemVerificationMutation } from "metabase/api";
+import { connect } from "metabase/lib/redux";
 import { getIsModerator } from "metabase-enterprise/moderation/selectors";
 import { getLatestModerationReview } from "metabase-enterprise/moderation/service";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/moderation/containers/ModerationReviewIcon/ModerationReviewIcon.tsx b/enterprise/frontend/src/metabase-enterprise/moderation/containers/ModerationReviewIcon/ModerationReviewIcon.tsx
index 74c9fed8583..9ab72f2ed54 100644
--- a/enterprise/frontend/src/metabase-enterprise/moderation/containers/ModerationReviewIcon/ModerationReviewIcon.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/moderation/containers/ModerationReviewIcon/ModerationReviewIcon.tsx
@@ -1,6 +1,6 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 import type { State } from "metabase-types/store";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/redux.ts b/enterprise/frontend/src/metabase-enterprise/redux.ts
new file mode 100644
index 00000000000..3c4724ea664
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/redux.ts
@@ -0,0 +1,10 @@
+import type { TypedUseSelectorHook } from "react-redux";
+import { createSelectorHook } from "react-redux";
+
+import { MetabaseReduxContext } from "metabase/lib/redux";
+
+// TODO: use the real type after we figure out what it is
+type EnterpriseState = any;
+
+export const useEnterpriseSelector: TypedUseSelectorHook<EnterpriseState> =
+  createSelectorHook(MetabaseReduxContext);
diff --git a/enterprise/frontend/src/metabase-enterprise/sandboxes/containers/EditSandboxingModal.tsx b/enterprise/frontend/src/metabase-enterprise/sandboxes/containers/EditSandboxingModal.tsx
index 128c2aeeaaa..15269727e99 100644
--- a/enterprise/frontend/src/metabase-enterprise/sandboxes/containers/EditSandboxingModal.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/sandboxes/containers/EditSandboxingModal.tsx
@@ -1,11 +1,11 @@
 import { useEffect } from "react";
-import { connect } from "react-redux";
 import { withRouter } from "react-router";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import { getParentPath } from "metabase/hoc/ModalRoute";
+import { connect } from "metabase/lib/redux";
 import {
   getGroupTableAccessPolicy,
   getPolicyRequestState,
diff --git a/enterprise/frontend/src/metabase-enterprise/snippets/components/SnippetCollectionForm.tsx b/enterprise/frontend/src/metabase-enterprise/snippets/components/SnippetCollectionForm.tsx
index 098dd6e4838..0dc1ba9077d 100644
--- a/enterprise/frontend/src/metabase-enterprise/snippets/components/SnippetCollectionForm.tsx
+++ b/enterprise/frontend/src/metabase-enterprise/snippets/components/SnippetCollectionForm.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 import * as Yup from "yup";
@@ -17,6 +16,7 @@ import SnippetCollections from "metabase/entities/snippet-collections";
 import { Form, FormProvider } from "metabase/forms";
 import { color } from "metabase/lib/colors";
 import * as Errors from "metabase/lib/errors";
+import { connect } from "metabase/lib/redux";
 import type { Collection, CollectionId } from "metabase-types/api";
 import type { State } from "metabase-types/store";
 
diff --git a/enterprise/frontend/src/metabase-enterprise/whitelabel/components/LogoIcon.jsx b/enterprise/frontend/src/metabase-enterprise/whitelabel/components/LogoIcon.jsx
index f180130a1b7..9afdab51d48 100644
--- a/enterprise/frontend/src/metabase-enterprise/whitelabel/components/LogoIcon.jsx
+++ b/enterprise/frontend/src/metabase-enterprise/whitelabel/components/LogoIcon.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import CS from "metabase/css/core/index.css";
 import { parseDataUri, removeAllChildren } from "metabase/lib/dom";
+import { connect } from "metabase/lib/redux";
 import { getLogoUrl } from "metabase-enterprise/settings/selectors";
 
 const mapStateToProps = state => ({
diff --git a/frontend/src/metabase/App.tsx b/frontend/src/metabase/App.tsx
index b5c1dc4e4bf..11a1bd1b45b 100644
--- a/frontend/src/metabase/App.tsx
+++ b/frontend/src/metabase/App.tsx
@@ -2,7 +2,6 @@ import type { Location } from "history";
 import { KBarProvider } from "kbar";
 import type { ReactNode } from "react";
 import { useEffect, useState } from "react";
-import { connect } from "react-redux";
 
 import { AppBanner } from "metabase/components/AppBanner";
 import {
@@ -17,6 +16,7 @@ import { ContentViewportContext } from "metabase/core/context/ContentViewportCon
 import CS from "metabase/css/core/index.css";
 import ScrollToTop from "metabase/hoc/ScrollToTop";
 import { initializeIframeResizer } from "metabase/lib/dom";
+import { connect } from "metabase/lib/redux";
 import AppBar from "metabase/nav/containers/AppBar";
 import Navbar from "metabase/nav/containers/Navbar";
 import { setErrorPage } from "metabase/redux/app";
diff --git a/frontend/src/metabase/account/app/containers/AccountApp/AccountApp.jsx b/frontend/src/metabase/account/app/containers/AccountApp/AccountApp.jsx
index addbb738d7a..645cef15f99 100644
--- a/frontend/src/metabase/account/app/containers/AccountApp/AccountApp.jsx
+++ b/frontend/src/metabase/account/app/containers/AccountApp/AccountApp.jsx
@@ -1,6 +1,6 @@
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 import AccountLayout from "../../components/AccountLayout";
diff --git a/frontend/src/metabase/account/notifications/containers/ArchiveAlertModal/ArchiveAlertModal.jsx b/frontend/src/metabase/account/notifications/containers/ArchiveAlertModal/ArchiveAlertModal.jsx
index 923a6079ed5..9577b6ebf4c 100644
--- a/frontend/src/metabase/account/notifications/containers/ArchiveAlertModal/ArchiveAlertModal.jsx
+++ b/frontend/src/metabase/account/notifications/containers/ArchiveAlertModal/ArchiveAlertModal.jsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Alerts from "metabase/entities/alerts";
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 import ArchiveModal from "../../components/ArchiveModal";
diff --git a/frontend/src/metabase/account/notifications/containers/ArchivePulseModal/ArchivePulseModal.jsx b/frontend/src/metabase/account/notifications/containers/ArchivePulseModal/ArchivePulseModal.jsx
index 19a5fa0cbe5..15a3206e47f 100644
--- a/frontend/src/metabase/account/notifications/containers/ArchivePulseModal/ArchivePulseModal.jsx
+++ b/frontend/src/metabase/account/notifications/containers/ArchivePulseModal/ArchivePulseModal.jsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Pulses from "metabase/entities/pulses";
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 import ArchiveModal from "../../components/ArchiveModal";
diff --git a/frontend/src/metabase/account/notifications/containers/NotificationsApp/NotificationsApp.jsx b/frontend/src/metabase/account/notifications/containers/NotificationsApp/NotificationsApp.jsx
index 4486aabf50a..50649cd5871 100644
--- a/frontend/src/metabase/account/notifications/containers/NotificationsApp/NotificationsApp.jsx
+++ b/frontend/src/metabase/account/notifications/containers/NotificationsApp/NotificationsApp.jsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Alerts from "metabase/entities/alerts";
 import Pulses from "metabase/entities/pulses";
+import { connect } from "metabase/lib/redux";
 import {
   canManageSubscriptions,
   getUser,
diff --git a/frontend/src/metabase/account/notifications/containers/UnsubscribeAlertModal/UnsubscribeAlertModal.jsx b/frontend/src/metabase/account/notifications/containers/UnsubscribeAlertModal/UnsubscribeAlertModal.jsx
index 7b244e8c8fa..ff2daf00ea3 100644
--- a/frontend/src/metabase/account/notifications/containers/UnsubscribeAlertModal/UnsubscribeAlertModal.jsx
+++ b/frontend/src/metabase/account/notifications/containers/UnsubscribeAlertModal/UnsubscribeAlertModal.jsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Alerts from "metabase/entities/alerts";
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 import { navigateToArchive } from "../../actions";
diff --git a/frontend/src/metabase/account/notifications/containers/UnsubscribePulseModal/UnsubscribePulseModal.jsx b/frontend/src/metabase/account/notifications/containers/UnsubscribePulseModal/UnsubscribePulseModal.jsx
index d7925d758bf..886f1058f4b 100644
--- a/frontend/src/metabase/account/notifications/containers/UnsubscribePulseModal/UnsubscribePulseModal.jsx
+++ b/frontend/src/metabase/account/notifications/containers/UnsubscribePulseModal/UnsubscribePulseModal.jsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Pulses from "metabase/entities/pulses";
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 import { navigateToArchive } from "../../actions";
diff --git a/frontend/src/metabase/account/password/containers/UserPasswordApp/UserPasswordApp.tsx b/frontend/src/metabase/account/password/containers/UserPasswordApp/UserPasswordApp.tsx
index 3c674815506..407ffb699c0 100644
--- a/frontend/src/metabase/account/password/containers/UserPasswordApp/UserPasswordApp.tsx
+++ b/frontend/src/metabase/account/password/containers/UserPasswordApp/UserPasswordApp.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import { checkNotNull } from "metabase/lib/types";
 import { getUser } from "metabase/selectors/user";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/account/profile/containers/UserProfileApp/UserProfileApp.tsx b/frontend/src/metabase/account/profile/containers/UserProfileApp/UserProfileApp.tsx
index 77e462a6e05..dec3ece1364 100644
--- a/frontend/src/metabase/account/profile/containers/UserProfileApp/UserProfileApp.tsx
+++ b/frontend/src/metabase/account/profile/containers/UserProfileApp/UserProfileApp.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import { checkNotNull } from "metabase/lib/types";
 import { getUser } from "metabase/selectors/user";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/actions/components/ActionViz/Action.tsx b/frontend/src/metabase/actions/components/ActionViz/Action.tsx
index d4d6ce2c1eb..340025c7bba 100644
--- a/frontend/src/metabase/actions/components/ActionViz/Action.tsx
+++ b/frontend/src/metabase/actions/components/ActionViz/Action.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { skipToken, useGetCardQuery } from "metabase/api";
@@ -13,7 +12,7 @@ import {
   getParameterValues,
 } from "metabase/dashboard/selectors";
 import { getActionIsEnabledInDatabase } from "metabase/dashboard/utils";
-import { useSelector } from "metabase/lib/redux";
+import { connect, useSelector } from "metabase/lib/redux";
 import { getMetadata } from "metabase/selectors/metadata";
 import type { VisualizationProps } from "metabase/visualizations/types";
 import Question from "metabase-lib/v1/Question";
diff --git a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx
index 30c79093cd5..b76eb513b9a 100644
--- a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx
+++ b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx
@@ -1,5 +1,4 @@
 import { useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { ConnectedActionPicker } from "metabase/actions/containers/ActionPicker";
@@ -7,6 +6,7 @@ import EmptyState from "metabase/components/EmptyState";
 import Button from "metabase/core/components/Button";
 import CS from "metabase/css/core/index.css";
 import { setActionForDashcard } from "metabase/dashboard/actions";
+import { connect } from "metabase/lib/redux";
 import type {
   ActionDashboardCard,
   Dashboard,
diff --git a/frontend/src/metabase/actions/containers/ActionCreator/ActionCreator.tsx b/frontend/src/metabase/actions/containers/ActionCreator/ActionCreator.tsx
index c0f1a707d85..f6eeceb4c0e 100644
--- a/frontend/src/metabase/actions/containers/ActionCreator/ActionCreator.tsx
+++ b/frontend/src/metabase/actions/containers/ActionCreator/ActionCreator.tsx
@@ -1,5 +1,4 @@
 import { useState } from "react";
-import { connect } from "react-redux";
 import type { Route } from "react-router";
 import { t } from "ttag";
 import _ from "underscore";
@@ -15,6 +14,7 @@ import Database from "metabase/entities/databases";
 import Questions from "metabase/entities/questions";
 import useBeforeUnload from "metabase/hooks/use-before-unload";
 import { useCallbackEffect } from "metabase/hooks/use-callback-effect";
+import { connect } from "metabase/lib/redux";
 import { getMetadata } from "metabase/selectors/metadata";
 import type Question from "metabase-lib/v1/Question";
 import type Metadata from "metabase-lib/v1/metadata/Metadata";
diff --git a/frontend/src/metabase/actions/containers/ActionCreator/InlineActionSettings.tsx b/frontend/src/metabase/actions/containers/ActionCreator/InlineActionSettings.tsx
index 0abb99f1e2e..228fe24deac 100644
--- a/frontend/src/metabase/actions/containers/ActionCreator/InlineActionSettings.tsx
+++ b/frontend/src/metabase/actions/containers/ActionCreator/InlineActionSettings.tsx
@@ -1,5 +1,4 @@
 import type { ChangeEvent } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import ConfirmContent from "metabase/components/ConfirmContent";
@@ -13,6 +12,7 @@ import Tooltip from "metabase/core/components/Tooltip";
 import Actions from "metabase/entities/actions/actions";
 import { useToggle } from "metabase/hooks/use-toggle";
 import { useUniqueId } from "metabase/hooks/use-unique-id";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import SidebarContent from "metabase/query_builder/components/SidebarContent";
 import { getSetting } from "metabase/selectors/settings";
diff --git a/frontend/src/metabase/actions/containers/ActionCreatorModal/ActionCreatorModal.tsx b/frontend/src/metabase/actions/containers/ActionCreatorModal/ActionCreatorModal.tsx
index e906edf5ba7..b65244bfefd 100644
--- a/frontend/src/metabase/actions/containers/ActionCreatorModal/ActionCreatorModal.tsx
+++ b/frontend/src/metabase/actions/containers/ActionCreatorModal/ActionCreatorModal.tsx
@@ -1,12 +1,12 @@
 import type { LocationDescriptor } from "history";
 import { useEffect } from "react";
-import { connect } from "react-redux";
 import type { Route } from "react-router";
 import { replace } from "react-router-redux";
 import _ from "underscore";
 
 import { skipToken, useGetActionQuery } from "metabase/api";
 import Models from "metabase/entities/questions";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { setErrorPage } from "metabase/redux/app";
 import type Question from "metabase-lib/v1/Question";
diff --git a/frontend/src/metabase/admin/app/containers/DeprecationNotice/DeprecationNotice.tsx b/frontend/src/metabase/admin/app/containers/DeprecationNotice/DeprecationNotice.tsx
index 91ca2124dfc..a608f01f1d5 100644
--- a/frontend/src/metabase/admin/app/containers/DeprecationNotice/DeprecationNotice.tsx
+++ b/frontend/src/metabase/admin/app/containers/DeprecationNotice/DeprecationNotice.tsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Databases from "metabase/entities/databases";
+import { connect } from "metabase/lib/redux";
 import type Database from "metabase-lib/v1/metadata/Database";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.tsx b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.tsx
index 70032cfb365..055927dd0d6 100644
--- a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.tsx
+++ b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.tsx
@@ -2,7 +2,6 @@ import type { Location, LocationDescriptor } from "history";
 import { updateIn } from "icepick";
 import type { ComponentType } from "react";
 import { useState } from "react";
-import { connect } from "react-redux";
 import type { Route } from "react-router";
 import { push } from "react-router-redux";
 import { useMount } from "react-use";
@@ -19,6 +18,7 @@ import CS from "metabase/css/core/index.css";
 import { DatabaseForm } from "metabase/databases/components/DatabaseForm";
 import title from "metabase/hoc/Title";
 import { useCallbackEffect } from "metabase/hooks/use-callback-effect";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import { getUserIsAdmin } from "metabase/selectors/user";
 import Database from "metabase-lib/v1/metadata/Database";
diff --git a/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx b/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx
index f7ec9761f6e..4c9a21c99cf 100644
--- a/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx
+++ b/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import LoadingAndGenericErrorWrapper from "metabase/components/LoadingAndGenericErrorWrapper";
 import Database from "metabase/entities/databases";
+import { connect } from "metabase/lib/redux";
 import { isSyncInProgress } from "metabase/lib/syncing";
 import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
 import { getSetting } from "metabase/selectors/settings";
diff --git a/frontend/src/metabase/admin/datamodel/containers/DataModelApp/DataModelApp.jsx b/frontend/src/metabase/admin/datamodel/containers/DataModelApp/DataModelApp.jsx
index a9dec95e402..b406429fc28 100644
--- a/frontend/src/metabase/admin/datamodel/containers/DataModelApp/DataModelApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/DataModelApp/DataModelApp.jsx
@@ -1,11 +1,11 @@
 import PropTypes from "prop-types";
 import { Fragment, useMemo } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import Radio from "metabase/core/components/Radio";
 import { useToggle } from "metabase/hooks/use-toggle";
+import { connect } from "metabase/lib/redux";
 import { getUserIsAdmin } from "metabase/selectors/user";
 
 import { ModelEducationButton, NavBar } from "./DataModelApp.styled";
diff --git a/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx b/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx
index 6e5a0aa5208..356c0276c7a 100644
--- a/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx
@@ -1,10 +1,10 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Segments from "metabase/entities/segments";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 
 import RevisionHistory from "../components/revisions/RevisionHistory";
 import { fetchSegmentRevisions } from "../datamodel";
diff --git a/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx b/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
index d423b295b1c..9c179c949be 100644
--- a/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
@@ -1,6 +1,5 @@
 /* eslint-disable react/prop-types */
 import { useCallback, useState } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
@@ -8,6 +7,7 @@ import { LeaveConfirmationModal } from "metabase/components/LeaveConfirmationMod
 import Segments from "metabase/entities/segments";
 import Tables from "metabase/entities/tables";
 import { useCallbackEffect } from "metabase/hooks/use-callback-effect";
+import { connect } from "metabase/lib/redux";
 
 import SegmentForm from "../components/SegmentForm";
 import { updatePreviewSummary } from "../datamodel";
diff --git a/frontend/src/metabase/admin/datamodel/containers/SegmentListApp.jsx b/frontend/src/metabase/admin/datamodel/containers/SegmentListApp.jsx
index 8bf23d5b3f0..c42a0a7914d 100644
--- a/frontend/src/metabase/admin/datamodel/containers/SegmentListApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/SegmentListApp.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -12,6 +11,7 @@ import Link from "metabase/core/components/Link";
 import AdminS from "metabase/css/admin.module.css";
 import CS from "metabase/css/core/index.css";
 import Segments from "metabase/entities/segments";
+import { connect } from "metabase/lib/redux";
 
 class SegmentListAppInner extends Component {
   render() {
diff --git a/frontend/src/metabase/admin/datamodel/hoc/FilteredToUrlTable.jsx b/frontend/src/metabase/admin/datamodel/hoc/FilteredToUrlTable.jsx
index e355c8b8e66..14b41028c62 100644
--- a/frontend/src/metabase/admin/datamodel/hoc/FilteredToUrlTable.jsx
+++ b/frontend/src/metabase/admin/datamodel/hoc/FilteredToUrlTable.jsx
@@ -1,13 +1,13 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import { FieldSet } from "metabase/components/FieldSet";
 import CS from "metabase/css/core/index.css";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import { DatabaseSchemaAndTableDataSelector } from "metabase/query_builder/components/DataSelector";
 import { Icon } from "metabase/ui";
 
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/FieldFormattingSettings/FieldFormattingSettings.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/FieldFormattingSettings/FieldFormattingSettings.tsx
index 649696dbc3a..65b0d7ec583 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/FieldFormattingSettings/FieldFormattingSettings.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/FieldFormattingSettings/FieldFormattingSettings.tsx
@@ -1,7 +1,7 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 
 import Fields from "metabase/entities/fields";
+import { connect } from "metabase/lib/redux";
 import ColumnSettings from "metabase/visualizations/components/ColumnSettings";
 import { getGlobalSettingsForColumn } from "metabase/visualizations/lib/settings/column";
 import type Field from "metabase-lib/v1/metadata/Field";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/FieldGeneralSettings/FieldGeneralSettings.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/FieldGeneralSettings/FieldGeneralSettings.tsx
index 61995bcdd4d..3085c94c7f3 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/FieldGeneralSettings/FieldGeneralSettings.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/FieldGeneralSettings/FieldGeneralSettings.tsx
@@ -1,6 +1,5 @@
 import cx from "classnames";
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { humanizeCoercionStrategy } from "metabase/admin/datamodel/utils/humanizeCoercionStrategy";
@@ -16,6 +15,7 @@ import ButtonsS from "metabase/css/components/buttons.module.css";
 import CS from "metabase/css/core/index.css";
 import Fields from "metabase/entities/fields";
 import * as MetabaseCore from "metabase/lib/core";
+import { connect } from "metabase/lib/redux";
 import type Field from "metabase-lib/v1/metadata/Field";
 import type Table from "metabase-lib/v1/metadata/Table";
 import type { FieldValuesType } from "metabase-types/api";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/FieldRemappingSettings/FieldRemappingSettings.jsx b/frontend/src/metabase/admin/datamodel/metadata/components/FieldRemappingSettings/FieldRemappingSettings.jsx
index 5bf4ba86f6e..49ff9c87f15 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/FieldRemappingSettings/FieldRemappingSettings.jsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/FieldRemappingSettings/FieldRemappingSettings.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component, createRef } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -9,6 +8,7 @@ import ButtonWithStatus from "metabase/components/ButtonWithStatus";
 import Select from "metabase/core/components/Select";
 import CS from "metabase/css/core/index.css";
 import Fields from "metabase/entities/fields";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
 import { FieldDataSelector } from "metabase/query_builder/components/DataSelector";
 import { getMetadataUnfiltered } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataFieldSettings/MetadataFieldSettings.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataFieldSettings/MetadataFieldSettings.tsx
index 797b16f3ddf..b9d2fef2216 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataFieldSettings/MetadataFieldSettings.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataFieldSettings/MetadataFieldSettings.tsx
@@ -1,5 +1,4 @@
 import cx from "classnames";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -12,6 +11,7 @@ import Databases from "metabase/entities/databases";
 import Fields from "metabase/entities/fields";
 import Schemas from "metabase/entities/schemas";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
 import type Database from "metabase-lib/v1/metadata/Database";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataHeader/MetadataHeader.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataHeader/MetadataHeader.tsx
index 4f197d68c7f..b7e99b39ca2 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataHeader/MetadataHeader.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataHeader/MetadataHeader.tsx
@@ -1,12 +1,12 @@
 import cx from "classnames";
 import { useLayoutEffect } from "react";
-import { connect } from "react-redux";
 import { push, replace } from "react-router-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
 import CS from "metabase/css/core/index.css";
 import Databases from "metabase/entities/databases";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
 import { DatabaseDataSelector } from "metabase/query_builder/components/DataSelector";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataSchemaList/MetadataSchemaList.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataSchemaList/MetadataSchemaList.tsx
index 20c6a462cb0..3292504bb47 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataSchemaList/MetadataSchemaList.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataSchemaList/MetadataSchemaList.tsx
@@ -1,6 +1,5 @@
 import cx from "classnames";
 import { useCallback, useLayoutEffect, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import { push, replace } from "react-router-redux";
 import { msgid, ngettext, t } from "ttag";
 import _ from "underscore";
@@ -8,6 +7,7 @@ import _ from "underscore";
 import AdminS from "metabase/css/admin.module.css";
 import CS from "metabase/css/core/index.css";
 import Schemas from "metabase/entities/schemas";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
 import { Icon } from "metabase/ui";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTable/MetadataTable.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTable/MetadataTable.tsx
index c4f40298114..ef23b37b301 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTable/MetadataTable.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTable/MetadataTable.tsx
@@ -1,7 +1,6 @@
 import cx from "classnames";
 import type { ReactNode } from "react";
 import { useCallback, useState } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -10,6 +9,7 @@ import AdminS from "metabase/css/admin.module.css";
 import CS from "metabase/css/core/index.css";
 import Databases from "metabase/entities/databases";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
 import type Field from "metabase-lib/v1/metadata/Field";
 import type Table from "metabase-lib/v1/metadata/Table";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumn/MetadataTableColumn.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumn/MetadataTableColumn.tsx
index 8babf714a3a..9be039ea968 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumn/MetadataTableColumn.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumn/MetadataTableColumn.tsx
@@ -1,13 +1,13 @@
 import cx from "classnames";
 import type { ReactNode } from "react";
 import { useCallback } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import Button from "metabase/core/components/Button/Button";
 import AdminS from "metabase/css/admin.module.css";
 import CS from "metabase/css/core/index.css";
 import Fields from "metabase/entities/fields";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import type Field from "metabase-lib/v1/metadata/Field";
 import type { DatabaseId, SchemaId, TableId } from "metabase-types/api";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumnList/MetadataTableColumnList.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumnList/MetadataTableColumnList.tsx
index bf138fa5b82..e25aaab5593 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumnList/MetadataTableColumnList.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableColumnList/MetadataTableColumnList.tsx
@@ -4,7 +4,6 @@ import { useSortable } from "@dnd-kit/sortable";
 import { CSS } from "@dnd-kit/utilities";
 import cx from "classnames";
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -15,6 +14,7 @@ import type { DragEndEvent } from "metabase/core/components/Sortable";
 import { SortableList } from "metabase/core/components/Sortable";
 import CS from "metabase/css/core/index.css";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import { Icon } from "metabase/ui";
 import type Field from "metabase-lib/v1/metadata/Field";
 import type Table from "metabase-lib/v1/metadata/Table";
diff --git a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableList/MetadataTableList.tsx b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableList/MetadataTableList.tsx
index 97f48877187..75108872d6e 100644
--- a/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableList/MetadataTableList.tsx
+++ b/frontend/src/metabase/admin/datamodel/metadata/components/MetadataTableList/MetadataTableList.tsx
@@ -1,7 +1,6 @@
 import cx from "classnames";
 import type { ChangeEvent, MouseEvent } from "react";
 import { useCallback, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { useAsyncFn } from "react-use";
 import { msgid, ngettext, t } from "ttag";
@@ -11,6 +10,7 @@ import Tooltip from "metabase/core/components/Tooltip";
 import AdminS from "metabase/css/admin.module.css";
 import CS from "metabase/css/core/index.css";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import { isSyncCompleted, isSyncInProgress } from "metabase/lib/syncing";
 import * as Urls from "metabase/lib/urls";
 import { PLUGIN_FEATURE_LEVEL_PERMISSIONS } from "metabase/plugins";
diff --git a/frontend/src/metabase/admin/people/components/GroupDetail.jsx b/frontend/src/metabase/admin/people/components/GroupDetail.jsx
index 03301362398..916f1d5c63b 100644
--- a/frontend/src/metabase/admin/people/components/GroupDetail.jsx
+++ b/frontend/src/metabase/admin/people/components/GroupDetail.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Fragment, useEffect, useState } from "react";
-import { connect } from "react-redux";
 import { msgid, ngettext, t } from "ttag";
 
 import { AdminPaneLayout } from "metabase/components/AdminPaneLayout";
@@ -14,6 +13,7 @@ import {
   isAdminGroup,
   isDefaultGroup,
 } from "metabase/lib/groups";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_GROUP_MANAGERS } from "metabase/plugins";
 import { getUser } from "metabase/selectors/user";
 
diff --git a/frontend/src/metabase/admin/people/components/PeopleList.jsx b/frontend/src/metabase/admin/people/components/PeopleList.jsx
index c165f7f2e7c..2b04c9dabbb 100644
--- a/frontend/src/metabase/admin/people/components/PeopleList.jsx
+++ b/frontend/src/metabase/admin/people/components/PeopleList.jsx
@@ -1,7 +1,6 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Fragment, useEffect } from "react";
-import { connect } from "react-redux";
 import { usePrevious } from "react-use";
 import { msgid, ngettext, t } from "ttag";
 import _ from "underscore";
@@ -12,6 +11,7 @@ import CS from "metabase/css/core/index.css";
 import Group from "metabase/entities/groups";
 import Users from "metabase/entities/users";
 import { useConfirmation } from "metabase/hooks/use-confirmation";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_GROUP_MANAGERS } from "metabase/plugins";
 import { getUser, getUserIsAdmin } from "metabase/selectors/user";
 import { Icon } from "metabase/ui";
diff --git a/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx b/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx
index 2a8f923bd64..d331091fb58 100644
--- a/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx
+++ b/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx
@@ -1,8 +1,8 @@
 import { Component } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Group from "metabase/entities/groups";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_GROUP_MANAGERS } from "metabase/plugins";
 import { getUserIsAdmin } from "metabase/selectors/user";
 
diff --git a/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx b/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
index b88823efdb4..331bedab776 100644
--- a/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
+++ b/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
@@ -1,10 +1,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { AdminPaneLayout } from "metabase/components/AdminPaneLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { getUserIsAdmin } from "metabase/selectors/user";
 import { Group, Radio } from "metabase/ui";
diff --git a/frontend/src/metabase/admin/people/containers/UserActivationModal.jsx b/frontend/src/metabase/admin/people/containers/UserActivationModal.jsx
index 48fa9d69343..801211bafd9 100644
--- a/frontend/src/metabase/admin/people/containers/UserActivationModal.jsx
+++ b/frontend/src/metabase/admin/people/containers/UserActivationModal.jsx
@@ -1,6 +1,5 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -9,6 +8,7 @@ import Text from "metabase/components/type/Text";
 import Button from "metabase/core/components/Button";
 import CS from "metabase/css/core/index.css";
 import Users from "metabase/entities/users";
+import { connect } from "metabase/lib/redux";
 
 // NOTE: we have to load the list of users because /api/user/:id doesn't return deactivated users
 // but that's ok because it's probably already loaded through the people PeopleListingApp
diff --git a/frontend/src/metabase/admin/people/containers/UserPasswordResetModal.jsx b/frontend/src/metabase/admin/people/containers/UserPasswordResetModal.jsx
index a936f01067e..b56223043c8 100644
--- a/frontend/src/metabase/admin/people/containers/UserPasswordResetModal.jsx
+++ b/frontend/src/metabase/admin/people/containers/UserPasswordResetModal.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { goBack } from "react-router-redux";
 import { t } from "ttag";
 import _ from "underscore";
@@ -11,6 +10,7 @@ import PasswordReveal from "metabase/components/PasswordReveal";
 import Button from "metabase/core/components/Button";
 import CS from "metabase/css/core/index.css";
 import Users from "metabase/entities/users";
+import { connect } from "metabase/lib/redux";
 import MetabaseSettings from "metabase/lib/settings";
 
 import { clearTemporaryPassword } from "../people";
diff --git a/frontend/src/metabase/admin/people/containers/UserSuccessModal.jsx b/frontend/src/metabase/admin/people/containers/UserSuccessModal.jsx
index bad2bca70b1..72989d520eb 100644
--- a/frontend/src/metabase/admin/people/containers/UserSuccessModal.jsx
+++ b/frontend/src/metabase/admin/people/containers/UserSuccessModal.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { jt, t } from "ttag";
 import _ from "underscore";
@@ -12,6 +11,7 @@ import Button from "metabase/core/components/Button";
 import Link from "metabase/core/components/Link";
 import CS from "metabase/css/core/index.css";
 import Users from "metabase/entities/users";
+import { connect } from "metabase/lib/redux";
 import { getSetting, isSsoEnabled } from "metabase/selectors/settings";
 
 import { clearTemporaryPassword } from "../people";
diff --git a/frontend/src/metabase/admin/permissions/components/CollectionPermissionsModal/CollectionPermissionsModal.jsx b/frontend/src/metabase/admin/permissions/components/CollectionPermissionsModal/CollectionPermissionsModal.jsx
index 36f6560cb3e..12f4382d640 100644
--- a/frontend/src/metabase/admin/permissions/components/CollectionPermissionsModal/CollectionPermissionsModal.jsx
+++ b/frontend/src/metabase/admin/permissions/components/CollectionPermissionsModal/CollectionPermissionsModal.jsx
@@ -1,6 +1,5 @@
 import PropTypes from "prop-types";
 import { useCallback, useEffect } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -11,6 +10,7 @@ import Link from "metabase/core/components/Link";
 import CS from "metabase/css/core/index.css";
 import Collections from "metabase/entities/collections";
 import Groups from "metabase/entities/groups";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 
 import {
diff --git a/frontend/src/metabase/admin/permissions/components/ToolbarUpsell/ToolbarUpsell.tsx b/frontend/src/metabase/admin/permissions/components/ToolbarUpsell/ToolbarUpsell.tsx
index a5cca4d3b1a..bb72d74b673 100644
--- a/frontend/src/metabase/admin/permissions/components/ToolbarUpsell/ToolbarUpsell.tsx
+++ b/frontend/src/metabase/admin/permissions/components/ToolbarUpsell/ToolbarUpsell.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { jt, t } from "ttag";
 
 import { useDocsUrl } from "metabase/common/hooks";
 import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
 import ExternalLink from "metabase/core/components/ExternalLink";
+import { connect } from "metabase/lib/redux";
 import { getUpgradeUrl } from "metabase/selectors/settings";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/admin/permissions/pages/CollectionPermissionsPage/CollectionPermissionsPage.tsx b/frontend/src/metabase/admin/permissions/pages/CollectionPermissionsPage/CollectionPermissionsPage.tsx
index 87fd5c269e2..bb60541ca22 100644
--- a/frontend/src/metabase/admin/permissions/pages/CollectionPermissionsPage/CollectionPermissionsPage.tsx
+++ b/frontend/src/metabase/admin/permissions/pages/CollectionPermissionsPage/CollectionPermissionsPage.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useEffect } from "react";
-import { connect } from "react-redux";
 import type { Route } from "react-router";
 import { push } from "react-router-redux";
 import { t } from "ttag";
@@ -8,6 +7,7 @@ import _ from "underscore";
 import { CollectionPermissionsHelp } from "metabase/admin/permissions/components/CollectionPermissionsHelp";
 import Collections from "metabase/entities/collections";
 import Groups from "metabase/entities/groups";
+import { connect } from "metabase/lib/redux";
 import type { Collection, CollectionId, GroupId } from "metabase-types/api";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/admin/permissions/pages/DatabasePermissionsPage/DatabasesPermissionsPage.jsx b/frontend/src/metabase/admin/permissions/pages/DatabasePermissionsPage/DatabasesPermissionsPage.jsx
index 35054b256e5..6c3b9d47784 100644
--- a/frontend/src/metabase/admin/permissions/pages/DatabasePermissionsPage/DatabasesPermissionsPage.jsx
+++ b/frontend/src/metabase/admin/permissions/pages/DatabasePermissionsPage/DatabasesPermissionsPage.jsx
@@ -1,14 +1,13 @@
 import { bindActionCreators } from "@reduxjs/toolkit";
 import PropTypes from "prop-types";
 import { Fragment, useCallback } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { useAsync } from "react-use";
 import { t } from "ttag";
 import _ from "underscore";
 
 import { PermissionsEditorLegacyNoSelfServiceWarning } from "metabase/admin/permissions/components/PermissionsEditor/PermissionsEditorLegacyWarning";
-import { useDispatch, useSelector } from "metabase/lib/redux";
+import { connect, useDispatch, useSelector } from "metabase/lib/redux";
 import { PLUGIN_ADVANCED_PERMISSIONS } from "metabase/plugins";
 import { getSetting } from "metabase/selectors/settings";
 import { PermissionsApi } from "metabase/services";
diff --git a/frontend/src/metabase/admin/permissions/pages/GroupDataPermissionsPage/GroupsPermissionsPage.jsx b/frontend/src/metabase/admin/permissions/pages/GroupDataPermissionsPage/GroupsPermissionsPage.jsx
index 28a45611863..4737f8669cf 100644
--- a/frontend/src/metabase/admin/permissions/pages/GroupDataPermissionsPage/GroupsPermissionsPage.jsx
+++ b/frontend/src/metabase/admin/permissions/pages/GroupDataPermissionsPage/GroupsPermissionsPage.jsx
@@ -1,14 +1,13 @@
 import { bindActionCreators } from "@reduxjs/toolkit";
 import PropTypes from "prop-types";
 import { Fragment, useCallback } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { useAsync } from "react-use";
 import { t } from "ttag";
 import _ from "underscore";
 
 import { PermissionsEditorLegacyNoSelfServiceWarning } from "metabase/admin/permissions/components/PermissionsEditor/PermissionsEditorLegacyWarning";
-import { useDispatch, useSelector } from "metabase/lib/redux";
+import { connect, useDispatch, useSelector } from "metabase/lib/redux";
 import { PLUGIN_ADVANCED_PERMISSIONS } from "metabase/plugins";
 import { getSetting } from "metabase/selectors/settings";
 import { PermissionsApi } from "metabase/services";
diff --git a/frontend/src/metabase/admin/settings/app/components/SettingsEditor/SettingsEditor.jsx b/frontend/src/metabase/admin/settings/app/components/SettingsEditor/SettingsEditor.jsx
index bb7a94a42c9..3646a202d06 100644
--- a/frontend/src/metabase/admin/settings/app/components/SettingsEditor/SettingsEditor.jsx
+++ b/frontend/src/metabase/admin/settings/app/components/SettingsEditor/SettingsEditor.jsx
@@ -3,7 +3,6 @@ import { bindActionCreators } from "@reduxjs/toolkit";
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component, createRef } from "react";
-import { connect } from "react-redux";
 import { Link } from "react-router";
 import { t } from "ttag";
 import _ from "underscore";
@@ -17,6 +16,7 @@ import SaveStatus from "metabase/components/SaveStatus";
 import AdminS from "metabase/css/admin.module.css";
 import CS from "metabase/css/core/index.css";
 import title from "metabase/hoc/Title";
+import { connect } from "metabase/lib/redux";
 import MetabaseSettings from "metabase/lib/settings";
 import { Box } from "metabase/ui";
 
diff --git a/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthCard/GoogleAuthCard.tsx b/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthCard/GoogleAuthCard.tsx
index a5833f4f93c..d9eb699e36b 100644
--- a/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthCard/GoogleAuthCard.tsx
+++ b/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthCard/GoogleAuthCard.tsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { updateSettings } from "metabase/admin/settings/settings";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { Dispatch, State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthForm/GoogleAuthForm.tsx b/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthForm/GoogleAuthForm.tsx
index 8299c408416..d4260d263b0 100644
--- a/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthForm/GoogleAuthForm.tsx
+++ b/frontend/src/metabase/admin/settings/auth/containers/GoogleAuthForm/GoogleAuthForm.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/admin/settings/auth/containers/LdapAuthCard/LdapAuthCard.tsx b/frontend/src/metabase/admin/settings/auth/containers/LdapAuthCard/LdapAuthCard.tsx
index 4790d2fa00f..a51c970481e 100644
--- a/frontend/src/metabase/admin/settings/auth/containers/LdapAuthCard/LdapAuthCard.tsx
+++ b/frontend/src/metabase/admin/settings/auth/containers/LdapAuthCard/LdapAuthCard.tsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { updateSettings } from "metabase/admin/settings/settings";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { Dispatch, State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/admin/settings/components/SettingsLdapForm.tsx b/frontend/src/metabase/admin/settings/components/SettingsLdapForm.tsx
index d731684709a..bba80e845af 100644
--- a/frontend/src/metabase/admin/settings/components/SettingsLdapForm.tsx
+++ b/frontend/src/metabase/admin/settings/components/SettingsLdapForm.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 import type { TestConfig } from "yup";
@@ -20,6 +19,7 @@ import {
   FormSwitch,
   FormTextInput,
 } from "metabase/forms";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_LDAP_FORM_FIELDS } from "metabase/plugins";
 import { Group, Radio, Stack } from "metabase/ui";
 import type { SettingKey, Settings } from "metabase-types/api";
diff --git a/frontend/src/metabase/admin/settings/components/SettingsLicense/SettingsLicense.tsx b/frontend/src/metabase/admin/settings/components/SettingsLicense/SettingsLicense.tsx
index 6bdcd95eafe..96122e29a04 100644
--- a/frontend/src/metabase/admin/settings/components/SettingsLicense/SettingsLicense.tsx
+++ b/frontend/src/metabase/admin/settings/components/SettingsLicense/SettingsLicense.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import Button from "metabase/core/components/Button";
 import ExternalLink from "metabase/core/components/ExternalLink";
+import { connect } from "metabase/lib/redux";
 import { getUpgradeUrl } from "metabase/selectors/settings";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/admin/settings/components/UploadSettings/UploadSettingsForm.tsx b/frontend/src/metabase/admin/settings/components/UploadSettings/UploadSettingsForm.tsx
index 35b19b0a1ec..0e6d5462030 100644
--- a/frontend/src/metabase/admin/settings/components/UploadSettings/UploadSettingsForm.tsx
+++ b/frontend/src/metabase/admin/settings/components/UploadSettings/UploadSettingsForm.tsx
@@ -1,6 +1,5 @@
 import type * as React from "react";
 import { useRef, useState } from "react";
-import { connect } from "react-redux";
 import { jt, t } from "ttag";
 import _ from "underscore";
 
@@ -15,7 +14,7 @@ import Select from "metabase/core/components/Select";
 import CS from "metabase/css/core/index.css";
 import Databases from "metabase/entities/databases";
 import Schemas from "metabase/entities/schemas";
-import { useDispatch } from "metabase/lib/redux";
+import { connect, useDispatch } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import { Group, Stack, Text } from "metabase/ui";
 import type Database from "metabase-lib/v1/metadata/Database";
diff --git a/frontend/src/metabase/admin/settings/components/widgets/RedirectWidget/RedirectWidget.tsx b/frontend/src/metabase/admin/settings/components/widgets/RedirectWidget/RedirectWidget.tsx
index 80740177819..d9a1acbb731 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/RedirectWidget/RedirectWidget.tsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/RedirectWidget/RedirectWidget.tsx
@@ -1,8 +1,9 @@
 import { useEffect } from "react";
-import { connect } from "react-redux";
 import type { LocationAction } from "react-router-redux";
 import { replace } from "react-router-redux";
 
+import { connect } from "metabase/lib/redux";
+
 interface RedirectWidgetProps {
   to: string;
   replace: LocationAction;
diff --git a/frontend/src/metabase/admin/settings/containers/GroupMappingsWidget.tsx b/frontend/src/metabase/admin/settings/containers/GroupMappingsWidget.tsx
index c08f573d459..e8600615ffc 100644
--- a/frontend/src/metabase/admin/settings/containers/GroupMappingsWidget.tsx
+++ b/frontend/src/metabase/admin/settings/containers/GroupMappingsWidget.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import GroupMappingsWidget from "metabase/admin/settings/components/widgets/GroupMappingsWidget/GroupMappingsWidget";
 import { updateSetting } from "metabase/admin/settings/settings";
 import Group from "metabase/entities/groups";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { Settings } from "metabase-types/api/settings";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/admin/settings/containers/RedirectToAllowedSettings.jsx b/frontend/src/metabase/admin/settings/containers/RedirectToAllowedSettings.jsx
index a0085448c19..b26edf5058f 100644
--- a/frontend/src/metabase/admin/settings/containers/RedirectToAllowedSettings.jsx
+++ b/frontend/src/metabase/admin/settings/containers/RedirectToAllowedSettings.jsx
@@ -1,8 +1,8 @@
 /* eslint-disable react/prop-types */
-import { connect } from "react-redux";
 import { push, replace } from "react-router-redux";
 
 import { getAdminPaths } from "metabase/admin/app/selectors";
+import { connect } from "metabase/lib/redux";
 
 const mapStateToProps = (state, props) => ({
   adminItems: getAdminPaths(state),
diff --git a/frontend/src/metabase/admin/settings/setup/components/SetupCheckList/SetupCheckList.jsx b/frontend/src/metabase/admin/settings/setup/components/SetupCheckList/SetupCheckList.jsx
index e6d548ee0d8..76140005453 100644
--- a/frontend/src/metabase/admin/settings/setup/components/SetupCheckList/SetupCheckList.jsx
+++ b/frontend/src/metabase/admin/settings/setup/components/SetupCheckList/SetupCheckList.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { UpsellHosting } from "metabase/admin/upsells";
@@ -9,6 +8,7 @@ import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
 import { color } from "metabase/lib/colors";
 import { isSameOrSiteUrlOrigin } from "metabase/lib/dom";
+import { connect } from "metabase/lib/redux";
 import { getIsPaidPlan } from "metabase/selectors/settings";
 import { SetupApi } from "metabase/services";
 import { Box, Flex, Icon } from "metabase/ui";
diff --git a/frontend/src/metabase/admin/settings/slack/containers/SlackSettings/SlackSettings.tsx b/frontend/src/metabase/admin/settings/slack/containers/SlackSettings/SlackSettings.tsx
index c5ab240c364..2416706ae58 100644
--- a/frontend/src/metabase/admin/settings/slack/containers/SlackSettings/SlackSettings.tsx
+++ b/frontend/src/metabase/admin/settings/slack/containers/SlackSettings/SlackSettings.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import type { State } from "metabase-types/store";
 
 import { loadManifest } from "../../actions";
diff --git a/frontend/src/metabase/admin/settings/slack/containers/SlackSetup/SlackSetup.tsx b/frontend/src/metabase/admin/settings/slack/containers/SlackSetup/SlackSetup.tsx
index 4b3d1219e91..fa51547e57f 100644
--- a/frontend/src/metabase/admin/settings/slack/containers/SlackSetup/SlackSetup.tsx
+++ b/frontend/src/metabase/admin/settings/slack/containers/SlackSetup/SlackSetup.tsx
@@ -1,6 +1,6 @@
 import type { ComponentType } from "react";
-import { connect } from "react-redux";
 
+import { connect } from "metabase/lib/redux";
 import type { State } from "metabase-types/store";
 
 import SlackSetup from "../../components/SlackSetup";
diff --git a/frontend/src/metabase/admin/settings/slack/containers/SlackSetupForm/SlackSetupForm.tsx b/frontend/src/metabase/admin/settings/slack/containers/SlackSetupForm/SlackSetupForm.tsx
index 05502880e1b..74c083a9643 100644
--- a/frontend/src/metabase/admin/settings/slack/containers/SlackSetupForm/SlackSetupForm.tsx
+++ b/frontend/src/metabase/admin/settings/slack/containers/SlackSetupForm/SlackSetupForm.tsx
@@ -1,4 +1,4 @@
-import { connect } from "react-redux";
+import { connect } from "metabase/lib/redux";
 
 import { updateSettings } from "../../actions";
 import SlackSetupForm from "../../components/SlackSetupForm";
diff --git a/frontend/src/metabase/admin/settings/slack/containers/SlackStatus/SlackStatus.tsx b/frontend/src/metabase/admin/settings/slack/containers/SlackStatus/SlackStatus.tsx
index 7f68d5c0c8a..5b82e8dbf40 100644
--- a/frontend/src/metabase/admin/settings/slack/containers/SlackStatus/SlackStatus.tsx
+++ b/frontend/src/metabase/admin/settings/slack/containers/SlackStatus/SlackStatus.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import type { State } from "metabase-types/store";
 
 import { updateSettings } from "../../actions";
diff --git a/frontend/src/metabase/admin/settings/slack/containers/SlackStatusForm/SlackStatusForm.tsx b/frontend/src/metabase/admin/settings/slack/containers/SlackStatusForm/SlackStatusForm.tsx
index 5727cc60f87..76d8a3b167a 100644
--- a/frontend/src/metabase/admin/settings/slack/containers/SlackStatusForm/SlackStatusForm.tsx
+++ b/frontend/src/metabase/admin/settings/slack/containers/SlackStatusForm/SlackStatusForm.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import type { State } from "metabase-types/store";
 
 import SlackStatusForm from "../../components/SlackStatusForm";
diff --git a/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobModal.tsx b/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobModal.tsx
index a4298bc5bcb..14106e60fe8 100644
--- a/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobModal.tsx
+++ b/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobModal.tsx
@@ -1,5 +1,4 @@
 import { useEffect, useMemo } from "react";
-import { connect } from "react-redux";
 import { usePrevious } from "react-use";
 import { t } from "ttag";
 import _ from "underscore";
@@ -9,6 +8,7 @@ import Button from "metabase/core/components/Button";
 import Link from "metabase/core/components/Link";
 import ButtonsS from "metabase/css/components/buttons.module.css";
 import PersistedModels from "metabase/entities/persisted-models";
+import { connect } from "metabase/lib/redux";
 import type { ModelCacheRefreshStatus } from "metabase-types/api";
 
 import { ErrorBox } from "./ModelCacheRefreshJobs.styled";
diff --git a/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobs.tsx b/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobs.tsx
index 6422b507faf..8c70e90730a 100644
--- a/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobs.tsx
+++ b/frontend/src/metabase/admin/tasks/containers/ModelCacheRefreshJobs/ModelCacheRefreshJobs.tsx
@@ -1,7 +1,6 @@
 import cx from "classnames";
 import moment from "moment-timezone"; // eslint-disable-line no-restricted-imports -- deprecated usage
 import { useCallback } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import NoResults from "assets/img/no_results.svg";
@@ -15,6 +14,7 @@ import CS from "metabase/css/core/index.css";
 import PersistedModels from "metabase/entities/persisted-models";
 import { usePagination } from "metabase/hooks/use-pagination";
 import { capitalize } from "metabase/lib/formatting";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { Icon } from "metabase/ui";
 import { checkCanRefreshModelCache } from "metabase-lib/v1/metadata/utils/models";
diff --git a/frontend/src/metabase/admin/tools/containers/Tools.tsx b/frontend/src/metabase/admin/tools/containers/Tools.tsx
index 7dfad435f0b..7e9dd78bd67 100644
--- a/frontend/src/metabase/admin/tools/containers/Tools.tsx
+++ b/frontend/src/metabase/admin/tools/containers/Tools.tsx
@@ -1,10 +1,10 @@
 import type { Location } from "history";
 import type * as React from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import Radio from "metabase/core/components/Radio";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_ADMIN_TOOLS } from "metabase/plugins";
 import { getSetting } from "metabase/selectors/settings";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/admin/utils.js b/frontend/src/metabase/admin/utils.js
index ef045a37408..757febff180 100644
--- a/frontend/src/metabase/admin/utils.js
+++ b/frontend/src/metabase/admin/utils.js
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { replace, routerActions } from "react-router-redux";
 import { connectedReduxRedirect } from "redux-auth-wrapper/history3/redirect";
 
 import { getAdminPaths } from "metabase/admin/app/selectors";
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 export const createAdminRouteGuard = (routeKey, Component) => {
diff --git a/frontend/src/metabase/api/api.ts b/frontend/src/metabase/api/api.ts
index a888f8004e3..61d02831c09 100644
--- a/frontend/src/metabase/api/api.ts
+++ b/frontend/src/metabase/api/api.ts
@@ -1,12 +1,36 @@
-import { createApi, skipToken } from "@reduxjs/toolkit/query/react";
-export { skipToken };
+import {
+  buildCreateApi,
+  coreModule,
+  reactHooksModule,
+  skipToken,
+} from "@reduxjs/toolkit/query/react";
+import {
+  createDispatchHook,
+  createSelectorHook,
+  createStoreHook,
+} from "react-redux";
+
+import { MetabaseReduxContext } from "metabase/lib/redux";
 
 import { apiQuery } from "./query";
 import { TAG_TYPES } from "./tags";
 
+const createApi = buildCreateApi(
+  coreModule(),
+  reactHooksModule({
+    hooks: {
+      useDispatch: createDispatchHook(MetabaseReduxContext),
+      useSelector: createSelectorHook(MetabaseReduxContext),
+      useStore: createStoreHook(MetabaseReduxContext),
+    },
+  }),
+);
+
 export const Api = createApi({
   reducerPath: "metabase-api",
   tagTypes: TAG_TYPES,
   baseQuery: apiQuery,
   endpoints: () => ({}),
 });
+
+export { skipToken };
diff --git a/frontend/src/metabase/app.js b/frontend/src/metabase/app.js
index 568b3784245..f4d240af26b 100644
--- a/frontend/src/metabase/app.js
+++ b/frontend/src/metabase/app.js
@@ -31,7 +31,6 @@ import { createHistory } from "history";
 import { DragDropContextProvider } from "react-dnd";
 import HTML5Backend from "react-dnd-html5-backend";
 import { createRoot } from "react-dom/client";
-import { Provider } from "react-redux";
 import { Router, useRouterHistory } from "react-router";
 import { syncHistoryWithStore } from "react-router-redux";
 
@@ -39,6 +38,7 @@ import { createTracker } from "metabase/lib/analytics";
 import api from "metabase/lib/api";
 import { initializeEmbedding } from "metabase/lib/embed";
 import { captureConsoleErrors } from "metabase/lib/errors";
+import { MetabaseReduxProvider } from "metabase/lib/redux/custom-context";
 import MetabaseSettings from "metabase/lib/settings";
 import { PLUGIN_APP_INIT_FUNCTIONS } from "metabase/plugins";
 import { refreshSiteSettings } from "metabase/redux/settings";
@@ -71,7 +71,7 @@ function _init(reducers, getRoutes, callback) {
   const root = createRoot(document.getElementById("root"));
 
   root.render(
-    <Provider store={store}>
+    <MetabaseReduxProvider store={store}>
       <EmotionCacheProvider>
         <DragDropContextProvider backend={HTML5Backend} context={{ window }}>
           <ThemeProvider>
@@ -80,7 +80,7 @@ function _init(reducers, getRoutes, callback) {
           </ThemeProvider>
         </DragDropContextProvider>
       </EmotionCacheProvider>
-    </Provider>,
+    </MetabaseReduxProvider>,
   );
 
   registerVisualizations();
diff --git a/frontend/src/metabase/browse/containers/TableBrowser/TableBrowser.jsx b/frontend/src/metabase/browse/containers/TableBrowser/TableBrowser.jsx
index 37ea6879b89..fc1d24ae57f 100644
--- a/frontend/src/metabase/browse/containers/TableBrowser/TableBrowser.jsx
+++ b/frontend/src/metabase/browse/containers/TableBrowser/TableBrowser.jsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import { isSyncInProgress } from "metabase/lib/syncing";
 import * as Urls from "metabase/lib/urls";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/collections/components/ActionMenu/ActionMenu.tsx b/frontend/src/metabase/collections/components/ActionMenu/ActionMenu.tsx
index 67a20666943..4206bfd957f 100644
--- a/frontend/src/metabase/collections/components/ActionMenu/ActionMenu.tsx
+++ b/frontend/src/metabase/collections/components/ActionMenu/ActionMenu.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
@@ -21,7 +20,7 @@ import {
 } from "metabase/collections/utils";
 import { ConfirmDeleteModal } from "metabase/components/ConfirmDeleteModal";
 import { bookmarks as BookmarkEntity } from "metabase/entities";
-import { useDispatch } from "metabase/lib/redux";
+import { connect, useDispatch } from "metabase/lib/redux";
 import { entityForObject } from "metabase/lib/schema";
 import * as Urls from "metabase/lib/urls";
 import { addUndo } from "metabase/redux/undo";
diff --git a/frontend/src/metabase/collections/components/CollectionCopyEntityModal.tsx b/frontend/src/metabase/collections/components/CollectionCopyEntityModal.tsx
index ed999397e6e..61905927118 100644
--- a/frontend/src/metabase/collections/components/CollectionCopyEntityModal.tsx
+++ b/frontend/src/metabase/collections/components/CollectionCopyEntityModal.tsx
@@ -1,11 +1,11 @@
 import { dissoc } from "icepick";
 import { useState } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import Collections from "metabase/entities/collections";
 import EntityCopyModal from "metabase/entities/containers/EntityCopyModal";
 import withToast from "metabase/hoc/Toast";
+import { connect } from "metabase/lib/redux";
 import { entityTypeForObject } from "metabase/lib/schema";
 
 function mapStateToProps(state: any, props: any) {
diff --git a/frontend/src/metabase/collections/components/CreateCollectionForm/CreateCollectionForm.tsx b/frontend/src/metabase/collections/components/CreateCollectionForm/CreateCollectionForm.tsx
index 35dd389d02e..3b1046f474f 100644
--- a/frontend/src/metabase/collections/components/CreateCollectionForm/CreateCollectionForm.tsx
+++ b/frontend/src/metabase/collections/components/CreateCollectionForm/CreateCollectionForm.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { withRouter } from "react-router";
 import { t } from "ttag";
 import _ from "underscore";
@@ -19,6 +18,7 @@ import Collections, {
 import { Form, FormProvider } from "metabase/forms";
 import { color } from "metabase/lib/colors";
 import * as Errors from "metabase/lib/errors";
+import { connect } from "metabase/lib/redux";
 import type { Collection } from "metabase-types/api";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/collections/containers/CollectionHeader/CollectionHeader.tsx b/frontend/src/metabase/collections/containers/CollectionHeader/CollectionHeader.tsx
index 4125269830f..d0a1ee19a44 100644
--- a/frontend/src/metabase/collections/containers/CollectionHeader/CollectionHeader.tsx
+++ b/frontend/src/metabase/collections/containers/CollectionHeader/CollectionHeader.tsx
@@ -1,6 +1,5 @@
-import { connect } from "react-redux";
-
 import Collections from "metabase/entities/collections";
+import { connect } from "metabase/lib/redux";
 import { uploadFile } from "metabase/redux/uploads";
 import type { Collection } from "metabase-types/api";
 
diff --git a/frontend/src/metabase/collections/containers/CreateCollectionModal.tsx b/frontend/src/metabase/collections/containers/CreateCollectionModal.tsx
index bbffd11f3f2..ca421d270c9 100644
--- a/frontend/src/metabase/collections/containers/CreateCollectionModal.tsx
+++ b/frontend/src/metabase/collections/containers/CreateCollectionModal.tsx
@@ -1,9 +1,9 @@
 import type { LocationDescriptor } from "history";
 import { useCallback } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { Modal } from "metabase/ui";
 import type { Collection } from "metabase-types/api";
diff --git a/frontend/src/metabase/components/AdminAwareEmptyState/AdminAwareEmptyState.jsx b/frontend/src/metabase/components/AdminAwareEmptyState/AdminAwareEmptyState.jsx
index 131913f8284..f11655f111a 100644
--- a/frontend/src/metabase/components/AdminAwareEmptyState/AdminAwareEmptyState.jsx
+++ b/frontend/src/metabase/components/AdminAwareEmptyState/AdminAwareEmptyState.jsx
@@ -1,8 +1,8 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import EmptyState from "metabase/components/EmptyState";
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 /*
diff --git a/frontend/src/metabase/components/ArchiveCollectionModal/ArchiveCollectionModal.jsx b/frontend/src/metabase/components/ArchiveCollectionModal/ArchiveCollectionModal.jsx
index f8a6738e10d..39fcfa36589 100644
--- a/frontend/src/metabase/components/ArchiveCollectionModal/ArchiveCollectionModal.jsx
+++ b/frontend/src/metabase/components/ArchiveCollectionModal/ArchiveCollectionModal.jsx
@@ -1,6 +1,5 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 import { withRouter } from "react-router";
 import { push } from "react-router-redux";
 import { t } from "ttag";
@@ -8,6 +7,7 @@ import _ from "underscore";
 
 import { ArchiveModal } from "metabase/components/ArchiveModal";
 import Collection from "metabase/entities/collections";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 
 const mapDispatchToProps = {
diff --git a/frontend/src/metabase/components/CollectionList/CollectionList.jsx b/frontend/src/metabase/components/CollectionList/CollectionList.jsx
index 56be31c2d9f..f1a1be51eb7 100644
--- a/frontend/src/metabase/components/CollectionList/CollectionList.jsx
+++ b/frontend/src/metabase/components/CollectionList/CollectionList.jsx
@@ -1,9 +1,9 @@
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 
 import CollectionItem from "metabase/components/CollectionItem";
 import { CollectionGridItem } from "metabase/components/CollectionList/CollectionList.styled";
 import { Grid } from "metabase/components/Grid";
+import { connect } from "metabase/lib/redux";
 import { getUser } from "metabase/selectors/user";
 
 const propTypes = {
diff --git a/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx b/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx
index cc653198995..5b616afc84b 100644
--- a/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx
+++ b/frontend/src/metabase/components/FieldValuesWidget/FieldValuesWidget.tsx
@@ -9,7 +9,6 @@ import {
   useRef,
   useState,
 } from "react";
-import { connect } from "react-redux";
 import { useMount, usePrevious, useThrottle, useUnmount } from "react-use";
 import { jt, t } from "ttag";
 import _ from "underscore";
@@ -26,7 +25,7 @@ import Fields from "metabase/entities/fields";
 import { formatValue } from "metabase/lib/formatting";
 import { parseNumberValue } from "metabase/lib/number";
 import { defer } from "metabase/lib/promise";
-import { useDispatch } from "metabase/lib/redux";
+import { connect, useDispatch } from "metabase/lib/redux";
 import { isNotNull } from "metabase/lib/types";
 import {
   fetchCardParameterValues,
diff --git a/frontend/src/metabase/components/LastEditInfoLabel/LastEditInfoLabel.tsx b/frontend/src/metabase/components/LastEditInfoLabel/LastEditInfoLabel.tsx
index c141b62e206..4346cfa2a01 100644
--- a/frontend/src/metabase/components/LastEditInfoLabel/LastEditInfoLabel.tsx
+++ b/frontend/src/metabase/components/LastEditInfoLabel/LastEditInfoLabel.tsx
@@ -1,10 +1,10 @@
 import dayjs from "dayjs";
 import type { MouseEventHandler } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { TextButton } from "metabase/components/Button.styled";
 import DateTime from "metabase/components/DateTime";
+import { connect } from "metabase/lib/redux";
 import type { NamedUser } from "metabase/lib/user";
 import { getFullName } from "metabase/lib/user";
 import { getUser } from "metabase/selectors/user";
diff --git a/frontend/src/metabase/components/MetadataInfo/ColumnFingerprintInfo/CategoryFingerprint.jsx b/frontend/src/metabase/components/MetadataInfo/ColumnFingerprintInfo/CategoryFingerprint.jsx
index b4a832df686..ad4e2ead261 100644
--- a/frontend/src/metabase/components/MetadataInfo/ColumnFingerprintInfo/CategoryFingerprint.jsx
+++ b/frontend/src/metabase/components/MetadataInfo/ColumnFingerprintInfo/CategoryFingerprint.jsx
@@ -1,9 +1,9 @@
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { msgid, ngettext, t } from "ttag";
 
 import { useGetFieldValuesQuery } from "metabase/api";
 import { formatNumber } from "metabase/lib/formatting";
+import { connect } from "metabase/lib/redux";
 import { getMetadata } from "metabase/selectors/metadata";
 
 import {
diff --git a/frontend/src/metabase/components/MetadataInfo/TableInfo/TableInfo.tsx b/frontend/src/metabase/components/MetadataInfo/TableInfo/TableInfo.tsx
index a9c6125813f..e00b28984dc 100644
--- a/frontend/src/metabase/components/MetadataInfo/TableInfo/TableInfo.tsx
+++ b/frontend/src/metabase/components/MetadataInfo/TableInfo/TableInfo.tsx
@@ -1,10 +1,10 @@
 import { useEffect, useState } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
 import Tables from "metabase/entities/tables";
 import { useSafeAsyncFunction } from "metabase/hooks/use-safe-async-function";
+import { connect } from "metabase/lib/redux";
 import type Table from "metabase-lib/v1/metadata/Table";
 
 import {
diff --git a/frontend/src/metabase/components/SaveStatus/SaveStatus.jsx b/frontend/src/metabase/components/SaveStatus/SaveStatus.jsx
index b735569e59b..1a10dfae20b 100644
--- a/frontend/src/metabase/components/SaveStatus/SaveStatus.jsx
+++ b/frontend/src/metabase/components/SaveStatus/SaveStatus.jsx
@@ -1,9 +1,9 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
+import { connect } from "metabase/lib/redux";
 import { addUndo, dismissUndo } from "metabase/redux/undo";
 
 class SaveStatus extends Component {
diff --git a/frontend/src/metabase/containers/AdHocQuestionLoader.jsx b/frontend/src/metabase/containers/AdHocQuestionLoader.jsx
index ba7d0fbb063..faec8d37855 100644
--- a/frontend/src/metabase/containers/AdHocQuestionLoader.jsx
+++ b/frontend/src/metabase/containers/AdHocQuestionLoader.jsx
@@ -1,8 +1,8 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import { deserializeCardFromUrl } from "metabase/lib/card";
+import { connect } from "metabase/lib/redux";
 import { loadMetadataForCard } from "metabase/questions/actions";
 import { getMetadata } from "metabase/selectors/metadata";
 import Question from "metabase-lib/v1/Question";
diff --git a/frontend/src/metabase/containers/NewItemMenu/NewItemMenu.tsx b/frontend/src/metabase/containers/NewItemMenu/NewItemMenu.tsx
index 97b47689e57..3aa44ce2d8e 100644
--- a/frontend/src/metabase/containers/NewItemMenu/NewItemMenu.tsx
+++ b/frontend/src/metabase/containers/NewItemMenu/NewItemMenu.tsx
@@ -1,10 +1,10 @@
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
 import NewItemMenu from "metabase/components/NewItemMenu";
 import Databases from "metabase/entities/databases";
 import Search from "metabase/entities/search";
+import { connect } from "metabase/lib/redux";
 import { closeNavbar } from "metabase/redux/app";
 import {
   getHasDataAccess,
diff --git a/frontend/src/metabase/containers/NotFoundFallbackPage.tsx b/frontend/src/metabase/containers/NotFoundFallbackPage.tsx
index 41e0a485ef0..a23e7562238 100644
--- a/frontend/src/metabase/containers/NotFoundFallbackPage.tsx
+++ b/frontend/src/metabase/containers/NotFoundFallbackPage.tsx
@@ -1,8 +1,8 @@
 import type { LocationDescriptor } from "history";
-import { connect } from "react-redux";
 import { replace } from "react-router-redux";
 import { useMount } from "react-use";
 
+import { connect } from "metabase/lib/redux";
 import { refreshCurrentUser } from "metabase/redux/user";
 
 import { NotFound } from "../components/ErrorPages";
diff --git a/frontend/src/metabase/containers/SchedulePicker.tsx b/frontend/src/metabase/containers/SchedulePicker.tsx
index 918d5c38532..320a8b878c0 100644
--- a/frontend/src/metabase/containers/SchedulePicker.tsx
+++ b/frontend/src/metabase/containers/SchedulePicker.tsx
@@ -1,7 +1,6 @@
-import { connect } from "react-redux";
-
 import type { SchedulePickerProps } from "metabase/components/SchedulePicker";
 import SchedulePicker from "metabase/components/SchedulePicker";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/dashboard/components/ActionSidebar/ActionSidebar.tsx b/frontend/src/metabase/dashboard/components/ActionSidebar/ActionSidebar.tsx
index 170603bcf83..a58bdf18f41 100644
--- a/frontend/src/metabase/dashboard/components/ActionSidebar/ActionSidebar.tsx
+++ b/frontend/src/metabase/dashboard/components/ActionSidebar/ActionSidebar.tsx
@@ -1,5 +1,4 @@
 import { useMemo, useRef } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import ActionViz from "metabase/actions/components/ActionViz";
@@ -17,6 +16,7 @@ import FormSelect from "metabase/core/components/FormSelect";
 import { closeSidebar } from "metabase/dashboard/actions";
 import { Sidebar } from "metabase/dashboard/components/Sidebar";
 import { Form, FormProvider } from "metabase/forms";
+import { connect } from "metabase/lib/redux";
 import type {
   ActionDashboardCard,
   Dashboard,
diff --git a/frontend/src/metabase/dashboard/components/ClickMappings.jsx b/frontend/src/metabase/dashboard/components/ClickMappings.jsx
index 0d720a31d9e..a937284c25e 100644
--- a/frontend/src/metabase/dashboard/components/ClickMappings.jsx
+++ b/frontend/src/metabase/dashboard/components/ClickMappings.jsx
@@ -2,7 +2,6 @@
 import cx from "classnames";
 import { assocIn, dissocIn, getIn } from "icepick";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -10,6 +9,7 @@ import Select from "metabase/core/components/Select";
 import CS from "metabase/css/core/index.css";
 import { getParameters } from "metabase/dashboard/selectors";
 import { isPivotGroupColumn } from "metabase/lib/data_grid";
+import { connect } from "metabase/lib/redux";
 import MetabaseSettings from "metabase/lib/settings";
 import { loadMetadataForCard } from "metabase/questions/actions";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ActionSettingsButton/ActionSettingsButton.tsx b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ActionSettingsButton/ActionSettingsButton.tsx
index c7039f2d380..554da217e39 100644
--- a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ActionSettingsButton/ActionSettingsButton.tsx
+++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ActionSettingsButton/ActionSettingsButton.tsx
@@ -1,8 +1,8 @@
 import { useEffect } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { setEditingDashcardId } from "metabase/dashboard/actions";
+import { connect } from "metabase/lib/redux";
 import type { ActionDashboardCard, Dashboard } from "metabase-types/api";
 
 import { DashCardActionButton } from "../DashCardActionButton/DashCardActionButton";
diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapper.tsx b/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapper.tsx
index 2d889e37ae0..8dc7b490e1f 100644
--- a/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapper.tsx
+++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardParameterMapper/DashCardCardParameterMapper.tsx
@@ -1,4 +1,3 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -10,6 +9,7 @@ import {
   getQuestionByCard,
 } from "metabase/dashboard/selectors";
 import { isNativeDashCard, isQuestionDashCard } from "metabase/dashboard/utils";
+import { connect } from "metabase/lib/redux";
 import type { ParameterMappingOption } from "metabase/parameters/utils/mapping-options";
 import { getIsRecentlyAutoConnectedDashcard } from "metabase/redux/undo";
 import { Flex, Icon, Text, Transition } from "metabase/ui";
diff --git a/frontend/src/metabase/dashboard/components/DashboardCopyModal.jsx b/frontend/src/metabase/dashboard/components/DashboardCopyModal.jsx
index 0a2db19ce64..0ff005aa581 100644
--- a/frontend/src/metabase/dashboard/components/DashboardCopyModal.jsx
+++ b/frontend/src/metabase/dashboard/components/DashboardCopyModal.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import { dissoc } from "icepick";
 import { useState } from "react";
-import { connect } from "react-redux";
 import { withRouter } from "react-router";
 import { replace } from "react-router-redux";
 import { t } from "ttag";
@@ -10,6 +9,7 @@ import _ from "underscore";
 import Collections from "metabase/entities/collections";
 import EntityCopyModal from "metabase/entities/containers/EntityCopyModal";
 import Dashboards from "metabase/entities/dashboards";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 
 import { getDashboardComplete } from "../selectors";
diff --git a/frontend/src/metabase/dashboard/components/DashboardGrid.tsx b/frontend/src/metabase/dashboard/components/DashboardGrid.tsx
index ef76b7ab994..afabf129470 100644
--- a/frontend/src/metabase/dashboard/components/DashboardGrid.tsx
+++ b/frontend/src/metabase/dashboard/components/DashboardGrid.tsx
@@ -2,7 +2,6 @@ import cx from "classnames";
 import type { ComponentType } from "react";
 import { Component } from "react";
 import type { ConnectedProps } from "react-redux";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 import _ from "underscore";
@@ -30,6 +29,7 @@ import {
   GRID_WIDTH,
   MIN_ROW_HEIGHT,
 } from "metabase/lib/dashboard_grid";
+import { connect } from "metabase/lib/redux";
 import EmbedFrameS from "metabase/public/components/EmbedFrame/EmbedFrame.module.css";
 import { addUndo } from "metabase/redux/undo";
 import { getVisualizationRaw } from "metabase/visualizations";
diff --git a/frontend/src/metabase/dashboard/components/DashboardMoveModal.tsx b/frontend/src/metabase/dashboard/components/DashboardMoveModal.tsx
index 9b73e12e234..fc64dcfe463 100644
--- a/frontend/src/metabase/dashboard/components/DashboardMoveModal.tsx
+++ b/frontend/src/metabase/dashboard/components/DashboardMoveModal.tsx
@@ -1,4 +1,3 @@
-import { connect } from "react-redux";
 import { c, t } from "ttag";
 import _ from "underscore";
 
@@ -6,6 +5,7 @@ import { MoveModal } from "metabase/containers/MoveModal";
 import Collection, { ROOT_COLLECTION } from "metabase/entities/collections";
 import Dashboards from "metabase/entities/dashboards";
 import { color } from "metabase/lib/colors";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { Icon } from "metabase/ui";
 import type { CollectionId, Dashboard, DashboardId } from "metabase-types/api";
diff --git a/frontend/src/metabase/dashboard/components/QuestionPicker/QuestionPicker.jsx b/frontend/src/metabase/dashboard/components/QuestionPicker/QuestionPicker.jsx
index 11fc712c4fb..1e2d1c995ae 100644
--- a/frontend/src/metabase/dashboard/components/QuestionPicker/QuestionPicker.jsx
+++ b/frontend/src/metabase/dashboard/components/QuestionPicker/QuestionPicker.jsx
@@ -1,6 +1,5 @@
 import PropTypes from "prop-types";
 import { useState } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -14,7 +13,7 @@ import { entityObjectLoader } from "metabase/entities/containers/EntityObjectLoa
 import { useDebouncedValue } from "metabase/hooks/use-debounced-value";
 import { getCrumbs } from "metabase/lib/collections";
 import { SEARCH_DEBOUNCE_DURATION } from "metabase/lib/constants";
-import { useSelector } from "metabase/lib/redux";
+import { connect, useSelector } from "metabase/lib/redux";
 import { PLUGIN_COLLECTIONS } from "metabase/plugins";
 import { Icon } from "metabase/ui";
 
diff --git a/frontend/src/metabase/dashboard/containers/ArchiveDashboardModal.jsx b/frontend/src/metabase/dashboard/containers/ArchiveDashboardModal.jsx
index 20dd994ec5e..4d44add1e93 100644
--- a/frontend/src/metabase/dashboard/containers/ArchiveDashboardModal.jsx
+++ b/frontend/src/metabase/dashboard/containers/ArchiveDashboardModal.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { withRouter } from "react-router";
 import { push } from "react-router-redux";
 import { t } from "ttag";
@@ -11,6 +10,7 @@ import { ArchiveModal } from "metabase/components/ArchiveModal";
 import { setArchivedDashboard } from "metabase/dashboard/actions";
 import Collection from "metabase/entities/collections";
 import Dashboards from "metabase/entities/dashboards";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 
 const mapDispatchToProps = dispatch => ({
diff --git a/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx b/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx
index 2a9b8ee6122..34bc05c4338 100644
--- a/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx
+++ b/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx
@@ -2,7 +2,6 @@
 import cx from "classnames";
 import { dissoc } from "icepick";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -21,6 +20,7 @@ import Dashboards from "metabase/entities/dashboards";
 import title from "metabase/hoc/Title";
 import withToast from "metabase/hoc/Toast";
 import { color } from "metabase/lib/colors";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { ParametersList } from "metabase/parameters/components/ParametersList";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/dashboard/containers/CreateDashboardForm.tsx b/frontend/src/metabase/dashboard/containers/CreateDashboardForm.tsx
index 72d11c6b7c2..5d128e393f9 100644
--- a/frontend/src/metabase/dashboard/containers/CreateDashboardForm.tsx
+++ b/frontend/src/metabase/dashboard/containers/CreateDashboardForm.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 import * as Yup from "yup";
@@ -16,6 +15,7 @@ import Collections from "metabase/entities/collections";
 import Dashboards from "metabase/entities/dashboards";
 import { Form, FormProvider } from "metabase/forms";
 import * as Errors from "metabase/lib/errors";
+import { connect } from "metabase/lib/redux";
 import type { CollectionId, Dashboard } from "metabase-types/api";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/dashboard/containers/CreateDashboardModal.tsx b/frontend/src/metabase/dashboard/containers/CreateDashboardModal.tsx
index faf96939b20..624e326b9ac 100644
--- a/frontend/src/metabase/dashboard/containers/CreateDashboardModal.tsx
+++ b/frontend/src/metabase/dashboard/containers/CreateDashboardModal.tsx
@@ -1,10 +1,10 @@
 import type { LocationDescriptor } from "history";
 import { useCallback } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import ModalContent from "metabase/components/ModalContent";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import type { Dashboard } from "metabase-types/api";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/dashboard/containers/DashboardApp/DashboardApp.tsx b/frontend/src/metabase/dashboard/containers/DashboardApp/DashboardApp.tsx
index bbd88211e90..c0c069f2eb4 100644
--- a/frontend/src/metabase/dashboard/containers/DashboardApp/DashboardApp.tsx
+++ b/frontend/src/metabase/dashboard/containers/DashboardApp/DashboardApp.tsx
@@ -2,7 +2,6 @@ import cx from "classnames";
 import type { ReactNode } from "react";
 import { useCallback, useEffect } from "react";
 import type { ConnectedProps } from "react-redux";
-import { connect } from "react-redux";
 import type { Route, WithRouterProps } from "react-router";
 import { push } from "react-router-redux";
 import { useUnmount } from "react-use";
@@ -24,7 +23,7 @@ import { useLoadingTimer } from "metabase/hooks/use-loading-timer";
 import { useUniqueId } from "metabase/hooks/use-unique-id";
 import { useWebNotification } from "metabase/hooks/use-web-notification";
 import { parseHashOptions } from "metabase/lib/browser";
-import { useDispatch } from "metabase/lib/redux";
+import { connect, useDispatch } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { closeNavbar, setErrorPage } from "metabase/redux/app";
 import { addUndo, dismissUndo } from "metabase/redux/undo";
diff --git a/frontend/src/metabase/dashboard/hoc/DashboardData.jsx b/frontend/src/metabase/dashboard/hoc/DashboardData.jsx
index 427e8379db5..d372ca879fb 100644
--- a/frontend/src/metabase/dashboard/hoc/DashboardData.jsx
+++ b/frontend/src/metabase/dashboard/hoc/DashboardData.jsx
@@ -1,6 +1,5 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
@@ -14,6 +13,7 @@ import {
   getSelectedTabId,
   getSlowCards,
 } from "metabase/dashboard/selectors";
+import { connect } from "metabase/lib/redux";
 import { setErrorPage } from "metabase/redux/app";
 
 const mapStateToProps = (state, props) => {
diff --git a/frontend/src/metabase/entities/containers/EntityListLoader.jsx b/frontend/src/metabase/entities/containers/EntityListLoader.jsx
index 254d89e4836..a437cf6fa41 100644
--- a/frontend/src/metabase/entities/containers/EntityListLoader.jsx
+++ b/frontend/src/metabase/entities/containers/EntityListLoader.jsx
@@ -2,12 +2,12 @@
 import { createSelector } from "@reduxjs/toolkit";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import paginationState from "metabase/hoc/PaginationState";
 import { capitalize } from "metabase/lib/formatting";
+import { connect } from "metabase/lib/redux";
 
 import entityType from "./EntityType";
 
diff --git a/frontend/src/metabase/entities/containers/EntityObjectLoader.jsx b/frontend/src/metabase/entities/containers/EntityObjectLoader.jsx
index bb691eef0b8..2be01b1342a 100644
--- a/frontend/src/metabase/entities/containers/EntityObjectLoader.jsx
+++ b/frontend/src/metabase/entities/containers/EntityObjectLoader.jsx
@@ -1,10 +1,10 @@
 /* eslint-disable react/prop-types */
 import { createSelector } from "@reduxjs/toolkit";
 import { Component } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import { connect } from "metabase/lib/redux";
 
 import entityType from "./EntityType";
 
diff --git a/frontend/src/metabase/entities/containers/EntityType.jsx b/frontend/src/metabase/entities/containers/EntityType.jsx
index 400e8883136..b48b9292618 100644
--- a/frontend/src/metabase/entities/containers/EntityType.jsx
+++ b/frontend/src/metabase/entities/containers/EntityType.jsx
@@ -1,7 +1,8 @@
 /* eslint-disable react/prop-types */
 import { bindActionCreators } from "@reduxjs/toolkit";
 import { Component } from "react";
-import { connect } from "react-redux";
+
+import { connect } from "metabase/lib/redux";
 
 /**
  * @deprecated HOCs are deprecated
diff --git a/frontend/src/metabase/env.ts b/frontend/src/metabase/env.ts
index 40ac3d501db..304aeaa0754 100644
--- a/frontend/src/metabase/env.ts
+++ b/frontend/src/metabase/env.ts
@@ -1,15 +1,45 @@
+const tryOrDefault = <T>(fn: () => T, defaultValue: T): T => {
+  try {
+    return fn();
+  } catch (e) {
+    console.warn(
+      "Error while trying to get env",
+      e,
+      `returning default: ${defaultValue}`,
+    );
+    return defaultValue;
+  }
+};
+
 // @ts-expect-error window.Cypress is not typed
-export const isCypressActive = !!window.Cypress;
+export const isCypressActive = tryOrDefault(() => !!window.Cypress, false);
 
-export const isStorybookActive = !!process.env.STORYBOOK;
+export const isStorybookActive = tryOrDefault(
+  () => !!process.env.STORYBOOK,
+  false,
+);
 
-export const isProduction = process.env.WEBPACK_BUNDLE === "production";
+export const isProduction = tryOrDefault(
+  () => process.env.WEBPACK_BUNDLE === "production",
+  false,
+);
 
-export const isTest = process.env.NODE_ENV === "test";
+export const isTest = tryOrDefault(
+  () => process.env.NODE_ENV === "test",
+  false,
+);
 
-export const shouldLogAnalytics = process.env.MB_LOG_ANALYTICS === "true";
+export const shouldLogAnalytics = tryOrDefault(
+  () => process.env.MB_LOG_ANALYTICS === "true",
+  false,
+);
 
-export const isChartsDebugLoggingEnabled =
-  process.env.MB_LOG_CHARTS_DEBUG === "true";
+export const isChartsDebugLoggingEnabled = tryOrDefault(
+  () => process.env.MB_LOG_CHARTS_DEBUG === "true",
+  false,
+);
 
-export const isEmbeddingSdk = !!process.env.IS_EMBEDDING_SDK;
+export const isEmbeddingSdk = tryOrDefault(
+  () => !!process.env.IS_EMBEDDING_SDK,
+  false,
+);
diff --git a/frontend/src/metabase/hoc/ModalRoute.tsx b/frontend/src/metabase/hoc/ModalRoute.tsx
index 7c7e33b6c3e..185a5231200 100644
--- a/frontend/src/metabase/hoc/ModalRoute.tsx
+++ b/frontend/src/metabase/hoc/ModalRoute.tsx
@@ -1,11 +1,11 @@
 import type { LocationDescriptor } from "history";
 import { Component } from "react";
 import * as React from "react";
-import { connect } from "react-redux";
 import { Route } from "react-router";
 import { push } from "react-router-redux";
 
 import Modal from "metabase/components/Modal";
+import { connect } from "metabase/lib/redux";
 import MetabaseSettings from "metabase/lib/settings";
 
 type IRoute = {
diff --git a/frontend/src/metabase/hoc/Remapped.jsx b/frontend/src/metabase/hoc/Remapped.jsx
index d63f8c22fdc..fd7b182e432 100644
--- a/frontend/src/metabase/hoc/Remapped.jsx
+++ b/frontend/src/metabase/hoc/Remapped.jsx
@@ -1,7 +1,7 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 
+import { connect } from "metabase/lib/redux";
 import { fetchRemapping } from "metabase/redux/metadata";
 import { getMetadata } from "metabase/selectors/metadata";
 
diff --git a/frontend/src/metabase/hoc/Routeless.jsx b/frontend/src/metabase/hoc/Routeless.jsx
index c2beb49ca72..128d0626e43 100644
--- a/frontend/src/metabase/hoc/Routeless.jsx
+++ b/frontend/src/metabase/hoc/Routeless.jsx
@@ -1,9 +1,10 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
+import { connect } from "metabase/lib/redux";
+
 // namespace under _routeless_
 const mapStateToProps = (state, props) => ({
   _routeless_location: state.routing.locationBeforeTransitions,
diff --git a/frontend/src/metabase/hoc/Toast.jsx b/frontend/src/metabase/hoc/Toast.jsx
index 9df49fddf5d..39ae0441aca 100644
--- a/frontend/src/metabase/hoc/Toast.jsx
+++ b/frontend/src/metabase/hoc/Toast.jsx
@@ -1,7 +1,7 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 
+import { connect } from "metabase/lib/redux";
 import { addUndo } from "metabase/redux/undo";
 
 const mapDispatchToProps = {
diff --git a/frontend/src/metabase/lib/redux/custom-context.tsx b/frontend/src/metabase/lib/redux/custom-context.tsx
new file mode 100644
index 00000000000..3c357f3ced9
--- /dev/null
+++ b/frontend/src/metabase/lib/redux/custom-context.tsx
@@ -0,0 +1,34 @@
+import type { Store } from "@reduxjs/toolkit";
+import { createContext } from "react";
+import { Provider, ReactReduxContext } from "react-redux";
+// eslint-disable-next-line no-restricted-imports
+import * as ReactRedux from "react-redux";
+
+import { isEmbeddingSdk } from "metabase/env";
+
+export const MetabaseReduxContext = isEmbeddingSdk
+  ? createContext<any>(null)
+  : ReactReduxContext;
+
+export const MetabaseReduxProvider = ({
+  children,
+  store,
+}: React.PropsWithChildren & { store: Store }) => {
+  return (
+    <Provider store={store} context={MetabaseReduxContext}>
+      {children}
+    </Provider>
+  );
+};
+
+export const connect: typeof ReactRedux.connect = (
+  mapStateToProps?: any,
+  mapDispatchToProps?: any,
+  mergeProps?: any,
+  options?: any,
+) => {
+  return ReactRedux.connect(mapStateToProps, mapDispatchToProps, mergeProps, {
+    context: MetabaseReduxContext,
+    ...options,
+  });
+};
diff --git a/frontend/src/metabase/lib/redux/hooks.ts b/frontend/src/metabase/lib/redux/hooks.ts
index 10622e92acb..dcb1d8604a6 100644
--- a/frontend/src/metabase/lib/redux/hooks.ts
+++ b/frontend/src/metabase/lib/redux/hooks.ts
@@ -1,16 +1,20 @@
 import type { AnyAction, Store, ThunkDispatch } from "@reduxjs/toolkit";
 import type { TypedUseSelectorHook } from "react-redux";
 import {
-  useDispatch as useDispatchOriginal,
-  useSelector as useSelectorOriginal,
-  useStore as useStoreOriginal,
+  createDispatchHook,
+  createSelectorHook,
+  createStoreHook,
 } from "react-redux";
 
 import type { State } from "metabase-types/store";
 
-export const useStore: () => Store<State, AnyAction> = useStoreOriginal;
+import { MetabaseReduxContext } from "./custom-context";
+
+export const useStore: () => Store<State, AnyAction> =
+  createStoreHook(MetabaseReduxContext);
 export const useDispatch: () => ThunkDispatch<State, void, AnyAction> =
-  useDispatchOriginal;
-export const useSelector: TypedUseSelectorHook<State> = useSelectorOriginal;
+  createDispatchHook(MetabaseReduxContext);
+export const useSelector: TypedUseSelectorHook<State> =
+  createSelectorHook(MetabaseReduxContext);
 
 export type DispatchFn = ReturnType<typeof useDispatch>;
diff --git a/frontend/src/metabase/lib/redux/index.ts b/frontend/src/metabase/lib/redux/index.ts
index 325110e8681..260997d43d1 100644
--- a/frontend/src/metabase/lib/redux/index.ts
+++ b/frontend/src/metabase/lib/redux/index.ts
@@ -1,3 +1,4 @@
 export * from "./utils";
 export * from "./typed-utils";
 export * from "./hooks";
+export * from "./custom-context";
diff --git a/frontend/src/metabase/models/components/ModelDetailPage/ModelActionDetails/ModelActionDetails.tsx b/frontend/src/metabase/models/components/ModelDetailPage/ModelActionDetails/ModelActionDetails.tsx
index 0e55c07d388..39e8b4227af 100644
--- a/frontend/src/metabase/models/components/ModelDetailPage/ModelActionDetails/ModelActionDetails.tsx
+++ b/frontend/src/metabase/models/components/ModelDetailPage/ModelActionDetails/ModelActionDetails.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -8,6 +7,7 @@ import Link from "metabase/core/components/Link";
 import Actions from "metabase/entities/actions";
 import Databases from "metabase/entities/databases";
 import { useConfirmation } from "metabase/hooks/use-confirmation";
+import { connect } from "metabase/lib/redux";
 import { parseTimestamp } from "metabase/lib/time";
 import * as Urls from "metabase/lib/urls";
 import type Question from "metabase-lib/v1/Question";
diff --git a/frontend/src/metabase/models/containers/ModelDetailPage/ModelDetailPage.tsx b/frontend/src/metabase/models/containers/ModelDetailPage/ModelDetailPage.tsx
index 16a9d67ddd3..0e3be191a44 100644
--- a/frontend/src/metabase/models/containers/ModelDetailPage/ModelDetailPage.tsx
+++ b/frontend/src/metabase/models/containers/ModelDetailPage/ModelDetailPage.tsx
@@ -1,7 +1,6 @@
 import type { Location, LocationDescriptor } from "history";
 import type * as React from "react";
 import { useCallback, useEffect, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import { replace } from "react-router-redux";
 import { useMount } from "react-use";
 import _ from "underscore";
@@ -12,7 +11,7 @@ import Databases from "metabase/entities/databases";
 import Questions from "metabase/entities/questions";
 import Tables from "metabase/entities/tables";
 import title from "metabase/hoc/Title";
-import { useSelector } from "metabase/lib/redux";
+import { connect, useSelector } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import ModelDetailPageView from "metabase/models/components/ModelDetailPage";
 import { loadMetadataForCard } from "metabase/questions/actions";
diff --git a/frontend/src/metabase/nav/components/ProfileLink/ProfileLink.jsx b/frontend/src/metabase/nav/components/ProfileLink/ProfileLink.jsx
index 4f31e1157fb..512aefd4b36 100644
--- a/frontend/src/metabase/nav/components/ProfileLink/ProfileLink.jsx
+++ b/frontend/src/metabase/nav/components/ProfileLink/ProfileLink.jsx
@@ -1,7 +1,6 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { useState } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -22,7 +21,7 @@ import {
 } from "metabase/home/selectors";
 import { color } from "metabase/lib/colors";
 import { capitalize } from "metabase/lib/formatting";
-import { useSelector } from "metabase/lib/redux";
+import { connect, useSelector } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { openDiagnostics } from "metabase/redux/app";
 import {
@@ -199,7 +198,6 @@ function ProfileLink({
           )}
         </Modal>
       ) : null}
-
       {modalOpen === "diagnostic" && (
         <ErrorDiagnosticModalWrapper isModalOpen={true} onClose={closeModal} />
       )}
diff --git a/frontend/src/metabase/nav/containers/AppBar/AppBar.tsx b/frontend/src/metabase/nav/containers/AppBar/AppBar.tsx
index d8ac9a57c3f..0af5940965e 100644
--- a/frontend/src/metabase/nav/containers/AppBar/AppBar.tsx
+++ b/frontend/src/metabase/nav/containers/AppBar/AppBar.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { withRouter } from "react-router";
 import _ from "underscore";
 
 import { logout } from "metabase/auth/actions";
 import Collections from "metabase/entities/collections";
+import { connect } from "metabase/lib/redux";
 import { closeNavbar, toggleNavbar } from "metabase/redux/app";
 import type { RouterProps } from "metabase/selectors/app";
 import {
diff --git a/frontend/src/metabase/nav/containers/MainNavbar/MainNavbar.tsx b/frontend/src/metabase/nav/containers/MainNavbar/MainNavbar.tsx
index 6bb8ba6838e..9941547c89f 100644
--- a/frontend/src/metabase/nav/containers/MainNavbar/MainNavbar.tsx
+++ b/frontend/src/metabase/nav/containers/MainNavbar/MainNavbar.tsx
@@ -1,12 +1,12 @@
 import type { LocationDescriptor } from "history";
 import { useEffect, useMemo } from "react";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
 import { skipToken, useGetCollectionQuery } from "metabase/api";
 import { useQuestionQuery } from "metabase/common/hooks";
 import { getDashboard } from "metabase/dashboard/selectors";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { closeNavbar, openNavbar } from "metabase/redux/app";
 import type Question from "metabase-lib/v1/Question";
diff --git a/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/BookmarkList/BookmarkList.tsx b/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/BookmarkList/BookmarkList.tsx
index b6203199eb6..a16d0662aa5 100644
--- a/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/BookmarkList/BookmarkList.tsx
+++ b/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/BookmarkList/BookmarkList.tsx
@@ -9,7 +9,6 @@ import {
   verticalListSortingStrategy,
 } from "@dnd-kit/sortable";
 import { useCallback, useEffect, useState } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import CollapseSection from "metabase/components/CollapseSection";
@@ -18,6 +17,7 @@ import Tooltip from "metabase/core/components/Tooltip";
 import GrabberS from "metabase/css/components/grabber.module.css";
 import CS from "metabase/css/core/index.css";
 import Bookmarks from "metabase/entities/bookmarks";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { PLUGIN_COLLECTIONS } from "metabase/plugins";
 import { Icon } from "metabase/ui";
diff --git a/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/MainNavbarContainer.tsx b/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/MainNavbarContainer.tsx
index 5ed0456608f..a58efe206e0 100644
--- a/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/MainNavbarContainer.tsx
+++ b/frontend/src/metabase/nav/containers/MainNavbar/MainNavbarContainer/MainNavbarContainer.tsx
@@ -1,6 +1,5 @@
 import type { LocationDescriptor } from "history";
 import { memo, useCallback, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import {
@@ -22,6 +21,7 @@ import Collections, {
   getCollectionIcon,
 } from "metabase/entities/collections";
 import Databases from "metabase/entities/databases";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import { getHasDataAccess } from "metabase/selectors/data";
 import { getUser, getUserIsAdmin } from "metabase/selectors/user";
diff --git a/frontend/src/metabase/nav/containers/Navbar.tsx b/frontend/src/metabase/nav/containers/Navbar.tsx
index e6dfaf3a000..a6f349021bc 100644
--- a/frontend/src/metabase/nav/containers/Navbar.tsx
+++ b/frontend/src/metabase/nav/containers/Navbar.tsx
@@ -1,11 +1,11 @@
 import type { Location } from "history";
 import { useMemo } from "react";
-import { connect } from "react-redux";
 import { withRouter } from "react-router";
 import _ from "underscore";
 
 import { getAdminPaths } from "metabase/admin/app/selectors";
 import Database from "metabase/entities/databases";
+import { connect } from "metabase/lib/redux";
 import { getIsNavbarOpen } from "metabase/selectors/app";
 import { getUser } from "metabase/selectors/user";
 import type { User } from "metabase-types/api";
diff --git a/frontend/src/metabase/nav/containers/QuestionLineage/QuestionLineage.tsx b/frontend/src/metabase/nav/containers/QuestionLineage/QuestionLineage.tsx
index 69322fa599c..431355feeb5 100644
--- a/frontend/src/metabase/nav/containers/QuestionLineage/QuestionLineage.tsx
+++ b/frontend/src/metabase/nav/containers/QuestionLineage/QuestionLineage.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import {
   getOriginalQuestion,
   getQuestion,
diff --git a/frontend/src/metabase/parameters/components/ValuesSourceModal/ValuesSourceTypeModal.tsx b/frontend/src/metabase/parameters/components/ValuesSourceModal/ValuesSourceTypeModal.tsx
index 9e30874c8a0..290246a8013 100644
--- a/frontend/src/metabase/parameters/components/ValuesSourceModal/ValuesSourceTypeModal.tsx
+++ b/frontend/src/metabase/parameters/components/ValuesSourceModal/ValuesSourceTypeModal.tsx
@@ -1,6 +1,5 @@
 import type { ChangeEvent } from "react";
 import { useCallback, useLayoutEffect, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import { jt, t } from "ttag";
 import _ from "underscore";
 
@@ -15,7 +14,7 @@ import SelectButton from "metabase/core/components/SelectButton";
 import Questions from "metabase/entities/questions";
 import Tables from "metabase/entities/tables";
 import { useSafeAsyncFunction } from "metabase/hooks/use-safe-async-function";
-import { useSelector } from "metabase/lib/redux";
+import { connect, useSelector } from "metabase/lib/redux";
 import { getLearnUrl } from "metabase/selectors/settings";
 import { getShowMetabaseLinks } from "metabase/selectors/whitelabel";
 import { Box, Flex, Icon } from "metabase/ui";
diff --git a/frontend/src/metabase/public/containers/PublicAction/PublicActionLoader.tsx b/frontend/src/metabase/public/containers/PublicAction/PublicActionLoader.tsx
index b2b89f1993c..1513feeb05b 100644
--- a/frontend/src/metabase/public/containers/PublicAction/PublicActionLoader.tsx
+++ b/frontend/src/metabase/public/containers/PublicAction/PublicActionLoader.tsx
@@ -1,8 +1,8 @@
 import { useCallback, useState } from "react";
-import { connect } from "react-redux";
 import { useMount } from "react-use";
 
 import { useSafeAsyncFunction } from "metabase/hooks/use-safe-async-function";
+import { connect } from "metabase/lib/redux";
 import { SyncedEmbedFrame } from "metabase/public/components/EmbedFrame";
 import { setErrorPage } from "metabase/redux/app";
 import { PublicApi } from "metabase/services";
diff --git a/frontend/src/metabase/public/containers/PublicApp/PublicApp.tsx b/frontend/src/metabase/public/containers/PublicApp/PublicApp.tsx
index 4dc00027928..642697b97c8 100644
--- a/frontend/src/metabase/public/containers/PublicApp/PublicApp.tsx
+++ b/frontend/src/metabase/public/containers/PublicApp/PublicApp.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import { PublicError } from "metabase/public/components/PublicError";
 import { PublicNotFound } from "metabase/public/components/PublicNotFound";
 import { getErrorPage } from "metabase/selectors/app";
diff --git a/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboard.tsx b/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboard.tsx
index 706094a4964..4a7694d2504 100644
--- a/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboard.tsx
+++ b/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboard.tsx
@@ -1,7 +1,6 @@
 import type { Query } from "history";
 import { useEffect, useRef } from "react";
 import type { ConnectedProps } from "react-redux";
-import { connect } from "react-redux";
 import { usePrevious, useUnmount } from "react-use";
 import _ from "underscore";
 
@@ -29,6 +28,7 @@ import type {
   FetchDashboardResult,
   SuccessfulFetchDashboardResult,
 } from "metabase/dashboard/types";
+import { connect } from "metabase/lib/redux";
 import { type DispatchFn, useDispatch } from "metabase/lib/redux";
 import { LocaleProvider } from "metabase/public/LocaleProvider";
 import type { PublicOrEmbeddedDashboardEventHandlersProps } from "metabase/public/containers/PublicOrEmbeddedDashboard/types";
diff --git a/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView-filters.stories.tsx b/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView-filters.stories.tsx
index ecf7e84676e..f0150cb41b2 100644
--- a/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView-filters.stories.tsx
+++ b/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView-filters.stories.tsx
@@ -3,12 +3,12 @@ import createAsyncCallback from "@loki/create-async-callback";
 import type { StoryContext, StoryFn } from "@storybook/react";
 import { userEvent, within } from "@storybook/testing-library";
 import { type ComponentProps, useEffect } from "react";
-import { Provider } from "react-redux";
 
 import { getStore } from "__support__/entities-store";
 import { createMockMetadata } from "__support__/metadata";
 import { getNextId } from "__support__/utils";
 import { NumberColumn, StringColumn } from "__support__/visualizations";
+import { MetabaseReduxProvider } from "metabase/lib/redux/custom-context";
 import { getDashboardUiParameters } from "metabase/parameters/utils/dashboards";
 import { publicReducers } from "metabase/reducers-public";
 import TABLE_RAW_SERIES from "metabase/visualizations/components/TableSimple/stories-data/table-simple-orders-with-people.json";
@@ -101,9 +101,9 @@ function ReduxDecorator(Story: StoryFn, context: StoryContext) {
 
   const store = getStore(publicReducers, initialState);
   return (
-    <Provider store={store}>
+    <MetabaseReduxProvider store={store}>
       <Story />
-    </Provider>
+    </MetabaseReduxProvider>
   );
 }
 
diff --git a/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView.stories.tsx b/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView.stories.tsx
index 1eb763c6668..3a219f6715f 100644
--- a/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView.stories.tsx
+++ b/frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard/PublicOrEmbeddedDashboardView.stories.tsx
@@ -2,7 +2,6 @@
 import createAsyncCallback from "@loki/create-async-callback";
 import type { StoryFn } from "@storybook/react";
 import { type ComponentProps, useEffect } from "react";
-import { Provider } from "react-redux";
 
 import { getStore } from "__support__/entities-store";
 import { getNextId } from "__support__/utils";
@@ -10,6 +9,7 @@ import { NumberColumn, StringColumn } from "__support__/visualizations";
 import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
 import TippyPopoverWithTrigger from "metabase/components/PopoverWithTrigger/TippyPopoverWithTrigger";
 import LegacyTooltip from "metabase/core/components/Tooltip";
+import { MetabaseReduxProvider } from "metabase/lib/redux";
 import { publicReducers } from "metabase/reducers-public";
 import { Box, Card, Popover, Text, Tooltip } from "metabase/ui";
 import { registerVisualization } from "metabase/visualizations";
@@ -51,9 +51,9 @@ export default {
 
 function ReduxDecorator(Story: StoryFn) {
   return (
-    <Provider store={store}>
+    <MetabaseReduxProvider store={store}>
       <Story />
-    </Provider>
+    </MetabaseReduxProvider>
   );
 }
 
diff --git a/frontend/src/metabase/public/containers/PublicOrEmbeddedQuestion/PublicOrEmbeddedQuestionView.stories.tsx b/frontend/src/metabase/public/containers/PublicOrEmbeddedQuestion/PublicOrEmbeddedQuestionView.stories.tsx
index 4eb11bfcf0e..808bf9f3843 100644
--- a/frontend/src/metabase/public/containers/PublicOrEmbeddedQuestion/PublicOrEmbeddedQuestionView.stories.tsx
+++ b/frontend/src/metabase/public/containers/PublicOrEmbeddedQuestion/PublicOrEmbeddedQuestionView.stories.tsx
@@ -3,7 +3,6 @@ import createAsyncCallback from "@loki/create-async-callback";
 import type { StoryFn } from "@storybook/react";
 import { userEvent, within } from "@storybook/testing-library";
 import { type ComponentProps, useEffect } from "react";
-import { Provider } from "react-redux";
 
 import { getStore } from "__support__/entities-store";
 import { createMockMetadata } from "__support__/metadata";
@@ -13,6 +12,7 @@ import {
   NumberColumn,
   StringColumn,
 } from "__support__/visualizations";
+import { MetabaseReduxProvider } from "metabase/lib/redux";
 import { publicReducers } from "metabase/reducers-public";
 import { Box } from "metabase/ui";
 import { registerVisualization } from "metabase/visualizations";
@@ -52,9 +52,9 @@ export default {
 
 function ReduxDecorator(Story: StoryFn) {
   return (
-    <Provider store={store}>
+    <MetabaseReduxProvider store={store}>
       <Story />
-    </Provider>
+    </MetabaseReduxProvider>
   );
 }
 
diff --git a/frontend/src/metabase/query_builder/components/AlertModals/AlertEditChannels.jsx b/frontend/src/metabase/query_builder/components/AlertModals/AlertEditChannels.jsx
index d0ff379b91a..f25227acc0c 100644
--- a/frontend/src/metabase/query_builder/components/AlertModals/AlertEditChannels.jsx
+++ b/frontend/src/metabase/query_builder/components/AlertModals/AlertEditChannels.jsx
@@ -1,12 +1,12 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { jt, t } from "ttag";
 import _ from "underscore";
 
 import CS from "metabase/css/core/index.css";
 import Users from "metabase/entities/users";
+import { connect } from "metabase/lib/redux";
 import { fetchPulseFormInput } from "metabase/pulse/actions";
 import { PulseEditChannels } from "metabase/pulse/components/PulseEditChannels";
 import { getPulseFormInput } from "metabase/pulse/selectors";
diff --git a/frontend/src/metabase/query_builder/components/AlertModals/AlertEditForm.jsx b/frontend/src/metabase/query_builder/components/AlertModals/AlertEditForm.jsx
index 2bd9ea213fd..a5ff24160cc 100644
--- a/frontend/src/metabase/query_builder/components/AlertModals/AlertEditForm.jsx
+++ b/frontend/src/metabase/query_builder/components/AlertModals/AlertEditForm.jsx
@@ -1,7 +1,7 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 
+import { connect } from "metabase/lib/redux";
 import { getUserIsAdmin } from "metabase/selectors/user";
 
 import { AlertEditChannels } from "./AlertEditChannels";
diff --git a/frontend/src/metabase/query_builder/components/AlertModals/RawDataAlertTip.jsx b/frontend/src/metabase/query_builder/components/AlertModals/RawDataAlertTip.jsx
index 1b783fe41e7..cab6c5e5976 100644
--- a/frontend/src/metabase/query_builder/components/AlertModals/RawDataAlertTip.jsx
+++ b/frontend/src/metabase/query_builder/components/AlertModals/RawDataAlertTip.jsx
@@ -1,8 +1,8 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
-import { connect } from "react-redux";
 
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import {
   getQuestion,
   getVisualizationSettings,
diff --git a/frontend/src/metabase/query_builder/components/DataSelector/DataSelector.jsx b/frontend/src/metabase/query_builder/components/DataSelector/DataSelector.jsx
index 6ed0ae8039a..c60ec747daa 100644
--- a/frontend/src/metabase/query_builder/components/DataSelector/DataSelector.jsx
+++ b/frontend/src/metabase/query_builder/components/DataSelector/DataSelector.jsx
@@ -2,7 +2,6 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component, createRef } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -16,6 +15,7 @@ import Questions from "metabase/entities/questions";
 import Schemas from "metabase/entities/schemas";
 import Search from "metabase/entities/search";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import { getHasDataAccess } from "metabase/selectors/data";
 import { getMetadata } from "metabase/selectors/metadata";
 import { getSetting } from "metabase/selectors/settings";
diff --git a/frontend/src/metabase/query_builder/components/DataSelector/saved-entity-picker/SavedEntityPicker.jsx b/frontend/src/metabase/query_builder/components/DataSelector/saved-entity-picker/SavedEntityPicker.jsx
index ebb7401480d..2944d867c89 100644
--- a/frontend/src/metabase/query_builder/components/DataSelector/saved-entity-picker/SavedEntityPicker.jsx
+++ b/frontend/src/metabase/query_builder/components/DataSelector/saved-entity-picker/SavedEntityPicker.jsx
@@ -1,6 +1,5 @@
 import PropTypes from "prop-types";
 import { useCallback, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import {
@@ -14,6 +13,7 @@ import Collection, {
   PERSONAL_COLLECTIONS,
   buildCollectionTree,
 } from "metabase/entities/collections";
+import { connect } from "metabase/lib/redux";
 import { Icon } from "metabase/ui";
 
 import SavedEntityList from "./SavedEntityList";
diff --git a/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetEditor.jsx b/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetEditor.jsx
index 8a6ad03d2ab..e89c56354f2 100644
--- a/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetEditor.jsx
+++ b/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetEditor.jsx
@@ -2,7 +2,6 @@ import cx from "classnames";
 import { merge } from "icepick";
 import PropTypes from "prop-types";
 import { useCallback, useEffect, useMemo, useState } from "react";
-import { connect } from "react-redux";
 import { usePrevious } from "react-use";
 import { t } from "ttag";
 
@@ -15,6 +14,7 @@ import Button from "metabase/core/components/Button";
 import ButtonsS from "metabase/css/components/buttons.module.css";
 import CS from "metabase/css/core/index.css";
 import { useToggle } from "metabase/hooks/use-toggle";
+import { connect } from "metabase/lib/redux";
 import { getSemanticTypeIcon } from "metabase/lib/schema_metadata";
 import { setDatasetEditorTab } from "metabase/query_builder/actions";
 import { calcInitialEditorHeight } from "metabase/query_builder/components/NativeQueryEditor/utils";
diff --git a/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetFieldMetadataSidebar/SemanticTypePicker/FKTargetPicker.tsx b/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetFieldMetadataSidebar/SemanticTypePicker/FKTargetPicker.tsx
index 8f1612b9237..a7c98e4a959 100644
--- a/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetFieldMetadataSidebar/SemanticTypePicker/FKTargetPicker.tsx
+++ b/frontend/src/metabase/query_builder/components/DatasetEditor/DatasetFieldMetadataSidebar/SemanticTypePicker/FKTargetPicker.tsx
@@ -1,11 +1,11 @@
 import { useField } from "formik";
 import { useEffect, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
 import Select from "metabase/core/components/Select";
 import Databases from "metabase/entities/databases";
+import { connect } from "metabase/lib/redux";
 import type Field from "metabase-lib/v1/metadata/Field";
 import type { DatabaseId } from "metabase-types/api";
 
diff --git a/frontend/src/metabase/query_builder/components/NativeQueryEditor/NativeQueryEditor.tsx b/frontend/src/metabase/query_builder/components/NativeQueryEditor/NativeQueryEditor.tsx
index 7007337925b..4f69899c819 100644
--- a/frontend/src/metabase/query_builder/components/NativeQueryEditor/NativeQueryEditor.tsx
+++ b/frontend/src/metabase/query_builder/components/NativeQueryEditor/NativeQueryEditor.tsx
@@ -1,7 +1,6 @@
 import type { Ace } from "ace-builds";
 import * as ace from "ace-builds/src-noconflict/ace";
 import { Component, createRef } from "react";
-import { connect } from "react-redux";
 import type { ResizableBox, ResizableBoxProps } from "react-resizable";
 import slugg from "slugg";
 import { t } from "ttag";
@@ -25,6 +24,7 @@ import Snippets from "metabase/entities/snippets";
 import { SQLBehaviour } from "metabase/lib/ace/sql_behaviour";
 import { isEventOverElement } from "metabase/lib/dom";
 import { getEngineNativeAceMode } from "metabase/lib/engine";
+import { connect } from "metabase/lib/redux";
 import { checkNotNull } from "metabase/lib/types";
 import SnippetFormModal from "metabase/query_builder/components/template_tags/SnippetFormModal";
 import type { QueryModalType } from "metabase/query_builder/constants";
diff --git a/frontend/src/metabase/query_builder/components/NewDatasetModal/NewDatasetModal.jsx b/frontend/src/metabase/query_builder/components/NewDatasetModal/NewDatasetModal.jsx
index 81a34bc7a88..d2b71b22fbc 100644
--- a/frontend/src/metabase/query_builder/components/NewDatasetModal/NewDatasetModal.jsx
+++ b/frontend/src/metabase/query_builder/components/NewDatasetModal/NewDatasetModal.jsx
@@ -1,11 +1,11 @@
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import ModalContent from "metabase/components/ModalContent";
 import Button from "metabase/core/components/Button";
 import Link from "metabase/core/components/Link";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import { turnQuestionIntoModel } from "metabase/query_builder/actions";
 
 import {
diff --git a/frontend/src/metabase/query_builder/components/dataref/TableInfoLoader.tsx b/frontend/src/metabase/query_builder/components/dataref/TableInfoLoader.tsx
index c07df2bef51..851ccdb3e32 100644
--- a/frontend/src/metabase/query_builder/components/dataref/TableInfoLoader.tsx
+++ b/frontend/src/metabase/query_builder/components/dataref/TableInfoLoader.tsx
@@ -1,9 +1,9 @@
 import { useEffect, useState } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Tables from "metabase/entities/tables";
 import { useSafeAsyncFunction } from "metabase/hooks/use-safe-async-function";
+import { connect } from "metabase/lib/redux";
 import type Table from "metabase-lib/v1/metadata/Table";
 
 type OwnProps = {
diff --git a/frontend/src/metabase/query_builder/components/dataref/TablePane.tsx b/frontend/src/metabase/query_builder/components/dataref/TablePane.tsx
index 55bd55c136a..5d85419b44f 100644
--- a/frontend/src/metabase/query_builder/components/dataref/TablePane.tsx
+++ b/frontend/src/metabase/query_builder/components/dataref/TablePane.tsx
@@ -1,4 +1,3 @@
-import { connect } from "react-redux";
 import { msgid, ngettext, t } from "ttag";
 import _ from "underscore";
 
@@ -8,6 +7,7 @@ import {
 } from "metabase/components/MetadataInfo/MetadataInfo.styled";
 import CS from "metabase/css/core/index.css";
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import SidebarContent from "metabase/query_builder/components/SidebarContent";
 import ConnectedTableList from "metabase/query_builder/components/dataref/ConnectedTableList";
 import type Table from "metabase-lib/v1/metadata/Table";
diff --git a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield/ExpressionEditorTextfield.tsx b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield/ExpressionEditorTextfield.tsx
index 3ee32b96f22..71ba78efb30 100644
--- a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield/ExpressionEditorTextfield.tsx
+++ b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield/ExpressionEditorTextfield.tsx
@@ -3,12 +3,12 @@ import * as ace from "ace-builds/src-noconflict/ace";
 import * as React from "react";
 import type { ICommand, IMarker } from "react-ace";
 import AceEditor from "react-ace";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
 import { getColumnIcon } from "metabase/common/utils/columns";
 import ExplicitSize from "metabase/components/ExplicitSize";
+import { connect } from "metabase/lib/redux";
 import { getMetadata } from "metabase/selectors/metadata";
 import { getShowMetabaseLinks } from "metabase/selectors/whitelabel";
 import type { IconName } from "metabase/ui";
diff --git a/frontend/src/metabase/query_builder/components/template_tags/SnippetForm/SnippetForm.tsx b/frontend/src/metabase/query_builder/components/template_tags/SnippetForm/SnippetForm.tsx
index 5f48d252283..1efa539a898 100644
--- a/frontend/src/metabase/query_builder/components/template_tags/SnippetForm/SnippetForm.tsx
+++ b/frontend/src/metabase/query_builder/components/template_tags/SnippetForm/SnippetForm.tsx
@@ -1,5 +1,4 @@
 import { useCallback, useMemo } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 import * as Yup from "yup";
@@ -14,6 +13,7 @@ import SnippetCollections from "metabase/entities/snippet-collections";
 import Snippets from "metabase/entities/snippets";
 import { Form, FormProvider } from "metabase/forms";
 import * as Errors from "metabase/lib/errors";
+import { connect } from "metabase/lib/redux";
 import type {
   Collection,
   NativeQuerySnippet,
diff --git a/frontend/src/metabase/query_builder/components/template_tags/SnippetSidebar/SnippetSidebar.jsx b/frontend/src/metabase/query_builder/components/template_tags/SnippetSidebar/SnippetSidebar.jsx
index 5a32e91b131..17f23dabf73 100644
--- a/frontend/src/metabase/query_builder/components/template_tags/SnippetSidebar/SnippetSidebar.jsx
+++ b/frontend/src/metabase/query_builder/components/template_tags/SnippetSidebar/SnippetSidebar.jsx
@@ -2,7 +2,6 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import * as React from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -14,6 +13,7 @@ import Search from "metabase/entities/search";
 import SnippetCollections from "metabase/entities/snippet-collections";
 import Snippets from "metabase/entities/snippets";
 import { color } from "metabase/lib/colors";
+import { connect } from "metabase/lib/redux";
 import {
   PLUGIN_SNIPPET_SIDEBAR_HEADER_BUTTONS,
   PLUGIN_SNIPPET_SIDEBAR_MODALS,
diff --git a/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.tsx b/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.tsx
index a708641c871..800e33c7b03 100644
--- a/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.tsx
+++ b/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.tsx
@@ -1,8 +1,8 @@
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
+import { connect } from "metabase/lib/redux";
 import { ValuesSourceSettings } from "metabase/parameters/components/ValuesSourceSettings";
 import type { EmbeddingParameterVisibility } from "metabase/public/lib/types";
 import { getOriginalQuestion } from "metabase/query_builder/selectors";
diff --git a/frontend/src/metabase/query_builder/components/view/QuestionRowCount/QuestionRowCount.tsx b/frontend/src/metabase/query_builder/components/view/QuestionRowCount/QuestionRowCount.tsx
index 21685518fe8..48e5c2f05e3 100644
--- a/frontend/src/metabase/query_builder/components/view/QuestionRowCount/QuestionRowCount.tsx
+++ b/frontend/src/metabase/query_builder/components/view/QuestionRowCount/QuestionRowCount.tsx
@@ -1,5 +1,4 @@
 import { useMemo } from "react";
-import { connect } from "react-redux";
 import { msgid, ngettext, t } from "ttag";
 import _ from "underscore";
 
@@ -7,6 +6,7 @@ import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
 import CS from "metabase/css/core/index.css";
 import Database from "metabase/entities/databases";
 import { formatNumber } from "metabase/lib/formatting";
+import { connect } from "metabase/lib/redux";
 import { setLimit } from "metabase/query_builder/actions";
 import LimitPopover from "metabase/query_builder/components/LimitPopover";
 import {
diff --git a/frontend/src/metabase/query_builder/components/view/View/View/View.jsx b/frontend/src/metabase/query_builder/components/view/View/View/View.jsx
index 221f398bc9b..1e12a889daa 100644
--- a/frontend/src/metabase/query_builder/components/view/View/View/View.jsx
+++ b/frontend/src/metabase/query_builder/components/view/View/View/View.jsx
@@ -1,6 +1,5 @@
 /* eslint-disable react/prop-types */
 
-import { connect } from "react-redux";
 import { match } from "ts-pattern";
 import { t } from "ttag";
 import _ from "underscore";
@@ -13,6 +12,7 @@ import CS from "metabase/css/core/index.css";
 import QueryBuilderS from "metabase/css/query_builder.module.css";
 import Bookmarks from "metabase/entities/bookmarks";
 import Questions from "metabase/entities/questions";
+import { connect } from "metabase/lib/redux";
 import {
   rememberLastUsedDatabase,
   setArchivedQuestion,
diff --git a/frontend/src/metabase/query_builder/components/view/sidebars/DatasetManagementSection/DatasetManagementSection.jsx b/frontend/src/metabase/query_builder/components/view/sidebars/DatasetManagementSection/DatasetManagementSection.jsx
index cfbf9fecaa6..84d30e098c5 100644
--- a/frontend/src/metabase/query_builder/components/view/sidebars/DatasetManagementSection/DatasetManagementSection.jsx
+++ b/frontend/src/metabase/query_builder/components/view/sidebars/DatasetManagementSection/DatasetManagementSection.jsx
@@ -1,8 +1,8 @@
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import { PLUGIN_MODERATION } from "metabase/plugins";
 import {
   setQueryBuilderMode,
diff --git a/frontend/src/metabase/query_builder/containers/QueryBuilder.tsx b/frontend/src/metabase/query_builder/containers/QueryBuilder.tsx
index a2318c62fe7..40aa47f8f37 100644
--- a/frontend/src/metabase/query_builder/containers/QueryBuilder.tsx
+++ b/frontend/src/metabase/query_builder/containers/QueryBuilder.tsx
@@ -1,6 +1,6 @@
 import type { Location } from "history";
 import { useCallback, useEffect, useMemo, useRef, useState } from "react";
-import { type ConnectedProps, connect } from "react-redux";
+import type { ConnectedProps } from "react-redux";
 import type { Route, WithRouterProps } from "react-router";
 import { push } from "react-router-redux";
 import { useMount, usePrevious, useUnmount } from "react-use";
@@ -17,7 +17,7 @@ import { useFavicon } from "metabase/hooks/use-favicon";
 import { useForceUpdate } from "metabase/hooks/use-force-update";
 import { useLoadingTimer } from "metabase/hooks/use-loading-timer";
 import { useWebNotification } from "metabase/hooks/use-web-notification";
-import { useSelector } from "metabase/lib/redux";
+import { connect, useSelector } from "metabase/lib/redux";
 import { closeNavbar } from "metabase/redux/app";
 import { getIsNavbarOpen } from "metabase/selectors/app";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/questions/containers/ArchiveQuestionModal.jsx b/frontend/src/metabase/questions/containers/ArchiveQuestionModal.jsx
index 77e93c0e8f2..0a0065deb1b 100644
--- a/frontend/src/metabase/questions/containers/ArchiveQuestionModal.jsx
+++ b/frontend/src/metabase/questions/containers/ArchiveQuestionModal.jsx
@@ -1,9 +1,9 @@
 /* eslint-disable react/prop-types */
 import { Component } from "react";
-import { connect } from "react-redux";
 import { msgid, ngettext, t } from "ttag";
 
 import { ArchiveModal } from "metabase/components/ArchiveModal";
+import { connect } from "metabase/lib/redux";
 import { setArchivedQuestion } from "metabase/query_builder/actions";
 
 const mapDispatchToProps = dispatch => ({
diff --git a/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx b/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
index 215633a4a16..b8146e6422a 100644
--- a/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
+++ b/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
@@ -1,10 +1,10 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import L from "metabase/components/List/List.module.css";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import { fetchTableMetadata } from "metabase/redux/metadata";
 import D from "metabase/reference/components/Detail.module.css";
 import FieldToGroupBy from "metabase/reference/components/FieldToGroupBy";
diff --git a/frontend/src/metabase/reference/databases/DatabaseDetail.jsx b/frontend/src/metabase/reference/databases/DatabaseDetail.jsx
index 42fc4f612c4..d3137af0899 100644
--- a/frontend/src/metabase/reference/databases/DatabaseDetail.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseDetail.jsx
@@ -2,13 +2,13 @@
 import cx from "classnames";
 import { useFormik } from "formik";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import List from "metabase/components/List";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import Detail from "metabase/reference/components/Detail";
 import EditHeader from "metabase/reference/components/EditHeader";
diff --git a/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx b/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx
index 78a01d269e9..4626e22f33e 100644
--- a/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import DatabaseDetail from "metabase/reference/databases/DatabaseDetail";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/DatabaseList.jsx b/frontend/src/metabase/reference/databases/DatabaseList.jsx
index 76def9d187d..b02f2966f61 100644
--- a/frontend/src/metabase/reference/databases/DatabaseList.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseList.jsx
@@ -1,7 +1,6 @@
 /* eslint "react/prop-types": "warn" */
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import List from "metabase/components/List";
@@ -9,6 +8,7 @@ import S from "metabase/components/List/List.module.css";
 import ListItem from "metabase/components/ListItem";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import { NoDatabasesEmptyState } from "metabase/reference/databases/NoDatabasesEmptyState";
 
diff --git a/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx b/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx
index cbf960c5dc0..cb04525b5ac 100644
--- a/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import DatabaseList from "metabase/reference/databases/DatabaseList";
 import BaseSidebar from "metabase/reference/guide/BaseSidebar";
diff --git a/frontend/src/metabase/reference/databases/FieldDetail.jsx b/frontend/src/metabase/reference/databases/FieldDetail.jsx
index 0760bbc0735..2fc056262d2 100644
--- a/frontend/src/metabase/reference/databases/FieldDetail.jsx
+++ b/frontend/src/metabase/reference/databases/FieldDetail.jsx
@@ -2,13 +2,13 @@
 import cx from "classnames";
 import { useFormik } from "formik";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import List from "metabase/components/List";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import S from "metabase/reference/Reference.module.css";
 import Detail from "metabase/reference/components/Detail";
diff --git a/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx b/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx
index 7251e9ee356..88ec64dc8f6 100644
--- a/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx
+++ b/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import FieldDetail from "metabase/reference/databases/FieldDetail";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/FieldList.jsx b/frontend/src/metabase/reference/databases/FieldList.jsx
index 5cb38352dd5..f69ccf78217 100644
--- a/frontend/src/metabase/reference/databases/FieldList.jsx
+++ b/frontend/src/metabase/reference/databases/FieldList.jsx
@@ -3,7 +3,6 @@
 import cx from "classnames";
 import { useFormik } from "formik";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import EmptyState from "metabase/components/EmptyState";
@@ -11,6 +10,7 @@ import List from "metabase/components/List";
 import S from "metabase/components/List/List.module.css";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import R from "metabase/reference/Reference.module.css";
 import EditHeader from "metabase/reference/components/EditHeader";
diff --git a/frontend/src/metabase/reference/databases/FieldListContainer.jsx b/frontend/src/metabase/reference/databases/FieldListContainer.jsx
index 8526b4ca1b3..4e4f99953b4 100644
--- a/frontend/src/metabase/reference/databases/FieldListContainer.jsx
+++ b/frontend/src/metabase/reference/databases/FieldListContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import FieldList from "metabase/reference/databases/FieldList";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/TableDetail.jsx b/frontend/src/metabase/reference/databases/TableDetail.jsx
index 737708c88fd..b9048c34f3f 100644
--- a/frontend/src/metabase/reference/databases/TableDetail.jsx
+++ b/frontend/src/metabase/reference/databases/TableDetail.jsx
@@ -2,13 +2,13 @@
 import cx from "classnames";
 import { useFormik } from "formik";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import List from "metabase/components/List";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import S from "metabase/reference/Reference.module.css";
 import Detail from "metabase/reference/components/Detail";
diff --git a/frontend/src/metabase/reference/databases/TableDetailContainer.jsx b/frontend/src/metabase/reference/databases/TableDetailContainer.jsx
index f4fe5c16e39..817124cc739 100644
--- a/frontend/src/metabase/reference/databases/TableDetailContainer.jsx
+++ b/frontend/src/metabase/reference/databases/TableDetailContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import TableDetail from "metabase/reference/databases/TableDetail";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/TableList.jsx b/frontend/src/metabase/reference/databases/TableList.jsx
index a196e523359..65fc9c9fd4f 100644
--- a/frontend/src/metabase/reference/databases/TableList.jsx
+++ b/frontend/src/metabase/reference/databases/TableList.jsx
@@ -2,7 +2,6 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -12,6 +11,7 @@ import S from "metabase/components/List/List.module.css";
 import ListItem from "metabase/components/ListItem";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import R from "metabase/reference/Reference.module.css";
 
diff --git a/frontend/src/metabase/reference/databases/TableListContainer.jsx b/frontend/src/metabase/reference/databases/TableListContainer.jsx
index 640d16151dd..190072b6354 100644
--- a/frontend/src/metabase/reference/databases/TableListContainer.jsx
+++ b/frontend/src/metabase/reference/databases/TableListContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import TableList from "metabase/reference/databases/TableList";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/TableQuestions.jsx b/frontend/src/metabase/reference/databases/TableQuestions.jsx
index 72c76311ffe..2aadfad1489 100644
--- a/frontend/src/metabase/reference/databases/TableQuestions.jsx
+++ b/frontend/src/metabase/reference/databases/TableQuestions.jsx
@@ -3,7 +3,6 @@ import cx from "classnames";
 import moment from "moment-timezone"; // eslint-disable-line no-restricted-imports -- deprecated usage
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
@@ -12,6 +11,7 @@ import S from "metabase/components/List/List.module.css";
 import ListItem from "metabase/components/ListItem";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import * as metadataActions from "metabase/redux/metadata";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx b/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx
index 21bc8e28301..495d93e2160 100644
--- a/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx
+++ b/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx
@@ -2,11 +2,11 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
 import Questions from "metabase/entities/questions";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import TableQuestions from "metabase/reference/databases/TableQuestions";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentDetail.jsx b/frontend/src/metabase/reference/segments/SegmentDetail.jsx
index bd9b85bd0d9..84e0e2ef63b 100644
--- a/frontend/src/metabase/reference/segments/SegmentDetail.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentDetail.jsx
@@ -2,13 +2,13 @@
 import cx from "classnames";
 import { useFormik } from "formik";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import List from "metabase/components/List";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import Link from "metabase/core/components/Link";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import Detail from "metabase/reference/components/Detail";
 import EditHeader from "metabase/reference/components/EditHeader";
diff --git a/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx b/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx
index 62852c3bc15..89d89fa3867 100644
--- a/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
 import SegmentDetail from "metabase/reference/segments/SegmentDetail";
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx b/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx
index 7baf315c42a..16d3ac987b4 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx
@@ -2,12 +2,12 @@
 import cx from "classnames";
 import { useFormik } from "formik";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import List from "metabase/components/List";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import S from "metabase/reference/Reference.module.css";
 import Detail from "metabase/reference/components/Detail";
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx b/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx
index c92bc7736c2..79ef8608c97 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
 import SegmentFieldDetail from "metabase/reference/segments/SegmentFieldDetail";
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldList.jsx b/frontend/src/metabase/reference/segments/SegmentFieldList.jsx
index f5f08dc062a..1fc5810a82b 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldList.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldList.jsx
@@ -2,7 +2,6 @@
 import cx from "classnames";
 import { useFormik } from "formik";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import EmptyState from "metabase/components/EmptyState";
@@ -10,6 +9,7 @@ import List from "metabase/components/List";
 import S from "metabase/components/List/List.module.css";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import R from "metabase/reference/Reference.module.css";
 import EditHeader from "metabase/reference/components/EditHeader";
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx b/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx
index 52b2da5781a..ddce9191b7d 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
 import SegmentFieldList from "metabase/reference/segments/SegmentFieldList";
diff --git a/frontend/src/metabase/reference/segments/SegmentListContainer.jsx b/frontend/src/metabase/reference/segments/SegmentListContainer.jsx
index 3a3a16998d2..903ba066b1e 100644
--- a/frontend/src/metabase/reference/segments/SegmentListContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentListContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import BaseSidebar from "metabase/reference/guide/BaseSidebar";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentQuestions.jsx b/frontend/src/metabase/reference/segments/SegmentQuestions.jsx
index 6d5ca70e3c9..6609a8e1810 100644
--- a/frontend/src/metabase/reference/segments/SegmentQuestions.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentQuestions.jsx
@@ -1,7 +1,6 @@
 /* eslint "react/prop-types": "warn" */
 import cx from "classnames";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import { useQuestionListQuery } from "metabase/common/hooks";
@@ -11,6 +10,7 @@ import S from "metabase/components/List/List.module.css";
 import ListItem from "metabase/components/ListItem";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import * as metadataActions from "metabase/redux/metadata";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx b/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx
index 1bff43bc79b..0b29595b18d 100644
--- a/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx
@@ -2,11 +2,11 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
 import Questions from "metabase/entities/questions";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
 import SegmentQuestions from "metabase/reference/segments/SegmentQuestions";
diff --git a/frontend/src/metabase/reference/segments/SegmentRevisions.jsx b/frontend/src/metabase/reference/segments/SegmentRevisions.jsx
index 2f77733a551..235cb06db5c 100644
--- a/frontend/src/metabase/reference/segments/SegmentRevisions.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentRevisions.jsx
@@ -2,7 +2,6 @@ import cx from "classnames";
 import { getIn } from "icepick";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 
 import Revision from "metabase/admin/datamodel/components/revisions/Revision";
@@ -11,6 +10,7 @@ import S from "metabase/components/List/List.module.css";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import CS from "metabase/css/core/index.css";
 import { assignUserColors } from "metabase/lib/formatting";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 
 import ReferenceHeader from "../components/ReferenceHeader";
diff --git a/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx b/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx
index b89c9a6df44..712c758373e 100644
--- a/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx
@@ -2,10 +2,10 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 
 import SidebarLayout from "metabase/components/SidebarLayout";
 import CS from "metabase/css/core/index.css";
+import { connect } from "metabase/lib/redux";
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
 import SegmentRevisions from "metabase/reference/segments/SegmentRevisions";
diff --git a/frontend/src/metabase/sharing/components/AddEditSidebar/AddEditSidebar.jsx b/frontend/src/metabase/sharing/components/AddEditSidebar/AddEditSidebar.jsx
index 4c3a1fff8fa..710c0a7b70b 100644
--- a/frontend/src/metabase/sharing/components/AddEditSidebar/AddEditSidebar.jsx
+++ b/frontend/src/metabase/sharing/components/AddEditSidebar/AddEditSidebar.jsx
@@ -1,6 +1,5 @@
-import { connect } from "react-redux";
-
 import { getParameters } from "metabase/dashboard/selectors";
+import { connect } from "metabase/lib/redux";
 
 import _AddEditEmailSidebar from "./AddEditEmailSidebar";
 import _AddEditSlackSidebar from "./AddEditSlackSidebar";
diff --git a/frontend/src/metabase/sharing/components/PulsesListSidebar.jsx b/frontend/src/metabase/sharing/components/PulsesListSidebar.jsx
index 858e5d2654f..55634783939 100644
--- a/frontend/src/metabase/sharing/components/PulsesListSidebar.jsx
+++ b/frontend/src/metabase/sharing/components/PulsesListSidebar.jsx
@@ -2,7 +2,6 @@
 
 import cx from "classnames";
 import PropTypes from "prop-types";
-import { connect } from "react-redux";
 import { msgid, ngettext, t } from "ttag";
 import _ from "underscore";
 
@@ -17,6 +16,7 @@ import {
   formatTimeWithUnit,
 } from "metabase/lib/formatting";
 import { getActivePulseParameters } from "metabase/lib/pulse";
+import { connect } from "metabase/lib/redux";
 import { formatFrame } from "metabase/lib/time";
 import { Icon } from "metabase/ui";
 
diff --git a/frontend/src/metabase/sharing/components/SharingSidebar/SharingSidebar.jsx b/frontend/src/metabase/sharing/components/SharingSidebar/SharingSidebar.jsx
index c9db06a96f1..2338be884ed 100644
--- a/frontend/src/metabase/sharing/components/SharingSidebar/SharingSidebar.jsx
+++ b/frontend/src/metabase/sharing/components/SharingSidebar/SharingSidebar.jsx
@@ -2,7 +2,6 @@
 
 import PropTypes from "prop-types";
 import { Component } from "react";
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
@@ -13,6 +12,7 @@ import {
   cleanPulse,
   createChannel,
 } from "metabase/lib/pulse";
+import { connect } from "metabase/lib/redux";
 import {
   cancelEditingPulse,
   fetchPulseFormInput,
diff --git a/frontend/src/metabase/status/containers/DatabaseStatus/DatabaseStatus.tsx b/frontend/src/metabase/status/containers/DatabaseStatus/DatabaseStatus.tsx
index 5c6cc434986..9f97af717fb 100644
--- a/frontend/src/metabase/status/containers/DatabaseStatus/DatabaseStatus.tsx
+++ b/frontend/src/metabase/status/containers/DatabaseStatus/DatabaseStatus.tsx
@@ -1,7 +1,7 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Databases from "metabase/entities/databases";
+import { connect } from "metabase/lib/redux";
 import { isSyncInProgress } from "metabase/lib/syncing";
 import { getUser } from "metabase/selectors/user";
 import type Database from "metabase-lib/v1/metadata/Database";
diff --git a/frontend/src/metabase/timelines/collections/containers/DeleteEventModal/DeleteEventModal.tsx b/frontend/src/metabase/timelines/collections/containers/DeleteEventModal/DeleteEventModal.tsx
index 7daf64e32c4..34511976ea5 100644
--- a/frontend/src/metabase/timelines/collections/containers/DeleteEventModal/DeleteEventModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/DeleteEventModal/DeleteEventModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import DeleteEventModal from "metabase/timelines/common/components/DeleteEventModal";
 import type { Timeline, TimelineEvent } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/DeleteTimelineModal/DeleteTimelineModal.tsx b/frontend/src/metabase/timelines/collections/containers/DeleteTimelineModal/DeleteTimelineModal.tsx
index 012dbde6ee9..9215b6c4767 100644
--- a/frontend/src/metabase/timelines/collections/containers/DeleteTimelineModal/DeleteTimelineModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/DeleteTimelineModal/DeleteTimelineModal.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import DeleteTimelineModal from "metabase/timelines/common/components/DeleteTimelineModal";
 import type { Timeline } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/EditEventModal/EditEventModal.tsx b/frontend/src/metabase/timelines/collections/containers/EditEventModal/EditEventModal.tsx
index 75d7abd1b2b..38497728909 100644
--- a/frontend/src/metabase/timelines/collections/containers/EditEventModal/EditEventModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/EditEventModal/EditEventModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import EditEventModal from "metabase/timelines/common/components/EditEventModal";
 import type { Timeline, TimelineEvent } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/EditTimelineModal/EditTimelineModal.tsx b/frontend/src/metabase/timelines/collections/containers/EditTimelineModal/EditTimelineModal.tsx
index 25e10d66349..117d6009312 100644
--- a/frontend/src/metabase/timelines/collections/containers/EditTimelineModal/EditTimelineModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/EditTimelineModal/EditTimelineModal.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import EditTimelineModal from "metabase/timelines/common/components/EditTimelineModal";
 import type { Timeline } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/MoveEventModal/MoveEventModal.tsx b/frontend/src/metabase/timelines/collections/containers/MoveEventModal/MoveEventModal.tsx
index d4059f89ac6..2bdc8d748ec 100644
--- a/frontend/src/metabase/timelines/collections/containers/MoveEventModal/MoveEventModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/MoveEventModal/MoveEventModal.tsx
@@ -1,10 +1,10 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import Collections from "metabase/entities/collections";
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import MoveEventModal from "metabase/timelines/common/components/MoveEventModal";
 import type { Timeline, TimelineEvent } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/MoveTimelineModal/MoveTimelineModal.tsx b/frontend/src/metabase/timelines/collections/containers/MoveTimelineModal/MoveTimelineModal.tsx
index 5338b38157b..d3f7ff5329f 100644
--- a/frontend/src/metabase/timelines/collections/containers/MoveTimelineModal/MoveTimelineModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/MoveTimelineModal/MoveTimelineModal.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { goBack } from "react-router-redux";
 import _ from "underscore";
 
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import MoveTimelineModal from "metabase/timelines/common/components/MoveTimelineModal";
 import type { Timeline } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/NewEventModal/NewEventModal.tsx b/frontend/src/metabase/timelines/collections/containers/NewEventModal/NewEventModal.tsx
index fb67f1ef7ac..a43d8cdea11 100644
--- a/frontend/src/metabase/timelines/collections/containers/NewEventModal/NewEventModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/NewEventModal/NewEventModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import NewEventModal from "metabase/timelines/common/components/NewEventModal";
 import type { Collection, Timeline, TimelineEvent } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/NewEventWithTimelineModal/NewEventWithTimelineModal.tsx b/frontend/src/metabase/timelines/collections/containers/NewEventWithTimelineModal/NewEventWithTimelineModal.tsx
index 7d0ee9f67a7..62d25880337 100644
--- a/frontend/src/metabase/timelines/collections/containers/NewEventWithTimelineModal/NewEventWithTimelineModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/NewEventWithTimelineModal/NewEventWithTimelineModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import Collections from "metabase/entities/collections";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import NewEventModal from "metabase/timelines/common/components/NewEventModal";
 import type { Collection, TimelineEvent } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/NewTimelineModal/NewTimelineModal.tsx b/frontend/src/metabase/timelines/collections/containers/NewTimelineModal/NewTimelineModal.tsx
index 8084a6d844a..ab81754706f 100644
--- a/frontend/src/metabase/timelines/collections/containers/NewTimelineModal/NewTimelineModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/NewTimelineModal/NewTimelineModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { goBack, push } from "react-router-redux";
 import _ from "underscore";
 
 import Collections from "metabase/entities/collections";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import NewTimelineModal from "metabase/timelines/common/components/NewTimelineModal";
 import type { Timeline } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/collections/containers/TimelineArchiveModal/TimelineArchiveModal.tsx b/frontend/src/metabase/timelines/collections/containers/TimelineArchiveModal/TimelineArchiveModal.tsx
index 0ea891ce851..df37d3effb5 100644
--- a/frontend/src/metabase/timelines/collections/containers/TimelineArchiveModal/TimelineArchiveModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/TimelineArchiveModal/TimelineArchiveModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import type { Timeline, TimelineEvent } from "metabase-types/api";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/timelines/collections/containers/TimelineDetailsModal/TimelineDetailsModal.tsx b/frontend/src/metabase/timelines/collections/containers/TimelineDetailsModal/TimelineDetailsModal.tsx
index 3d74da52a10..8b600ffb670 100644
--- a/frontend/src/metabase/timelines/collections/containers/TimelineDetailsModal/TimelineDetailsModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/TimelineDetailsModal/TimelineDetailsModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import type { Timeline, TimelineEvent } from "metabase-types/api";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/timelines/collections/containers/TimelineListArchiveModal/TimelineListArchiveModal.tsx b/frontend/src/metabase/timelines/collections/containers/TimelineListArchiveModal/TimelineListArchiveModal.tsx
index 8efd721d327..673ac3c7289 100644
--- a/frontend/src/metabase/timelines/collections/containers/TimelineListArchiveModal/TimelineListArchiveModal.tsx
+++ b/frontend/src/metabase/timelines/collections/containers/TimelineListArchiveModal/TimelineListArchiveModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import _ from "underscore";
 
 import Collections from "metabase/entities/collections";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import type { Collection, TimelineEvent } from "metabase-types/api";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/timelines/common/containers/EventForm/EventForm.tsx b/frontend/src/metabase/timelines/common/containers/EventForm/EventForm.tsx
index eddd58ff663..5740655f85a 100644
--- a/frontend/src/metabase/timelines/common/containers/EventForm/EventForm.tsx
+++ b/frontend/src/metabase/timelines/common/containers/EventForm/EventForm.tsx
@@ -1,5 +1,4 @@
-import { connect } from "react-redux";
-
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/timelines/questions/containers/EditEventModal/EditEventModal.tsx b/frontend/src/metabase/timelines/questions/containers/EditEventModal/EditEventModal.tsx
index d0e8180a684..1197c9df9ff 100644
--- a/frontend/src/metabase/timelines/questions/containers/EditEventModal/EditEventModal.tsx
+++ b/frontend/src/metabase/timelines/questions/containers/EditEventModal/EditEventModal.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
 import TimelineEvents from "metabase/entities/timeline-events";
+import { connect } from "metabase/lib/redux";
 import { addUndo } from "metabase/redux/undo";
 import EditEventModal from "metabase/timelines/common/components/EditEventModal";
 import type { TimelineEvent } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/questions/containers/MoveEventModal/MoveEventModal.tsx b/frontend/src/metabase/timelines/questions/containers/MoveEventModal/MoveEventModal.tsx
index 235b05717ef..3c962d90490 100644
--- a/frontend/src/metabase/timelines/questions/containers/MoveEventModal/MoveEventModal.tsx
+++ b/frontend/src/metabase/timelines/questions/containers/MoveEventModal/MoveEventModal.tsx
@@ -1,9 +1,9 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Collections, { ROOT_COLLECTION } from "metabase/entities/collections";
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import MoveEventModal from "metabase/timelines/common/components/MoveEventModal";
 import type { Timeline, TimelineEvent } from "metabase-types/api";
 import type { State } from "metabase-types/store";
diff --git a/frontend/src/metabase/timelines/questions/containers/NewEventModal/NewEventModal.tsx b/frontend/src/metabase/timelines/questions/containers/NewEventModal/NewEventModal.tsx
index dcf8d1ad8f7..dcb36f53583 100644
--- a/frontend/src/metabase/timelines/questions/containers/NewEventModal/NewEventModal.tsx
+++ b/frontend/src/metabase/timelines/questions/containers/NewEventModal/NewEventModal.tsx
@@ -1,10 +1,10 @@
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
 import Collections, { ROOT_COLLECTION } from "metabase/entities/collections";
 import TimelineEvents from "metabase/entities/timeline-events";
 import Timelines from "metabase/entities/timelines";
+import { connect } from "metabase/lib/redux";
 import { addUndo } from "metabase/redux/undo";
 import NewEventModal from "metabase/timelines/common/components/NewEventModal";
 import type { Collection, TimelineEvent } from "metabase-types/api";
diff --git a/frontend/src/metabase/timelines/questions/containers/TimelinePanel/TimelinePanel.tsx b/frontend/src/metabase/timelines/questions/containers/TimelinePanel/TimelinePanel.tsx
index 9ab97692b76..240e1b75907 100644
--- a/frontend/src/metabase/timelines/questions/containers/TimelinePanel/TimelinePanel.tsx
+++ b/frontend/src/metabase/timelines/questions/containers/TimelinePanel/TimelinePanel.tsx
@@ -1,8 +1,8 @@
-import { connect } from "react-redux";
 import _ from "underscore";
 
 import Collections, { ROOT_COLLECTION } from "metabase/entities/collections";
 import TimelineEvents from "metabase/entities/timeline-events";
+import { connect } from "metabase/lib/redux";
 import type { TimelineEvent } from "metabase-types/api";
 import type { State } from "metabase-types/store";
 
diff --git a/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx b/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
index 145baf4d6e9..7f3987dc0a3 100644
--- a/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
+++ b/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
@@ -3,7 +3,6 @@ import cx from "classnames";
 import Color from "color";
 import * as d3 from "d3";
 import { Component } from "react";
-import { connect } from "react-redux";
 import ss from "simple-statistics";
 import { t } from "ttag";
 import _ from "underscore";
@@ -12,6 +11,7 @@ import { getMetabaseInstanceUrl } from "embedding-sdk/store/selectors";
 import LoadingSpinner from "metabase/components/LoadingSpinner";
 import CS from "metabase/css/core/index.css";
 import { formatValue } from "metabase/lib/formatting";
+import { connect } from "metabase/lib/redux";
 import MetabaseSettings from "metabase/lib/settings";
 import { getIsEmbeddingSdk } from "metabase/selectors/embed";
 import { MinColumnsError } from "metabase/visualizations/lib/errors";
diff --git a/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.tsx b/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.tsx
index 15efac9bfde..66140352df0 100644
--- a/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.tsx
+++ b/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.tsx
@@ -1,8 +1,8 @@
 import { Component } from "react";
-import { connect } from "react-redux";
 import type * as tippy from "tippy.js";
 
 import { getEventTarget } from "metabase/lib/dom";
+import { connect } from "metabase/lib/redux";
 import { performAction } from "metabase/visualizations/lib/action";
 import type {
   ClickObject,
diff --git a/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx b/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx
index fcbdf440798..ba12f3afbf2 100644
--- a/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx
+++ b/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx
@@ -1,6 +1,5 @@
-import { connect } from "react-redux";
-
 import Tables from "metabase/entities/tables";
+import { connect } from "metabase/lib/redux";
 import {
   closeObjectDetail,
   followForeignKey,
diff --git a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx
index f256660b536..e2a975af8e3 100644
--- a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx
+++ b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx
@@ -2,7 +2,6 @@
 import cx from "classnames";
 import PropTypes from "prop-types";
 import { Component, createRef, forwardRef } from "react";
-import { connect } from "react-redux";
 import { Grid, ScrollSync } from "react-virtualized";
 import { t } from "ttag";
 import _ from "underscore";
@@ -20,6 +19,7 @@ import { withMantineTheme } from "metabase/hoc/MantineTheme";
 import { getScrollBarSize } from "metabase/lib/dom";
 import { formatValue } from "metabase/lib/formatting";
 import { renderRoot, unmountRoot } from "metabase/lib/react-compat";
+import { connect } from "metabase/lib/redux";
 import { setUIControls, zoomInRow } from "metabase/query_builder/actions";
 import {
   getIsShowingRawTable,
diff --git a/frontend/src/metabase/visualizations/components/Visualization/Visualization.jsx b/frontend/src/metabase/visualizations/components/Visualization/Visualization.jsx
index d0868e0cb0d..7bfab7fd96f 100644
--- a/frontend/src/metabase/visualizations/components/Visualization/Visualization.jsx
+++ b/frontend/src/metabase/visualizations/components/Visualization/Visualization.jsx
@@ -1,7 +1,6 @@
 /* eslint-disable react/prop-types */
 import cx from "classnames";
 import { PureComponent } from "react";
-import { connect } from "react-redux";
 import { t } from "ttag";
 import _ from "underscore";
 
@@ -11,6 +10,7 @@ import ExplicitSize from "metabase/components/ExplicitSize";
 import CS from "metabase/css/core/index.css";
 import DashboardS from "metabase/css/dashboard.module.css";
 import { formatNumber } from "metabase/lib/formatting";
+import { connect } from "metabase/lib/redux";
 import { equals } from "metabase/lib/utils";
 import { getIsShowingRawTable } from "metabase/query_builder/selectors";
 import { getIsEmbeddingSdk } from "metabase/selectors/embed";
diff --git a/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.tsx b/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.tsx
index 1e1d6b1ec2c..7b54b40dab4 100644
--- a/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.tsx
+++ b/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.tsx
@@ -2,7 +2,6 @@ import cx from "classnames";
 import type * as React from "react";
 import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { findDOMNode } from "react-dom";
-import { connect } from "react-redux";
 import { useMount, usePrevious } from "react-use";
 import type { OnScrollParams } from "react-virtualized";
 import { AutoSizer, Collection, Grid, ScrollSync } from "react-virtualized";
@@ -18,6 +17,7 @@ import {
   multiLevelPivot,
 } from "metabase/lib/data_grid";
 import { getScrollBarSize } from "metabase/lib/dom";
+import { connect } from "metabase/lib/redux";
 import { getSetting } from "metabase/selectors/settings";
 import { useMantineTheme } from "metabase/ui";
 import {
diff --git a/frontend/test/__support__/storybook.tsx b/frontend/test/__support__/storybook.tsx
index 2a11a258f56..cbb27f80c19 100644
--- a/frontend/test/__support__/storybook.tsx
+++ b/frontend/test/__support__/storybook.tsx
@@ -1,8 +1,8 @@
 // Storybook helpers
-import { Provider } from "react-redux";
 
 import type { MetabaseTheme } from "embedding-sdk";
 import { SdkThemeProvider } from "embedding-sdk/components/private/SdkThemeProvider";
+import { MetabaseReduxProvider } from "metabase/lib/redux";
 import { mainReducers } from "metabase/reducers-main";
 import { StaticVisualization } from "metabase/static-viz/components/StaticVisualization";
 import { createStaticRenderingContext } from "metabase/static-viz/lib/rendering-context";
@@ -22,9 +22,9 @@ export const ReduxProvider = ({
   children: React.ReactNode;
   storeInitialState?: Record<string, any>;
 }) => (
-  <Provider store={getStore(mainReducers, storeInitialState)}>
+  <MetabaseReduxProvider store={getStore(mainReducers, storeInitialState)}>
     {children}
-  </Provider>
+  </MetabaseReduxProvider>
 );
 
 export const VisualizationWrapper = ({
diff --git a/frontend/test/__support__/ui.tsx b/frontend/test/__support__/ui.tsx
index 31fa8a9ffc5..547cb266aa6 100644
--- a/frontend/test/__support__/ui.tsx
+++ b/frontend/test/__support__/ui.tsx
@@ -10,7 +10,6 @@ import { KBarProvider } from "kbar";
 import type * as React from "react";
 import { DragDropContextProvider } from "react-dnd";
 import HTML5Backend from "react-dnd-html5-backend";
-import { Provider } from "react-redux";
 import { Router, useRouterHistory } from "react-router";
 import { routerMiddleware, routerReducer } from "react-router-redux";
 import _ from "underscore";
@@ -25,6 +24,7 @@ import { createMockSdkState } from "embedding-sdk/test/mocks/state";
 import { Api } from "metabase/api";
 import { UndoListing } from "metabase/containers/UndoListing";
 import { baseStyle } from "metabase/css/core/base.styled";
+import { MetabaseReduxProvider } from "metabase/lib/redux";
 import { mainReducers } from "metabase/reducers-main";
 import { publicReducers } from "metabase/reducers-public";
 import { ThemeProvider } from "metabase/ui";
@@ -141,13 +141,13 @@ export function renderWithProviders(
   const wrapper = (props: any) => {
     if (mode === "sdk") {
       return (
-        <Provider store={store}>
+        <MetabaseReduxProvider store={store}>
           <MetabaseProviderInternal
             {...props}
             {...sdkProviderProps}
             store={store}
           />
-        </Provider>
+        </MetabaseReduxProvider>
       );
     }
 
@@ -203,7 +203,7 @@ export function TestWrapper({
   theme?: MantineThemeOverride;
 }): JSX.Element {
   return (
-    <Provider store={store}>
+    <MetabaseReduxProvider store={store}>
       <MaybeDNDProvider hasDND={withDND}>
         <ThemeProvider theme={theme}>
           <GlobalStylesForTest />
@@ -216,7 +216,7 @@ export function TestWrapper({
           {withUndos && <UndoListing />}
         </ThemeProvider>
       </MaybeDNDProvider>
-    </Provider>
+    </MetabaseReduxProvider>
   );
 }
 
-- 
GitLab