diff --git a/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.hbs b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.hbs
index e558957c56c..214eec48cc6 100644
--- a/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.hbs
+++ b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.hbs
@@ -5,5 +5,6 @@
     @icon={{button.switchButtonIcon}}
     @disabled={{this.isSwitching}}
     @translatedLabel={{button.switchButtonLabel}}
+    data-key={{button.key}}
   />
 {{/each}}
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.js b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.js
index 329bf69863e..613de5909d2 100644
--- a/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.js
+++ b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.js
@@ -16,9 +16,13 @@ export default class SwitchPanelButtons extends Component {
 
     const url = panel.lastKnownURL || panel.switchButtonDefaultUrl;
     const destination = url === "/" ? `discovery.${defaultHomepage()}` : url;
-    this.router.transitionTo(destination).finally(() => {
-      this.isSwitching = false;
-      this.sidebarState.setPanel(panel.key);
-    });
+    this.router
+      .transitionTo(destination)
+      .then(() => {
+        this.sidebarState.setPanel(panel.key);
+      })
+      .finally(() => {
+        this.isSwitching = false;
+      });
   }
 }
diff --git a/app/models/user_option.rb b/app/models/user_option.rb
index 87232465f5d..1fb652a271f 100644
--- a/app/models/user_option.rb
+++ b/app/models/user_option.rb
@@ -292,6 +292,7 @@ end
 #  sidebar_link_to_filtered_list        :boolean          default(FALSE), not null
 #  sidebar_show_count_of_new_items      :boolean          default(FALSE), not null
 #  watched_precedence_over_muted        :boolean
+#  chat_separate_sidebar_mode           :integer          default(0), not null
 #
 # Indexes
 #
