diff --git src/bp-blogs/bp-blogs-widgets.php src/bp-blogs/bp-blogs-widgets.php
index b0edfea71..1b7e1bed3 100644
--- src/bp-blogs/bp-blogs-widgets.php
+++ src/bp-blogs/bp-blogs-widgets.php
@@ -10,6 +10,15 @@
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
+/**
+ * Registers the Recent Posts Legacy Widget.
+ *
+ * @since 10.0.0
+ */
+function bp_blogs_register_recent_posts_widget() {
+	register_widget( 'BP_Blogs_Recent_Posts_Widget' );
+}
+
 /**
  * Register the widgets for the Blogs component.
  */
@@ -17,7 +26,7 @@ function bp_blogs_register_widgets() {
 	global $wpdb;
 
 	if ( bp_is_active( 'activity' ) && bp_is_root_blog( $wpdb->blogid ) ) {
-		add_action( 'widgets_init', function() { register_widget( 'BP_Blogs_Recent_Posts_Widget' ); } );
+		add_action( 'widgets_init', 'bp_blogs_register_recent_posts_widget' );
 	}
 }
 add_action( 'bp_register_widgets', 'bp_blogs_register_widgets' );
diff --git src/bp-core/bp-core-widgets.php src/bp-core/bp-core-widgets.php
index 17be2801a..53ae6d981 100644
--- src/bp-core/bp-core-widgets.php
+++ src/bp-core/bp-core-widgets.php
@@ -10,12 +10,89 @@
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
+/**
+ * Should BuddyPress load Legacy Widgets?
+ *
+ * @since 10.0.0
+ *
+ * @return bool False if BuddyPress shouldn't load Legacy Widgets. True otherwise.
+ */
+function bp_core_retain_legacy_widgets() {
+	$theme_supports = current_theme_supports( 'widgets-block-editor' );
+	$wp_supports    = bp_is_running_wp( '5.8.0' );
+
+	/** This filter is documented in wp-includes/widgets.php */
+	$block_widgets_enabled = $theme_supports && apply_filters( 'use_widgets_block_editor', $wp_supports );
+
+	$retain_legacy_widgets = true;
+	if ( $block_widgets_enabled ) {
+		$retain_legacy_widgets = false;
+	}
+
+	/**
+	 * Filter here to force Legacy Widgets to be retained or not.
+	 *
+	 * @since 10.0.0
+	 *
+	 * @param bool $retain_legacy_widgets False if BuddyPress shouldn't load Legacy Widgets. True otherwise.
+	 */
+	return apply_filters( 'bp_core_retain_legacy_widgets', $retain_legacy_widgets );
+}
+
+/**
+ * Registers the Login widget.
+ *
+ * @since 10.0.0
+ */
+function bp_core_register_login_widget() {
+	register_widget( 'BP_Core_Login_Widget' );
+}
+
 /**
  * Register bp-core widgets.
  *
  * @since 1.0.0
  */
 function bp_core_register_widgets() {
-	add_action( 'widgets_init', function() { register_widget( 'BP_Core_Login_Widget' ); } );
+	add_action( 'widgets_init', 'bp_core_register_login_widget' );
 }
 add_action( 'bp_register_widgets', 'bp_core_register_widgets' );