diff --git a/plugins/chat/app/models/chat/separate_sidebar_mode_site_setting.rb b/plugins/chat/app/models/chat/separate_sidebar_mode_site_setting.rb
new file mode 100644
index 00000000000..f435457acfd
--- /dev/null
+++ b/plugins/chat/app/models/chat/separate_sidebar_mode_site_setting.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Chat
+  class SeparateSidebarModeSiteSetting < EnumSiteSetting
+    def self.valid_value?(val)
+      values.any? { |v| v[:value] == val }
+    end
+
+    def self.values
+      @values ||= [
+        { name: "admin.site_settings.chat_separate_sidebar_mode.never", value: "never" },
+        { name: "admin.site_settings.chat_separate_sidebar_mode.always", value: "always" },
+        { name: "admin.site_settings.chat_separate_sidebar_mode.fullscreen", value: "fullscreen" },
+      ]
+    end
+
+    def self.translate_names?
+      true
+    end
+  end
+end
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-drawer.js b/plugins/chat/assets/javascripts/discourse/components/chat-drawer.js
index 7732db38cff..543143d4689 100644
--- a/plugins/chat/assets/javascripts/discourse/components/chat-drawer.js
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-drawer.js
@@ -171,8 +171,8 @@ export default Component.extend({
   @action
   openURL(url = null) {
     this.chat.activeChannel = null;
-    this.chatStateManager.didOpenDrawer(url);
     this.chatDrawerRouter.stateFor(this._routeFromURL(url));
+    this.chatStateManager.didOpenDrawer(url);
   },
 
   _routeFromURL(url) {
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.hbs b/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.hbs
index 00fb2474a4f..3fd922ddef2 100644
--- a/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.hbs
+++ b/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.hbs
@@ -2,8 +2,9 @@
   href={{this.href}}
   tabindex="0"
   class={{concat-class "icon" "btn-flat" (if this.isActive "active")}}
+  title={{i18n this.title}}
 >
-  {{d-icon "d-chat"}}
+  {{d-icon this.icon}}
   {{#unless this.currentUserInDnD}}
     <Chat::Header::Icon::UnreadIndicator
       @urgentCount={{@urgentCount}}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.js b/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.js
index 6dbf81707d7..7491ec82d31 100644
--- a/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.js
+++ b/plugins/chat/assets/javascripts/discourse/components/chat/header/icon.js
@@ -1,7 +1,7 @@
 import { inject as service } from "@ember/service";
 import Component from "@glimmer/component";
 import getURL from "discourse-common/lib/get-url";
-
+import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
 export default class ChatHeaderIcon extends Component {
   @service currentUser;
   @service site;
@@ -12,6 +12,10 @@ export default class ChatHeaderIcon extends Component {
     return this.args.currentUserInDnD || this.currentUser.isInDoNotDisturb();
   }
 
+  get chatSeparateSidebarMode() {
+    return getUserChatSeparateSidebarMode(this.currentUser);
+  }
+
   get isActive() {
     return (
       this.args.isActive ||
@@ -20,13 +24,38 @@ export default class ChatHeaderIcon extends Component {
     );
   }
 
+  get title() {
+    if (
+      this.chatStateManager.isFullPageActive &&
+      !this.chatSeparateSidebarMode.never
+    ) {
+      return "sidebar.panels.forum.label";
+    }
+
+    return "chat.title_capitalized";
+  }
+
+  get icon() {
+    if (
+      this.chatStateManager.isFullPageActive &&
+      !this.chatSeparateSidebarMode.never
+    ) {
+      return "random";
+    }
+
+    return "d-chat";
+  }
+
   get href() {
-    if (this.chatStateManager.isFullPageActive) {
-      if (this.site.mobileView) {
-        return getURL("/chat");
-      } else {
-        return getURL(this.router.currentURL);
-      }
+    if (this.site.mobileView && this.chatStateManager.isFullPageActive) {
+      return getURL("/chat");
+    }
+
+    if (
+      this.chatStateManager.isFullPageActive &&
+      !this.chatSeparateSidebarMode.never
+    ) {
+      return getURL(this.chatStateManager.lastKnownAppURL || "/");
     }
 
     if (this.chatStateManager.isDrawerActive) {
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js b/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js
index b5e346b62c4..7621e51818c 100644
--- a/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js
+++ b/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js
@@ -14,38 +14,65 @@ const CHAT_ATTRS = [
   "chat_sound",
   "chat_email_frequency",
   "chat_header_indicator_preference",
+  "chat_separate_sidebar_mode",
+];
+
+const EMAIL_FREQUENCY_OPTIONS = [
+  { name: I18n.t("chat.email_frequency.never"), value: "never" },
+  { name: I18n.t("chat.email_frequency.when_away"), value: "when_away" },
 ];
 
 export const HEADER_INDICATOR_PREFERENCE_NEVER = "never";
 export const HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS = "dm_and_mentions";
 export const HEADER_INDICATOR_PREFERENCE_ALL_NEW = "all_new";
-
-const EMAIL_FREQUENCY_OPTIONS = [
-  { name: I18n.t(`chat.email_frequency.never`), value: "never" },
-  { name: I18n.t(`chat.email_frequency.when_away`), value: "when_away" },
-];
-
 const HEADER_INDICATOR_OPTIONS = [
   {
-    name: I18n.t(`chat.header_indicator_preference.all_new`),
+    name: I18n.t("chat.header_indicator_preference.all_new"),
     value: HEADER_INDICATOR_PREFERENCE_ALL_NEW,
   },
   {
-    name: I18n.t(`chat.header_indicator_preference.dm_and_mentions`),
+    name: I18n.t("chat.header_indicator_preference.dm_and_mentions"),
     value: HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
   },
   {
-    name: I18n.t(`chat.header_indicator_preference.never`),
+    name: I18n.t("chat.header_indicator_preference.never"),
     value: HEADER_INDICATOR_PREFERENCE_NEVER,
   },
 ];
 
+const CHAT_SEPARATE_SIDEBAR_MODE_OPTIONS = [
+  {
+    name: I18n.t("admin.site_settings.chat_separate_sidebar_mode.always"),
+    value: "always",
+  },
+  {
+    name: I18n.t("admin.site_settings.chat_separate_sidebar_mode.fullscreen"),
+    value: "fullscreen",
+  },
+  {
+    name: I18n.t("admin.site_settings.chat_separate_sidebar_mode.never"),
+    value: "never",
+  },
+];
+
 export default class PreferencesChatController extends Controller {
   @service chatAudioManager;
+  @service siteSettings;
+
   subpageTitle = I18n.t("chat.admin.title");
 
   emailFrequencyOptions = EMAIL_FREQUENCY_OPTIONS;
   headerIndicatorOptions = HEADER_INDICATOR_OPTIONS;
+  chatSeparateSidebarModeOptions = CHAT_SEPARATE_SIDEBAR_MODE_OPTIONS;
+
+  get chatSeparateSidebarMode() {
+    const mode = this.model.get("user_option.chat_separate_sidebar_mode");
+    if (mode === "default") {
+      return this.siteSettings.chat_separate_sidebar_mode;
+    } else {
+      return mode;
+    }
+  }
 
   @discourseComputed
   chatSounds() {
diff --git a/plugins/chat/assets/javascripts/discourse/initializers/chat-sidebar.js b/plugins/chat/assets/javascripts/discourse/initializers/chat-sidebar.js
index e9c8d2f593a..5e7af1fd0bb 100644
--- a/plugins/chat/assets/javascripts/discourse/initializers/chat-sidebar.js
+++ b/plugins/chat/assets/javascripts/discourse/initializers/chat-sidebar.js
@@ -11,6 +11,7 @@ import { decorateUsername } from "discourse/helpers/decorate-username-selector";
 import { until } from "discourse/lib/formatter";
 import { inject as service } from "@ember/service";
 import ChatModalNewMessage from "discourse/plugins/chat/discourse/components/chat/modal/new-message";
+import getURL from "discourse-common/lib/get-url";
 
 export default {
   name: "chat-sidebar",
@@ -23,6 +24,18 @@ export default {
 
     this.siteSettings = container.lookup("service:site-settings");
 
+    withPluginApi("1.8.0", (api) => {
+      api.addSidebarPanel(
+        (BaseCustomSidebarPanel) =>
+          class ChatSidebarPanel extends BaseCustomSidebarPanel {
+            key = "chat";
+            switchButtonLabel = I18n.t("sidebar.panels.chat.label");
+            switchButtonIcon = "d-chat";
+            switchButtonDefaultUrl = getURL("/chat");
+          }
+      );
+    });
+
     withPluginApi("1.3.0", (api) => {
       if (this.siteSettings.enable_public_channels) {
         api.addSidebarSection(
@@ -180,7 +193,8 @@ export default {
             };
 
             return SidebarChatChannelsSection;
-          }
+          },
+          "chat"
         );
       }
 
@@ -414,7 +428,8 @@ export default {
           };
 
           return SidebarChatDirectMessagesSection;
-        }
+        },
+        "chat"
       );
     });
   },
diff --git a/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js b/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js
index c410763d713..5fdc01b7fd5 100644
--- a/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js
+++ b/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js
@@ -6,6 +6,7 @@ const IGNORE_CHANNEL_WIDE_MENTION = "ignore_channel_wide_mention";
 const CHAT_SOUND = "chat_sound";
 const CHAT_EMAIL_FREQUENCY = "chat_email_frequency";
 const CHAT_HEADER_INDICATOR_PREFERENCE = "chat_header_indicator_preference";
+const CHAT_SEPARATE_SIDEBAR_MODE = "chat_separate_sidebar_mode";
 
 export default {
   name: "chat-user-options",
@@ -20,6 +21,7 @@ export default {
         api.addSaveableUserOptionField(CHAT_SOUND);
         api.addSaveableUserOptionField(CHAT_EMAIL_FREQUENCY);
         api.addSaveableUserOptionField(CHAT_HEADER_INDICATOR_PREFERENCE);
+        api.addSaveableUserOptionField(CHAT_SEPARATE_SIDEBAR_MODE);
       }
     });
   },
diff --git a/plugins/chat/assets/javascripts/discourse/lib/get-user-chat-separate-sidebar-mode.js b/plugins/chat/assets/javascripts/discourse/lib/get-user-chat-separate-sidebar-mode.js
new file mode 100644
index 00000000000..456f364b15a
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/lib/get-user-chat-separate-sidebar-mode.js
@@ -0,0 +1,9 @@
+export function getUserChatSeparateSidebarMode(user) {
+  const mode = user?.get("user_option.chat_separate_sidebar_mode");
+
+  return {
+    never: "never" === mode,
+    always: "always" === mode,
+    fullscreen: "fullscreen" === mode,
+  };
+}
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat.js b/plugins/chat/assets/javascripts/discourse/routes/chat.js
index cae606d06b2..3186d64d233 100644
--- a/plugins/chat/assets/javascripts/discourse/routes/chat.js
+++ b/plugins/chat/assets/javascripts/discourse/routes/chat.js
@@ -4,11 +4,13 @@ import { defaultHomepage } from "discourse/lib/utilities";
 import { inject as service } from "@ember/service";
 import { scrollTop } from "discourse/mixins/scroll-top";
 import { schedule } from "@ember/runloop";
-
+import { withPluginApi } from "discourse/lib/plugin-api";
+import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
 export default class ChatRoute extends DiscourseRoute {
   @service chat;
   @service router;
   @service chatStateManager;
+  @service currentUser;
 
   titleToken() {
     return I18n.t("chat.title_capitalized");
@@ -57,6 +59,16 @@ export default class ChatRoute extends DiscourseRoute {
   }
 
   activate() {
+    withPluginApi("1.8.0", (api) => {
+      api.setSidebarPanel("chat");
+      if (getUserChatSeparateSidebarMode(this.currentUser).never) {
+        api.setCombinedSidebarMode();
+        api.hideSidebarSwitchPanelButtons();
+      } else {
+        api.setSeparatedSidebarMode();
+      }
+    });
+
     this.chatStateManager.storeAppURL();
     this.chat.updatePresence();
 
@@ -68,6 +80,23 @@ export default class ChatRoute extends DiscourseRoute {
   }
 
   deactivate(transition) {
+    withPluginApi("1.8.0", (api) => {
+      api.setSidebarPanel("main");
+
+      const chatSeparateSidebarMode = getUserChatSeparateSidebarMode(
+        this.currentUser
+      );
+      if (chatSeparateSidebarMode.fullscreen) {
+        api.setCombinedSidebarMode();
+        api.showSidebarSwitchPanelButtons();
+      } else if (chatSeparateSidebarMode.always) {
+        api.setSeparatedSidebarMode();
+      } else {
+        api.setCombinedSidebarMode();
+        api.hideSidebarSwitchPanelButtons();
+      }
+    });
+
     if (transition) {
       const url = this.router.urlFor(transition.from.name);
       this.chatStateManager.storeChatURL(url);
diff --git a/plugins/chat/assets/javascripts/discourse/services/chat-state-manager.js b/plugins/chat/assets/javascripts/discourse/services/chat-state-manager.js
index 88608e1a41d..c1956798632 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat-state-manager.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat-state-manager.js
@@ -4,6 +4,8 @@ import { tracked } from "@glimmer/tracking";
 import KeyValueStore from "discourse/lib/key-value-store";
 import Site from "discourse/models/site";
 import getURL from "discourse-common/lib/get-url";
+import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
+import { withPluginApi } from "discourse/lib/plugin-api";
 
 const PREFERRED_MODE_KEY = "preferred_mode";
 const PREFERRED_MODE_STORE_NAMESPACE = "discourse_chat_";
@@ -56,6 +58,16 @@ export default class ChatStateManager extends Service {
   }
 
   didOpenDrawer(url = null) {
+    withPluginApi("1.8.0", (api) => {
+      if (getUserChatSeparateSidebarMode(this.currentUser).always) {
+        api.setSidebarPanel("main");
+        api.setSeparatedSidebarMode();
+        api.hideSidebarSwitchPanelButtons();
+      } else {
+        api.setCombinedSidebarMode();
+      }
+    });
+
     this.isDrawerActive = true;
     this.isDrawerExpanded = true;
 
@@ -68,6 +80,24 @@ export default class ChatStateManager extends Service {
   }
 
   didCloseDrawer() {
+    withPluginApi("1.8.0", (api) => {
+      api.setSidebarPanel("main");
+
+      const chatSeparateSidebarMode = getUserChatSeparateSidebarMode(
+        this.currentUser
+      );
+      if (chatSeparateSidebarMode.fullscreen) {
+        api.setCombinedSidebarMode();
+        api.showSidebarSwitchPanelButtons();
+      } else if (chatSeparateSidebarMode.always) {
+        api.setSeparatedSidebarMode();
+        api.showSidebarSwitchPanelButtons();
+      } else {
+        api.setCombinedSidebarMode();
+        api.hideSidebarSwitchPanelButtons();
+      }
+    });
+
     this.isDrawerActive = false;
     this.isDrawerExpanded = false;
     this.chat.updatePresence();
diff --git a/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.hbs b/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.hbs
index 15eb67ad181..b90fe1b44b8 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.hbs
+++ b/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.hbs
@@ -99,6 +99,23 @@
   />
 </div>
 
+<div
+  class="control-group chat-setting controls-dropdown"
+  data-setting-name="user_chat_separate_sidebar_mode"
+>
+  <label for="user_chat_separate_sidebar_mode">
+    {{i18n "chat.separate_sidebar_mode.title"}}
+  </label>
+
+  <ComboBox
+    @valueProperty="value"
+    @content={{this.chatSeparateSidebarModeOptions}}
+    @value={{this.chatSeparateSidebarMode}}
+    @id="user_chat_separate_sidebar_mode"
+    @onChange={{action (mut this.model.user_option.chat_separate_sidebar_mode)}}
+  />
+</div>
+
 <SaveControls
   @id="user_chat_preference_save"
   @model={{this.model}}
diff --git a/plugins/chat/assets/javascripts/discourse/widgets/chat-header-icon.js b/plugins/chat/assets/javascripts/discourse/widgets/chat-header-icon.js
index dcacd94f499..30717cdc102 100644
--- a/plugins/chat/assets/javascripts/discourse/widgets/chat-header-icon.js
+++ b/plugins/chat/assets/javascripts/discourse/widgets/chat-header-icon.js
@@ -4,7 +4,6 @@ import { hbs } from "ember-cli-htmlbars";
 
 export default createWidget("chat-header-icon", {
   tagName: "li.header-dropdown-toggle.chat-header-icon",
-  title: "chat.title_capitalized",
 
   services: ["chat"],
 
diff --git a/plugins/chat/config/locales/client.en.yml b/plugins/chat/config/locales/client.en.yml
index f77cb687258..86e0e27b9f1 100644
--- a/plugins/chat/config/locales/client.en.yml
+++ b/plugins/chat/config/locales/client.en.yml
@@ -4,6 +4,10 @@ en:
       site_settings:
         categories:
           chat: Chat
+        chat_separate_sidebar_mode:
+          always: "Always"
+          fullscreen: "When chat is in fullscreen"
+          never: "Never"
       logs:
         staff_actions:
           actions:
@@ -104,6 +108,8 @@ en:
         all_new: "All New Messages"
         dm_and_mentions: "Direct Messages and Mentions"
         never: "Never"
+      separate_sidebar_mode:
+        title: "Show separate sidebar modes for forum and chat"
       enable: "Enable chat"
       flag: "Flag"
       emoji: "Insert emoji"
@@ -685,3 +691,8 @@ en:
       sections:
         chat:
           title: Chat
+
+    sidebar:
+      panels:
+        chat:
+          label: "Chat"
diff --git a/plugins/chat/config/locales/server.en.yml b/plugins/chat/config/locales/server.en.yml
index a8b4c143a43..a8027d07859 100644
--- a/plugins/chat/config/locales/server.en.yml
+++ b/plugins/chat/config/locales/server.en.yml
@@ -1,5 +1,6 @@
 en:
   site_settings:
+    chat_separate_sidebar_mode: "Show separate sidebar modes for forum and chat."
     chat_enabled: "Enable the chat plugin."
     enable_public_channels: "Enable public channels based on categories."
     chat_allowed_groups: "Users in these groups can chat. Note that staff can always access chat."
diff --git a/plugins/chat/config/settings.yml b/plugins/chat/config/settings.yml
index e5958c82cde..dd5e54ecb7c 100644
--- a/plugins/chat/config/settings.yml
+++ b/plugins/chat/config/settings.yml
@@ -116,3 +116,8 @@ chat:
   max_chat_draft_length:
     default: 50_000
     hidden: true
+  chat_separate_sidebar_mode:
+    client: true
+    default: "never"
+    type: enum
+    enum: "Chat::SeparateSidebarModeSiteSetting"
diff --git a/plugins/chat/db/migrate/20230722124044_add_chat_separate_sidebar_mode_user_option.rb b/plugins/chat/db/migrate/20230722124044_add_chat_separate_sidebar_mode_user_option.rb
new file mode 100644
index 00000000000..597252808d2
--- /dev/null
+++ b/plugins/chat/db/migrate/20230722124044_add_chat_separate_sidebar_mode_user_option.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddChatSeparateSidebarModeUserOption < ActiveRecord::Migration[7.0]
+  def change
+    add_column :user_options, :chat_separate_sidebar_mode, :integer, default: 0, null: false
+  end
+end
diff --git a/plugins/chat/lib/chat/user_option_extension.rb b/plugins/chat/lib/chat/user_option_extension.rb
index 290f6361d55..467a78c9b47 100644
--- a/plugins/chat/lib/chat/user_option_extension.rb
+++ b/plugins/chat/lib/chat/user_option_extension.rb
@@ -14,19 +14,32 @@ module Chat
         @chat_email_frequencies ||= { never: 0, when_away: 1 }
       end
 
+      # Avoid attempting to override when autoloading
+      if !base.method_defined?(:send_chat_email_never?)
+        base.enum :chat_email_frequency, base.chat_email_frequencies, prefix: "send_chat_email"
+      end
+
       def base.chat_header_indicator_preferences
         @chat_header_indicator_preferences ||= { all_new: 0, dm_and_mentions: 1, never: 2 }
       end
 
-      if !base.method_defined?(:send_chat_email_never?) # Avoid attempting to override when autoloading
-        base.enum :chat_email_frequency, base.chat_email_frequencies, prefix: "send_chat_email"
-      end
-
-      if !base.method_defined?(:chat_header_indicator_never?) # Avoid attempting to override when autoloading
+      # Avoid attempting to override when autoloading
+      if !base.method_defined?(:chat_header_indicator_never?)
         base.enum :chat_header_indicator_preference,
                   base.chat_header_indicator_preferences,
                   prefix: "chat_header_indicator"
       end
+
+      def base.chat_separate_sidebar_mode
+        @chat_separate_sidebar_mode ||= { default: 0, never: 1, always: 2, fullscreen: 3 }
+      end
+
+      # Avoid attempting to override when autoloading
+      if !base.method_defined?(:chat_separate_sidebar_mode_default?)
+        base.enum :chat_separate_sidebar_mode,
+                  base.chat_separate_sidebar_mode,
+                  prefix: "chat_separate_sidebar_mode"
+      end
     end
   end
 end
diff --git a/plugins/chat/plugin.rb b/plugins/chat/plugin.rb
index 16584f9de06..d022eecb42d 100644
--- a/plugins/chat/plugin.rb
+++ b/plugins/chat/plugin.rb
@@ -47,6 +47,7 @@ after_initialize do
   UserUpdater::OPTION_ATTR.push(:ignore_channel_wide_mention)
   UserUpdater::OPTION_ATTR.push(:chat_email_frequency)
   UserUpdater::OPTION_ATTR.push(:chat_header_indicator_preference)
+  UserUpdater::OPTION_ATTR.push(:chat_separate_sidebar_mode)
 
   register_reviewable_type Chat::ReviewableMessage
 
@@ -297,6 +298,12 @@ after_initialize do
     object.chat_header_indicator_preference
   end
 
+  add_to_serializer(:user_option, :chat_separate_sidebar_mode) { object.chat_separate_sidebar_mode }
+
+  add_to_serializer(:current_user_option, :chat_separate_sidebar_mode) do
+    object.chat_separate_sidebar_mode
+  end
+
   RETENTION_SETTINGS_TO_USER_OPTION_FIELDS = {
     chat_channel_retention_days: :dismissed_channel_retention_reminder,
     chat_dm_retention_days: :dismissed_dm_retention_reminder,
diff --git a/plugins/chat/spec/models/user_option_spec.rb b/plugins/chat/spec/models/user_option_spec.rb
new file mode 100644
index 00000000000..481f7e3b55c
--- /dev/null
+++ b/plugins/chat/spec/models/user_option_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+RSpec.describe UserOption do
+  describe "#chat_separate_sidebar_mode" do
+    it "is present" do
+      expect(described_class.new.chat_separate_sidebar_mode).to eq("default")
+    end
+  end
+end
diff --git a/plugins/chat/spec/serializer/current_user_serializer_spec.rb b/plugins/chat/spec/serializer/current_user_serializer_spec.rb
index 2e2fd20a0ef..d1a2a7c52ed 100644
--- a/plugins/chat/spec/serializer/current_user_serializer_spec.rb
+++ b/plugins/chat/spec/serializer/current_user_serializer_spec.rb
@@ -13,6 +13,12 @@ RSpec.describe CurrentUserSerializer do
     current_user.user_option.update(chat_enabled: true)
   end
 
+  describe "#chat_separate_sidebar_mode" do
+    it "is present" do
+      expect(serializer.as_json[:user_option][:chat_separate_sidebar_mode]).to eq("default")
+    end
+  end
+
   describe "#chat_drafts" do
     context "when user can't chat" do
       before { SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:staff] }
diff --git a/plugins/chat/spec/serializer/user_serializer_spec.rb b/plugins/chat/spec/serializer/user_serializer_spec.rb
new file mode 100644
index 00000000000..f4b1ed28c05
--- /dev/null
+++ b/plugins/chat/spec/serializer/user_serializer_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+RSpec.describe UserSerializer do
+  fab!(:current_user) { Fabricate(:user) }
+
+  let(:serializer) do
+    described_class.new(current_user, scope: Guardian.new(current_user), root: false)
+  end
+
+  describe "#chat_separate_sidebar_mode" do
+    it "is present" do
+      expect(serializer.as_json[:user_option][:chat_separate_sidebar_mode]).to eq("default")
+    end
+  end
+end
diff --git a/plugins/chat/spec/system/navigation_spec.rb b/plugins/chat/spec/system/navigation_spec.rb
index 40bead2f3d0..b41513f9198 100644
--- a/plugins/chat/spec/system/navigation_spec.rb
+++ b/plugins/chat/spec/system/navigation_spec.rb
@@ -19,6 +19,9 @@ RSpec.describe "Navigation", type: :system do
 
   before do
     chat_system_bootstrap(current_user, [category_channel, category_channel_2])
+    current_user.user_option.update(
+      chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:never],
+    )
     sign_in(current_user)
   end
 
@@ -36,7 +39,6 @@ RSpec.describe "Navigation", type: :system do
 
   context "when clicking chat icon on mobile and is viewing channel" do
     it "navigates to index", mobile: true do
-      visit("/chat")
       chat_page.visit_channel(category_channel_2)
       chat_page.open_from_header
 
@@ -44,18 +46,6 @@ RSpec.describe "Navigation", type: :system do
     end
   end
 
-  context "when clicking chat icon on desktop and is viewing channel" do
-    it "stays on channel page" do
-      visit("/chat")
-      chat_page.visit_channel(category_channel_2)
-      chat_page.open_from_header
-
-      expect(page).to have_current_path(
-        chat.channel_path(category_channel_2.slug, category_channel_2.id),
-      )
-    end
-  end
-
   context "when visiting /chat" do
     it "opens full page" do
       chat_page.open
diff --git a/plugins/chat/spec/system/page_objects/chat/chat.rb b/plugins/chat/spec/system/page_objects/chat/chat.rb
index 6a77ed8402b..d00db1c3735 100644
--- a/plugins/chat/spec/system/page_objects/chat/chat.rb
+++ b/plugins/chat/spec/system/page_objects/chat/chat.rb
@@ -17,6 +17,12 @@ module PageObjects
         )
       end
 
+      def prefers_drawer
+        page.execute_script(
+          "window.localStorage.setItem('discourse_chat_preferred_mode', '\"DRAWER_CHAT\"');",
+        )
+      end
+
       def open_from_header
         find(".chat-header-icon").click
       end
diff --git a/plugins/chat/spec/system/page_objects/chat/components/header.rb b/plugins/chat/spec/system/page_objects/chat/components/header.rb
new file mode 100644
index 00000000000..b9c78052946
--- /dev/null
+++ b/plugins/chat/spec/system/page_objects/chat/components/header.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module PageObjects
+  module Components
+    module Chat
+      class Header < PageObjects::Components::Base
+        def has_open_chat_button?
+          has_css?(".d-header .chat-header-icon .d-icon-d-chat")
+        end
+
+        def has_open_forum_button?
+          has_css?(".d-header .chat-header-icon .d-icon-random")
+        end
+
+        def has_no_chat_button?
+          has_no_css?(".d-header .chat-header-icon")
+        end
+      end
+    end
+  end
+end
diff --git a/plugins/chat/spec/system/separate_sidebar_mode_spec.rb b/plugins/chat/spec/system/separate_sidebar_mode_spec.rb
new file mode 100644
index 00000000000..265a3b22984
--- /dev/null
+++ b/plugins/chat/spec/system/separate_sidebar_mode_spec.rb
@@ -0,0 +1,202 @@
+# frozen_string_literal: true
+
+RSpec.describe "Separate sidebar mode", type: :system do
+  let(:chat_page) { PageObjects::Pages::Chat.new }
+  let(:sidebar_page) { PageObjects::Pages::Sidebar.new }
+  let(:sidebar_component) { PageObjects::Components::NavigationMenu::Sidebar.new }
+  let(:chat_drawer_page) { PageObjects::Pages::ChatDrawer.new }
+  let(:header_component) { PageObjects::Components::Chat::Header.new }
+
+  fab!(:current_user) { Fabricate(:user) }
+  fab!(:channel_1) { Fabricate(:chat_channel) }
+
+  before do
+    SiteSetting.navigation_menu = "sidebar"
+    channel_1.add(current_user)
+    chat_system_bootstrap
+    sign_in(current_user)
+  end
+
+  describe "when separate sidebar mode is never" do
+    before do
+      current_user.user_option.update!(
+        chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:never],
+      )
+    end
+
+    context "with drawer" do
+      before { chat_page.prefers_drawer }
+
+      it "has the expected behavior" do
+        visit("/")
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+
+        sidebar_page.open_channel(channel_1)
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+
+        chat_drawer_page.close
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+      end
+    end
+
+    context "with full page" do
+      before { chat_page.prefers_full_page }
+
+      it "has the expected behavior" do
+        visit("/")
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+
+        sidebar_page.open_channel(channel_1)
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+
+        find("#site-logo").click
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+      end
+    end
+  end
+
+  describe "when separate sidebar mode is always" do
+    before do
+      current_user.user_option.update(
+        chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:always],
+      )
+    end
+
+    context "with drawer" do
+      before { chat_page.prefers_drawer }
+
+      it "has the expected behavior" do
+        visit("/")
+
+        expect(sidebar_component).to have_switch_button("chat")
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_no_section("chat-channels")
+
+        chat_page.open_from_header
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_no_section("chat-channels")
+
+        chat_drawer_page.close
+
+        expect(sidebar_component).to have_switch_button("chat")
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_no_section("chat-channels")
+      end
+    end
+
+    context "with full page" do
+      before { chat_page.prefers_full_page }
+
+      it "has the expected behavior" do
+        visit("/")
+
+        expect(sidebar_component).to have_switch_button("chat")
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_no_section("chat-channels")
+        expect(sidebar_component).to have_section("Categories")
+
+        chat_page.open_from_header
+
+        expect(sidebar_component).to have_switch_button("main")
+        expect(header_component).to have_open_forum_button
+        expect(sidebar_component).to have_section("chat-channels")
+        expect(sidebar_component).to have_no_section("Categories")
+
+        find("#site-logo").click
+
+        expect(sidebar_component).to have_switch_button("chat")
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_no_section("chat-channels")
+        expect(sidebar_component).to have_section("Categories")
+      end
+    end
+  end
+
+  describe "when separate sidebar mode is fullscreen" do
+    before do
+      current_user.user_option.update(
+        chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:fullscreen],
+      )
+    end
+
+    context "with drawer" do
+      before { chat_page.prefers_drawer }
+
+      it "has the expected behavior" do
+        visit("/")
+
+        expect(sidebar_component).to have_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+
+        sidebar_page.open_channel(channel_1)
+
+        expect(sidebar_component).to have_no_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+
+        chat_drawer_page.close
+
+        expect(sidebar_component).to have_switch_button
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("Categories")
+        expect(sidebar_component).to have_section("chat-channels")
+      end
+    end
+
+    context "with full page" do
+      before { chat_page.prefers_full_page }
+
+      it "has the expected behavior" do
+        visit("/")
+
+        expect(sidebar_component).to have_switch_button("chat")
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("chat-channels")
+        expect(sidebar_component).to have_section("Categories")
+
+        sidebar_page.open_channel(channel_1)
+
+        expect(sidebar_component).to have_switch_button("main")
+        expect(header_component).to have_open_forum_button
+        expect(sidebar_component).to have_section("chat-channels")
+        expect(sidebar_component).to have_no_section("Categories")
+
+        find("#site-logo").click
+
+        expect(sidebar_component).to have_switch_button("chat")
+        expect(header_component).to have_open_chat_button
+        expect(sidebar_component).to have_section("chat-channels")
+        expect(sidebar_component).to have_section("Categories")
+      end
+    end
+  end
+end
diff --git a/plugins/chat/spec/system/user_chat_preferences_spec.rb b/plugins/chat/spec/system/user_chat_preferences_spec.rb
index 69ade2eb6a1..3657893c172 100644
--- a/plugins/chat/spec/system/user_chat_preferences_spec.rb
+++ b/plugins/chat/spec/system/user_chat_preferences_spec.rb
@@ -25,22 +25,32 @@ RSpec.describe "User chat preferences", type: :system do
 
   it "can select chat sound" do
     visit("/u/#{current_user.username}/preferences/chat")
-    find("#user_chat_sounds .select-kit-header[data-value]").click
-    find("[data-value='bell']").click
+    select_kit = PageObjects::Components::SelectKit.new("#user_chat_sounds")
+    select_kit.expand
+    select_kit.select_row_by_value("bell")
     find(".save-changes").click
 
-    expect(page).to have_css("#user_chat_sounds .select-kit-header[data-value='bell']")
+    expect(select_kit).to have_selected_value("bell")
   end
 
   it "can select header_indicator_preference" do
     visit("/u/#{current_user.username}/preferences/chat")
-    find("#user_chat_header_indicator_preference .select-kit-header[data-value]").click
-    find("[data-value='dm_and_mentions']").click
+    select_kit = PageObjects::Components::SelectKit.new("#user_chat_header_indicator_preference")
+    select_kit.expand
+    select_kit.select_row_by_value("dm_and_mentions")
     find(".save-changes").click
 
-    expect(page).to have_css(
-      "#user_chat_header_indicator_preference .select-kit-header[data-value='dm_and_mentions']",
-    )
+    expect(select_kit).to have_selected_value("dm_and_mentions")
+  end
+
+  it "can select separate sidebar mode" do
+    visit("/u/#{current_user.username}/preferences/chat")
+    select_kit = PageObjects::Components::SelectKit.new("#user_chat_separate_sidebar_mode")
+    select_kit.expand
+    select_kit.select_row_by_value("fullscreen")
+    find(".save-changes").click
+
+    expect(select_kit).to have_selected_value("fullscreen")
   end
 
   context "as an admin on another user's preferences" do
diff --git a/plugins/chat/test/javascripts/components/chat-header-icon-test.js b/plugins/chat/test/javascripts/components/chat-header-icon-test.js
new file mode 100644
index 00000000000..192fb6914e8
--- /dev/null
+++ b/plugins/chat/test/javascripts/components/chat-header-icon-test.js
@@ -0,0 +1,44 @@
+import { module, test } from "qunit";
+import { setupRenderingTest } from "discourse/tests/helpers/component-test";
+import { render } from "@ember/test-helpers";
+import { hbs } from "ember-cli-htmlbars";
+import sinon from "sinon";
+import I18n from "I18n";
+
+module("Discourse Chat | Component | chat-header-icon", function (hooks) {
+  setupRenderingTest(hooks);
+
+  hooks.beforeEach(function () {});
+
+  test("full page - never separated sidebar mode", async function (assert) {
+    this.currentUser.user_option.chat_separate_sidebar_mode = "never";
+    sinon
+      .stub(this.owner.lookup("service:chat-state-manager"), "isFullPageActive")
+      .value(true);
+
+    await render(hbs`<Chat::Header::Icon />`);
+
+    assert
+      .dom(".icon.btn-flat")
+      .hasAttribute("title", I18n.t("chat.title_capitalized"))
+      .hasAttribute("href", "/chat");
+
+    assert.dom(".d-icon-d-chat").exists();
+  });
+
+  test("full page - always separated mode", async function (assert) {
+    this.currentUser.user_option.chat_separate_sidebar_mode = "always";
+    sinon
+      .stub(this.owner.lookup("service:chat-state-manager"), "isFullPageActive")
+      .value(true);
+
+    await render(hbs`<Chat::Header::Icon />`);
+
+    assert
+      .dom(".icon.btn-flat")
+      .hasAttribute("title", I18n.t("sidebar.panels.forum.label"))
+      .hasAttribute("href", "/latest");
+
+    assert.dom(".d-icon-random").exists();
+  });
+});
diff --git a/spec/system/page_objects/components/navigation_menu/base.rb b/spec/system/page_objects/components/navigation_menu/base.rb
index a7b1ab7edcd..7f41ea2447a 100644
--- a/spec/system/page_objects/components/navigation_menu/base.rb
+++ b/spec/system/page_objects/components/navigation_menu/base.rb
@@ -34,6 +34,22 @@ module PageObjects
           has_no_css?(".sidebar-sections [data-section-name='#{name.parameterize}']")
         end
 
+        def has_switch_button?(key = nil)
+          if key
+            page.has_css?(".sidebar__panel-switch-button[data-key='#{key.parameterize}']")
+          else
+            page.has_css?(".sidebar__panel-switch-button")
+          end
+        end
+
+        def has_no_switch_button?(key = nil)
+          if key
+            page.has_no_css?(".sidebar__panel-switch-button[data-key='#{key.parameterize}']")
+          else
+            page.has_no_css?(".sidebar__panel-switch-button")
+          end
+        end
+
         def has_categories_section?
           has_section?("Categories")
         end