+
+/**
+ * Checks whether BuddyPress should unhook Legacy Widget registrations.
+ *
+ * @since 10.0.0
+ */
+function bp_core_maybe_unhook_legacy_widgets() {
+	if ( bp_core_retain_legacy_widgets() ) {
+		return;
+	}
+
+	$callbacks = array(
+		'bp_core_register_login_widget',
+		'bp_members_register_members_widget',
+		'bp_members_register_whos_online_widget',
+		'bp_members_register_recently_active_widget',
+	);
+
+	if ( bp_is_active( 'friends' ) ) {
+		$callbacks[] = 'bp_friends_register_friends_widget';
+	}
+
+	if ( bp_is_active( 'groups' ) ) {
+		$callbacks[] = 'bp_groups_register_groups_widget';
+	}
+
+	if ( bp_is_active( 'messages' ) ) {
+		$callbacks[] = 'bp_messages_register_sitewide_notices_widget';
+	}
+
+	if ( bp_is_active( 'blogs' ) && bp_is_active( 'activity' ) && bp_is_root_blog() ) {
+		$callbacks[] = 'bp_blogs_register_recent_posts_widget';
+	}
+
+	foreach ( $callbacks as $callback ) {
+		remove_action( 'widgets_init', $callback );
+	}
+}
+add_action( 'widgets_init', 'bp_core_maybe_unhook_legacy_widgets', 0 );
diff --git src/bp-friends/bp-friends-widgets.php src/bp-friends/bp-friends-widgets.php
index 9858b7c78..732f48de8 100644
--- src/bp-friends/bp-friends-widgets.php
+++ src/bp-friends/bp-friends-widgets.php
@@ -10,6 +10,15 @@
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
+/**
+ * Registers the Friends Legacy Widget.
+ *
+ * @since 10.0.0
+ */
+function bp_friends_register_friends_widget() {
+	register_widget( 'BP_Core_Friends_Widget' );
+}
+
 /**
  * Register the friends widget.
  *
@@ -27,12 +36,7 @@ function bp_friends_register_widgets() {
 		return;
 	}
 
-	add_action(
-		'widgets_init',
-		function() {
-			register_widget( 'BP_Core_Friends_Widget' );
-		}
-	);
+	add_action( 'widgets_init', 'bp_friends_register_friends_widget' );
 }
 add_action( 'bp_register_widgets', 'bp_friends_register_widgets' );
 
diff --git src/bp-groups/bp-groups-widgets.php src/bp-groups/bp-groups-widgets.php
index 937bb14cb..50516eb49 100644
--- src/bp-groups/bp-groups-widgets.php
+++ src/bp-groups/bp-groups-widgets.php
@@ -10,13 +10,22 @@
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
+/**
+ * Registers the Groups Legacy Widget.
+ *
+ * @since 10.0.0
+ */
+function bp_groups_register_groups_widget() {
+	register_widget( 'BP_Groups_Widget' );
+}
+
 /**
  * Register widgets for groups component.
  *
  * @since 1.0.0
  */
 function groups_register_widgets() {
-	add_action( 'widgets_init', function() { register_widget( 'BP_Groups_Widget' ); } );
+	add_action( 'widgets_init', 'bp_groups_register_groups_widget' );
 }
 add_action( 'bp_register_widgets', 'groups_register_widgets' );
 
diff --git src/bp-members/bp-members-widgets.php src/bp-members/bp-members-widgets.php
index 924980fb3..3d760f22f 100644
--- src/bp-members/bp-members-widgets.php
+++ src/bp-members/bp-members-widgets.php
@@ -10,6 +10,33 @@
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
+/**
+ * Registers the Members Legacy Widget.
+ *
+ * @since 10.0.0
+ */
+function bp_members_register_members_widget() {
+	register_widget( 'BP_Core_Members_Widget' );
+}
+
+/**
+ * Registers the "Who's online?" Legacy Widget.
+ *
+ * @since 10.0.0
+ */
+function bp_members_register_whos_online_widget() {
+	register_widget( 'BP_Core_Whos_Online_Widget' );
+}
+
+/**
+ * Registers the "Recently Active" Legacy Widget.
+ *
+ * @since 10.0.0
+ */
+function bp_members_register_recently_active_widget() {
+	register_widget( 'BP_Core_Recently_Active_Widget' );
+}
+
 /**
  * Register bp-members widgets.
  *
@@ -18,26 +45,9 @@ defined( 'ABSPATH' ) || exit;
  * @since 2.2.0
  */
 function bp_members_register_widgets() {
-	add_action(
-		'widgets_init',
-		function() {
-			return register_widget( 'BP_Core_Members_Widget' );
-		}
-	);
-
-	add_action(
-		'widgets_init',
-		function() {
-			return register_widget( 'BP_Core_Whos_Online_Widget' );
-		}
-	);
-
-	add_action(
-		'widgets_init',
-		function() {
-			return register_widget( 'BP_Core_Recently_Active_Widget' );
-		}
-	);
+	add_action( 'widgets_init', 'bp_members_register_members_widget' );
+	add_action( 'widgets_init', 'bp_members_register_whos_online_widget' );
+	add_action( 'widgets_init', 'bp_members_register_recently_active_widget' );
 }
 add_action( 'bp_register_widgets', 'bp_members_register_widgets' );
 
diff --git src/bp-messages/bp-messages-widgets.php src/bp-messages/bp-messages-widgets.php
index cd8ffd4a0..d9bf3d1e6 100644
--- src/bp-messages/bp-messages-widgets.php
+++ src/bp-messages/bp-messages-widgets.php
@@ -10,17 +10,21 @@
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
+/**
+ * Registers the Sitewide Notices Legacy Widget.
+ *
+ * @since 10.0.0
+ */
+function bp_messages_register_sitewide_notices_widget() {
+	register_widget( 'BP_Messages_Sitewide_Notices_Widget' );
+}
+
 /**
  * Register widgets for the Messages component.
  *
  * @since 1.9.0
  */
 function bp_messages_register_widgets() {
-	add_action(
-		'widgets_init',
-		function() {
-			register_widget( 'BP_Messages_Sitewide_Notices_Widget' );
-		}
-	);
+	add_action( 'widgets_init', 'bp_messages_register_sitewide_notices_widget' );
 }
 add_action( 'bp_register_widgets', 'bp_messages_register_widgets' );
diff --git src/bp-templates/bp-nouveau/buddypress-functions.php src/bp-templates/bp-nouveau/buddypress-functions.php
index bffb1ce40..a9ccaee8a 100644
--- src/bp-templates/bp-nouveau/buddypress-functions.php
+++ src/bp-templates/bp-nouveau/buddypress-functions.php
@@ -196,7 +196,9 @@ class BP_Nouveau extends BP_Theme_Compat {
 		add_action( 'widgets_init', 'bp_nouveau_register_sidebars', 11 );
 
 		// Register the Primary Object nav widget.
-		add_action( 'bp_widgets_init', array( 'BP_Nouveau_Object_Nav_Widget', 'register_widget' ) );
+		if ( bp_core_retain_legacy_widgets() ) {
+			add_action( 'bp_widgets_init', array( 'BP_Nouveau_Object_Nav_Widget', 'register_widget' ) );
+		}
 
 		// Set the BP Uri for the Ajax customizer preview.
 		add_filter( 'bp_uri', array( $this, 'customizer_set_uri' ), 10, 1 );
diff --git src/bp-templates/bp-nouveau/includes/activity/loader.php src/bp-templates/bp-nouveau/includes/activity/loader.php
index 9f74fc3ba..73ed8791b 100644
--- src/bp-templates/bp-nouveau/includes/activity/loader.php
+++ src/bp-templates/bp-nouveau/includes/activity/loader.php
@@ -60,7 +60,10 @@ class BP_Nouveau_Activity {
 	protected function includes() {
 		require $this->dir . 'functions.php';
 		require $this->dir . 'template-tags.php';
-		require $this->dir . 'widgets.php';
+
+		if ( bp_core_retain_legacy_widgets() ) {
+			require $this->dir . 'widgets.php';
+		}
 
 		// Test suite requires the AJAX functions early.
 		if ( function_exists( 'tests_add_filter' ) ) {
@@ -87,9 +90,12 @@ class BP_Nouveau_Activity {
 	 */
 	protected function setup_actions() {
 		add_action( 'bp_nouveau_enqueue_scripts', 'bp_nouveau_activity_enqueue_scripts' );
-		add_action( 'bp_widgets_init', array( 'BP_Latest_Activities', 'register_widget' ) );
 		add_action( 'bp_nouveau_notifications_init_filters', 'bp_nouveau_activity_notification_filters' );
 
+		if ( bp_core_retain_legacy_widgets() ) {
+			add_action( 'bp_widgets_init', array( 'BP_Latest_Activities', 'register_widget' ) );
+		}
+
 		$bp = buddypress();
 
 		if ( bp_is_akismet_active() && isset( $bp->activity->akismet ) ) {
diff --git src/bp-templates/bp-nouveau/includes/classes.php src/bp-templates/bp-nouveau/includes/classes.php
index 52f52612d..3e01aa79e 100644
--- src/bp-templates/bp-nouveau/includes/classes.php
+++ src/bp-templates/bp-nouveau/includes/classes.php
@@ -3,350 +3,14 @@
  * Common Classes
  *
  * @since 3.0.0
- * @version 9.0.0
+ * @version 10.0.0
  */
 
 // Exit if accessed directly.
 defined( 'ABSPATH' ) || exit;
 
-/**
- * Builds a group of BP_Button
- *
- * @since 3.0.0
- */
-class BP_Buttons_Group {
-
-	/**
-	 * The parameters of the Group of buttons
-	 *
-	 * @var array
-	 */
-	protected $group = array();
-
-	/**
-	 * Constructor
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param array $args Optional array having the following parameters {
-	 *     @type string $id                A string to use as the unique ID for the button. Required.
-	 *     @type int    $position          Where to insert the Button. Defaults to 99.
-	 *     @type string $component         The Component's the button is build for (eg: Activity, Groups..). Required.
-	 *     @type bool   $must_be_logged_in Whether the button should only be displayed to logged in users. Defaults to True.
-	 *     @type bool   $block_self        Optional. True if the button should be hidden when a user is viewing his own profile.
-	 *                                     Defaults to False.
-	 *     @type string $parent_element    Whether to use a wrapper. Defaults to false.
-	 *     @type string $parent_attr       set an array of attributes for the parent element.
-	 *     @type string $button_element    Set this to 'button', 'img', or 'a', defaults to anchor.
-	 *     @type string $button_attr       Any attributes required for the button_element
-	 *     @type string $link_text         The text of the link. Required.
-	 * }
-	 */
-	public function __construct( $args = array() ) {
-		foreach ( $args as $arg ) {
-			$this->add( $arg );
-		}
-	}
-
-
-	/**
-	 * Sort the Buttons of the group according to their position attribute
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param array the list of buttons to sort.
-	 *
-	 * @return array the list of buttons sorted.
-	 */
-	public function sort( $buttons ) {
-		$sorted = array();
-
-		foreach ( $buttons as $button ) {
-			$position = 99;
-
-			if ( isset( $button['position'] ) ) {
-				$position = (int) $button['position'];
-			}
-
-			// If position is already taken, move to the first next available
-			if ( isset( $sorted[ $position ] ) ) {
-				$sorted_keys = array_keys( $sorted );
-
-				do {
-					$position += 1;
-				} while ( in_array( $position, $sorted_keys, true ) );
-			}
-
-			$sorted[ $position ] = $button;
-		}
-
-		ksort( $sorted );
-		return $sorted;
-	}
-
-	/**
-	 * Get the BuddyPress buttons for the group
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param bool $sort whether to sort the buttons or not.
-	 *
-	 * @return array An array of HTML links.
-	 */
-	public function get( $sort = true ) {
-		$buttons = array();
-
-		if ( empty( $this->group ) ) {
-			return $buttons;
-		}
-
-		if ( true === $sort ) {
-			$this->group = $this->sort( $this->group );
-		}
-
-		foreach ( $this->group as $key_button => $button ) {
-			// Reindex with ids.
-			if ( true === $sort ) {
-				$this->group[ $button['id'] ] = $button;
-				unset( $this->group[ $key_button ] );
-			}
-
-			$buttons[ $button['id'] ] = bp_get_button( $button );
-		}
-
-		return $buttons;
-	}
-
-	/**
-	 * Update the group of buttons
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param array $args Optional. See the __constructor for a description of this argument.
-	 */
-	public function update( $args = array() ) {
-		foreach ( $args as $id => $params ) {
-			if ( isset( $this->group[ $id ] ) ) {
-				$this->group[ $id ] = bp_parse_args(
-					$params,
-					$this->group[ $id ],
-					'buttons_group_update'
-				);
-			} else {
-				$this->add( $params );
-			}
-		}
-	}
-
-	/**
-	 * Adds a button.
-	 *
-	 * @since 9.0.0
-	 *
-	 * @param array $args Required. See the __constructor for a description of this argument.
-	 * @return bool true on success, false on failure to add.
-	 */
-	private function add( $args ) {
-		$r = bp_parse_args(
-			(array) $args,
-			array(
-				'id'                => '',
-				'position'          => 99,
-				'component'         => '',
-				'must_be_logged_in' => true,
-				'block_self'        => false,
-				'parent_element'    => false,
-				'parent_attr'       => array(),
-				'button_element'    => 'a',
-				'button_attr'       => array(),
-				'link_text'         => '',
-			),
-			'buttons_group_constructor'
-		);
-
-		// Just don't set the button if a param is missing
-		if ( empty( $r['id'] ) || empty( $r['component'] ) || empty( $r['link_text'] ) ) {
-			return false;
-		}
-
-		$r['id'] = sanitize_key( $r['id'] );
-
-		// If the button already exist don't add it
-		if ( isset( $this->group[ $r['id'] ] ) ) {
-			return false;
-		}
-
-		/*
-		 * If, in bp_nouveau_get_*_buttons(), we pass through a false value for 'parent_element'
-		 * but we have attributtes for it in the array, let's default to setting a div.
-		 *
-		 * Otherwise, the original false value will be passed through to BP buttons.
-		 * @todo: this needs review, probably trying to be too clever
-		 */
-		if ( ( ! empty( $r['parent_attr'] ) ) && false === $r['parent_element'] ) {
-			$r['parent_element'] = 'div';
-		}
-
-		$this->group[ $r['id'] ] = $r;
-		return true;
-	}
-}
-
-/**
- * BP Sidebar Item Nav_Widget
- *
- * Adds a widget to move avatar/item nav into the sidebar
- *
- * @since 3.0.0
- *
- * @uses WP_Widget
- */
-class BP_Nouveau_Object_Nav_Widget extends WP_Widget {
-	/**
-	 * Constructor
-	 *
-	 * @since 3.0.0
-	 * @since 9.0.0 Adds the `show_instance_in_rest` property to Widget options.
-	 */
-	public function __construct() {
-		$widget_ops = array(
-			'description'           => __( 'Displays BuddyPress primary nav in the sidebar of your site. Make sure to use it as the first widget of the sidebar and only once.', 'buddypress' ),
-			'classname'             => 'widget_nav_menu buddypress_object_nav',
-			'show_instance_in_rest' => true,
-		);
-
-		parent::__construct(
-			'bp_nouveau_sidebar_object_nav_widget',
-			__( '(BuddyPress) Primary navigation', 'buddypress' ),
-			$widget_ops
-		);
-	}
-
-	/**
-	 * Register the widget
-	 *
-	 * @since 3.0.0
-	 */
-	public static function register_widget() {
-		register_widget( 'BP_Nouveau_Object_Nav_Widget' );
-	}
-
-	/**
-	 * Displays the output, the button to post new support topics
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param mixed   $args     Arguments
-	 * @param unknown $instance
-	 */
-	public function widget( $args, $instance ) {
-		if ( ! is_buddypress() || bp_is_group_create() ) {
-			return;
-		}
-
-		/**
-		 * Filters the nav widget args for the BP_Nouveau_Object_Nav_Widget widget.
-		 *
-		 * @since 3.0.0
-		 *
-		 * @param array $value Array of arguments {
-		 *     @param bool $bp_nouveau_widget_title Whether or not to assign a title for the widget.
-		 * }
-		 */
-		$item_nav_args = bp_parse_args(
-			$instance,
-			apply_filters(
-				'bp_nouveau_object_nav_widget_args',
-				array( 'bp_nouveau_widget_title' => true )
-			),
-			'widget_object_nav'
-		);
-
-		$title = '';
-
-		if ( ! empty( $item_nav_args['bp_nouveau_widget_title'] ) ) {
-			if ( bp_is_group() ) {
-				$title = bp_get_current_group_name();
-			} elseif ( bp_is_user() ) {
-				$title = bp_get_displayed_user_fullname();
-			} elseif ( bp_get_directory_title( bp_current_component() ) ) {
-				$title = bp_get_directory_title( bp_current_component() );
-			}
-		}
-
-		/**
-		 * Filters the BP_Nouveau_Object_Nav_Widget widget title.
-		 *
-		 * @since 3.0.0
-		 *
-		 * @param string $title    The widget title.
-		 * @param array  $instance The settings for the particular instance of the widget.
-		 * @param string $id_base  Root ID for all widgets of this type.
-		 */
-		$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
-
-		echo $args['before_widget'];
-
-		if ( ! empty( $title ) ) {
-			echo $args['before_title'] . $title . $args['after_title'];
-		}
-
-		if ( bp_is_user() ) {
-			bp_get_template_part( 'members/single/parts/item-nav' );
-		} elseif ( bp_is_group() ) {
-			bp_get_template_part( 'groups/single/parts/item-nav' );
-		} elseif ( bp_is_directory() ) {
-			bp_get_template_part( 'common/nav/directory-nav' );
-		}
-
-		echo $args['after_widget'];
-	}
-
-	/**
-	 * Update the new support topic widget options (title)
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param array $new_instance The new instance options
-	 * @param array $old_instance The old instance options
-	 *
-	 * @return array the instance
-	 */
-	public function update( $new_instance, $old_instance ) {
-		$instance                            = $old_instance;
-		$instance['bp_nouveau_widget_title'] = (bool) $new_instance['bp_nouveau_widget_title'];
-
-		return $instance;
-	}
-
-	/**
-	 * Output the new support topic widget options form
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param $instance Instance
-	 *
-	 * @return string HTML Output
-	 */
-	public function form( $instance ) {
-		$defaults = array(
-			'bp_nouveau_widget_title' => true,
-		);
-
-		$instance = bp_parse_args(
-			(array) $instance,
-			$defaults,
-			'widget_object_nav_form'
-		);
-
-		$bp_nouveau_widget_title = (bool) $instance['bp_nouveau_widget_title'];
-		?>
-
-		<p>
-			<input class="checkbox" type="checkbox" <?php checked( $bp_nouveau_widget_title, true ); ?> id="<?php echo $this->get_field_id( 'bp_nouveau_widget_title' ); ?>" name="<?php echo $this->get_field_name( 'bp_nouveau_widget_title' ); ?>" />
-			<label for="<?php echo $this->get_field_id( 'bp_nouveau_widget_title' ); ?>"><?php esc_html_e( 'Include navigation title', 'buddypress' ); ?></label>
-		</p>
+require plugin_dir_path( __FILE__ ) . 'classes/class-bp-buttons-group.php';
 
-		<?php
-	}
+if ( bp_core_retain_legacy_widgets() ) {
+	require plugin_dir_path( __FILE__ ) . 'classes/class-bp-nouveau-object-nav-widget.php';
 }
diff --git src/bp-templates/bp-nouveau/includes/classes/class-bp-buttons-group.php src/bp-templates/bp-nouveau/includes/classes/class-bp-buttons-group.php
index e69de29bb..be429fdaa 100644
--- src/bp-templates/bp-nouveau/includes/classes/class-bp-buttons-group.php
+++ src/bp-templates/bp-nouveau/includes/classes/class-bp-buttons-group.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * BP Buttons Group class.
+ *
+ * @since 3.0.0
+ * @version 10.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * Builds a group of BP_Button
+ *
+ * @since 3.0.0
+ */
+class BP_Buttons_Group {
+
+	/**
+	 * The parameters of the Group of buttons
+	 *
+	 * @var array
+	 */
+	protected $group = array();
+
+	/**
+	 * Constructor
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param array $args Optional array having the following parameters {
+	 *     @type string $id                A string to use as the unique ID for the button. Required.
+	 *     @type int    $position          Where to insert the Button. Defaults to 99.
+	 *     @type string $component         The Component's the button is build for (eg: Activity, Groups..). Required.
+	 *     @type bool   $must_be_logged_in Whether the button should only be displayed to logged in users. Defaults to True.
+	 *     @type bool   $block_self        Optional. True if the button should be hidden when a user is viewing his own profile.
+	 *                                     Defaults to False.
+	 *     @type string $parent_element    Whether to use a wrapper. Defaults to false.
+	 *     @type string $parent_attr       set an array of attributes for the parent element.
+	 *     @type string $button_element    Set this to 'button', 'img', or 'a', defaults to anchor.
+	 *     @type string $button_attr       Any attributes required for the button_element
+	 *     @type string $link_text         The text of the link. Required.
+	 * }
+	 */
+	public function __construct( $args = array() ) {
+		foreach ( $args as $arg ) {
+			$this->add( $arg );
+		}
+	}
+
+
+	/**
+	 * Sort the Buttons of the group according to their position attribute
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param array the list of buttons to sort.
+	 *
+	 * @return array the list of buttons sorted.
+	 */
+	public function sort( $buttons ) {
+		$sorted = array();
+
+		foreach ( $buttons as $button ) {
+			$position = 99;
+
+			if ( isset( $button['position'] ) ) {
+				$position = (int) $button['position'];
+			}
+
+			// If position is already taken, move to the first next available
+			if ( isset( $sorted[ $position ] ) ) {
+				$sorted_keys = array_keys( $sorted );
+
+				do {
+					$position += 1;
+				} while ( in_array( $position, $sorted_keys, true ) );
+			}
+
+			$sorted[ $position ] = $button;
+		}
+
+		ksort( $sorted );
+		return $sorted;
+	}
+
+	/**
+	 * Get the BuddyPress buttons for the group
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param bool $sort whether to sort the buttons or not.
+	 *
+	 * @return array An array of HTML links.
+	 */
+	public function get( $sort = true ) {
+		$buttons = array();
+
+		if ( empty( $this->group ) ) {
+			return $buttons;
+		}
+
+		if ( true === $sort ) {
+			$this->group = $this->sort( $this->group );
+		}
+
+		foreach ( $this->group as $key_button => $button ) {
+			// Reindex with ids.
+			if ( true === $sort ) {
+				$this->group[ $button['id'] ] = $button;
+				unset( $this->group[ $key_button ] );
+			}
+
+			$buttons[ $button['id'] ] = bp_get_button( $button );
+		}
+
+		return $buttons;
+	}
+
+	/**
+	 * Update the group of buttons
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param array $args Optional. See the __constructor for a description of this argument.
+	 */
+	public function update( $args = array() ) {
+		foreach ( $args as $id => $params ) {
+			if ( isset( $this->group[ $id ] ) ) {
+				$this->group[ $id ] = bp_parse_args(
+					$params,
+					$this->group[ $id ],
+					'buttons_group_update'
+				);
+			} else {
+				$this->add( $params );
+			}
+		}
+	}
+
+	/**
+	 * Adds a button.
+	 *
+	 * @since 9.0.0
+	 *
+	 * @param array $args Required. See the __constructor for a description of this argument.
+	 * @return bool true on success, false on failure to add.
+	 */
+	private function add( $args ) {
+		$r = bp_parse_args(
+			(array) $args,
+			array(
+				'id'                => '',
+				'position'          => 99,
+				'component'         => '',
+				'must_be_logged_in' => true,
+				'block_self'        => false,
+				'parent_element'    => false,
+				'parent_attr'       => array(),
+				'button_element'    => 'a',
+				'button_attr'       => array(),
+				'link_text'         => '',
+			),
+			'buttons_group_constructor'
+		);
+
+		// Just don't set the button if a param is missing
+		if ( empty( $r['id'] ) || empty( $r['component'] ) || empty( $r['link_text'] ) ) {
+			return false;
+		}
+
+		$r['id'] = sanitize_key( $r['id'] );
+
+		// If the button already exist don't add it
+		if ( isset( $this->group[ $r['id'] ] ) ) {
+			return false;
+		}
+
+		/*
+		 * If, in bp_nouveau_get_*_buttons(), we pass through a false value for 'parent_element'
+		 * but we have attributtes for it in the array, let's default to setting a div.
+		 *
+		 * Otherwise, the original false value will be passed through to BP buttons.
+		 * @todo: this needs review, probably trying to be too clever
+		 */
+		if ( ( ! empty( $r['parent_attr'] ) ) && false === $r['parent_element'] ) {
+			$r['parent_element'] = 'div';
+		}
+
+		$this->group[ $r['id'] ] = $r;
+		return true;
+	}
+}
diff --git src/bp-templates/bp-nouveau/includes/classes/class-bp-nouveau-object-nav-widget.php src/bp-templates/bp-nouveau/includes/classes/class-bp-nouveau-object-nav-widget.php
index e69de29bb..a5c5d4a0a 100644
--- src/bp-templates/bp-nouveau/includes/classes/class-bp-nouveau-object-nav-widget.php
+++ src/bp-templates/bp-nouveau/includes/classes/class-bp-nouveau-object-nav-widget.php
@@ -0,0 +1,167 @@
+<?php
+/**
+ * BP Sidebar Item Nav_Widget class.
+ *
+ * @since 3.0.0
+ * @version 10.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * BP Sidebar Item Nav_Widget.
+ *
+ * Adds a widget to move avatar/item nav into the sidebar.
+ *
+ * @since 3.0.0
+ */
+class BP_Nouveau_Object_Nav_Widget extends WP_Widget {
+	/**
+	 * Constructor
+	 *
+	 * @since 3.0.0
+	 * @since 9.0.0 Adds the `show_instance_in_rest` property to Widget options.
+	 */
+	public function __construct() {
+		$widget_ops = array(
+			'description'           => __( 'Displays BuddyPress primary nav in the sidebar of your site. Make sure to use it as the first widget of the sidebar and only once.', 'buddypress' ),
+			'classname'             => 'widget_nav_menu buddypress_object_nav',
+			'show_instance_in_rest' => true,
+		);
+
+		parent::__construct(
+			'bp_nouveau_sidebar_object_nav_widget',
+			__( '(BuddyPress) Primary navigation', 'buddypress' ),
+			$widget_ops
+		);
+	}
+
+	/**
+	 * Register the widget
+	 *
+	 * @since 3.0.0
+	 */
+	public static function register_widget() {
+		register_widget( 'BP_Nouveau_Object_Nav_Widget' );
+	}
+
+	/**
+	 * Displays the output, the button to post new support topics
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param mixed   $args     Arguments
+	 * @param unknown $instance
+	 */
+	public function widget( $args, $instance ) {
+		if ( ! is_buddypress() || bp_is_group_create() ) {
+			return;
+		}
+
+		/**
+		 * Filters the nav widget args for the BP_Nouveau_Object_Nav_Widget widget.
+		 *
+		 * @since 3.0.0
+		 *
+		 * @param array $value Array of arguments {
+		 *     @param bool $bp_nouveau_widget_title Whether or not to assign a title for the widget.
+		 * }
+		 */
+		$item_nav_args = bp_parse_args(
+			$instance,
+			apply_filters(
+				'bp_nouveau_object_nav_widget_args',
+				array( 'bp_nouveau_widget_title' => true )
+			),
+			'widget_object_nav'
+		);
+
+		$title = '';
+
+		if ( ! empty( $item_nav_args['bp_nouveau_widget_title'] ) ) {
+			if ( bp_is_group() ) {
+				$title = bp_get_current_group_name();
+			} elseif ( bp_is_user() ) {
+				$title = bp_get_displayed_user_fullname();
+			} elseif ( bp_get_directory_title( bp_current_component() ) ) {
+				$title = bp_get_directory_title( bp_current_component() );
+			}
+		}
+
+		/**
+		 * Filters the BP_Nouveau_Object_Nav_Widget widget title.
+		 *
+		 * @since 3.0.0
+		 *
+		 * @param string $title    The widget title.
+		 * @param array  $instance The settings for the particular instance of the widget.
+		 * @param string $id_base  Root ID for all widgets of this type.
+		 */
+		$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
+
+		echo $args['before_widget'];
+
+		if ( ! empty( $title ) ) {
+			echo $args['before_title'] . $title . $args['after_title'];
+		}
+
+		if ( bp_is_user() ) {
+			bp_get_template_part( 'members/single/parts/item-nav' );
+		} elseif ( bp_is_group() ) {
+			bp_get_template_part( 'groups/single/parts/item-nav' );
+		} elseif ( bp_is_directory() ) {
+			bp_get_template_part( 'common/nav/directory-nav' );
+		}
+
+		echo $args['after_widget'];
+	}
+
+	/**
+	 * Update the new support topic widget options (title)
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param array $new_instance The new instance options
+	 * @param array $old_instance The old instance options
+	 *
+	 * @return array the instance
+	 */
+	public function update( $new_instance, $old_instance ) {
+		$instance                            = $old_instance;
+		$instance['bp_nouveau_widget_title'] = (bool) $new_instance['bp_nouveau_widget_title'];
+
+		return $instance;
+	}
+
+	/**
+	 * Output the new support topic widget options form
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param $instance Instance
+	 *
+	 * @return string HTML Output
+	 */
+	public function form( $instance ) {
+		$defaults = array(
+			'bp_nouveau_widget_title' => true,
+		);
+
+		$instance = bp_parse_args(
+			(array) $instance,
+			$defaults,
+			'widget_object_nav_form'
+		);
+
+		$bp_nouveau_widget_title = (bool) $instance['bp_nouveau_widget_title'];
+		?>
+
+		<p>
+			<input class="checkbox" type="checkbox" <?php checked( $bp_nouveau_widget_title, true ); ?> id="<?php echo $this->get_field_id( 'bp_nouveau_widget_title' ); ?>" name="<?php echo $this->get_field_name( 'bp_nouveau_widget_title' ); ?>" />
+			<label for="<?php echo $this->get_field_id( 'bp_nouveau_widget_title' ); ?>"><?php esc_html_e( 'Include navigation title', 'buddypress' ); ?></label>
+		</p>
+
+		<?php
+	}
+}
