diff --git Gruntfile.js Gruntfile.js
index 8841c2358..16635088d 100644
--- Gruntfile.js
+++ Gruntfile.js
@@ -33,6 +33,7 @@ module.exports = function( grunt ) {
 			'!bp-templates/bp-legacy/css/twenty*.css',
 			'!bp-templates/bp-nouveau/css/buddypress.css',
 			'!bp-templates/bp-nouveau/css/twenty*.css',
+			'!bp-templates/bp-nouveau/css/primary-nav.css',
 			'!bp-core/admin/css/hello.css',
 			'!bp-members/css/blocks/member.css',
 			'!bp-groups/css/blocks/group.css',
@@ -119,7 +120,7 @@ module.exports = function( grunt ) {
 				expand: true,
 				ext: '.css',
 				flatten: true,
-				src: ['bp-templates/bp-nouveau/sass/buddypress.scss', 'bp-templates/bp-nouveau/sass/twenty*.scss'],
+				src: ['bp-templates/bp-nouveau/sass/buddypress.scss', 'bp-templates/bp-nouveau/sass/twenty*.scss', 'bp-templates/bp-nouveau/sass/primary-nav.scss'],
 				dest: SOURCE_DIR + 'bp-templates/bp-nouveau/css/'
 			},
 			admin: {
diff --git src/bp-core/classes/class-bp-core.php src/bp-core/classes/class-bp-core.php
index c8b1e924b..0a010c2a9 100644
--- src/bp-core/classes/class-bp-core.php
+++ src/bp-core/classes/class-bp-core.php
@@ -295,7 +295,7 @@ class BP_Core extends BP_Component {
 			array(
 				'block_globals' => array(
 					'bp/login-form' => array(
-						'widget_classnames' => array ( 'widget_bp_core_login_widget', 'buddypress' ),
+						'widget_classnames' => array( 'widget_bp_core_login_widget', 'buddypress' ),
 					)
 				)
 			)
diff --git src/bp-core/js/blocks/primary-nav.js src/bp-core/js/blocks/primary-nav.js
new file mode 100644
index 000000000..67b40d2d0
--- /dev/null
+++ src/bp-core/js/blocks/primary-nav.js
@@ -0,0 +1,264 @@
+// modules are defined as an array
+// [ module function, map of requires ]
+//
+// map of requires is short require name -> numeric require
+//
+// anything defined in a previous bundle is accessed via the
+// orig method which is the require for previous bundles
+parcelRequire = (function (modules, cache, entry, globalName) {
+  // Save the require from previous bundle to this closure if any
+  var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
+  var nodeRequire = typeof require === 'function' && require;
+
+  function newRequire(name, jumped) {
+    if (!cache[name]) {
+      if (!modules[name]) {
+        // if we cannot find the module within our internal map or
+        // cache jump to the current global require ie. the last bundle
+        // that was added to the page.
+        var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
+        if (!jumped && currentRequire) {
+          return currentRequire(name, true);
+        }
+
+        // If there are other bundles on this page the require from the
+        // previous one is saved to 'previousRequire'. Repeat this as
+        // many times as there are bundles until the module is found or
+        // we exhaust the require chain.
+        if (previousRequire) {
+          return previousRequire(name, true);
+        }
+
+        // Try the node require function if it exists.
+        if (nodeRequire && typeof name === 'string') {
+          return nodeRequire(name);
+        }
+
+        var err = new Error('Cannot find module \'' + name + '\'');
+        err.code = 'MODULE_NOT_FOUND';
+        throw err;
+      }
+
+      localRequire.resolve = resolve;
+      localRequire.cache = {};
+
+      var module = cache[name] = new newRequire.Module(name);
+
+      modules[name][0].call(module.exports, localRequire, module, module.exports, this);
+    }
+
+    return cache[name].exports;
+
+    function localRequire(x){
+      return newRequire(localRequire.resolve(x));
+    }
+
+    function resolve(x){
+      return modules[name][1][x] || x;
+    }
+  }
+
+  function Module(moduleName) {
+    this.id = moduleName;
+    this.bundle = newRequire;
+    this.exports = {};
+  }
+
+  newRequire.isParcelRequire = true;
+  newRequire.Module = Module;
+  newRequire.modules = modules;
+  newRequire.cache = cache;
+  newRequire.parent = previousRequire;
+  newRequire.register = function (id, exports) {
+    modules[id] = [function (require, module) {
+      module.exports = exports;
+    }, {}];
+  };
+
+  var error;
+  for (var i = 0; i < entry.length; i++) {
+    try {
+      newRequire(entry[i]);
+    } catch (e) {
+      // Save first error but execute all entries
+      if (!error) {
+        error = e;
+      }
+    }
+  }
+
+  if (entry.length) {
+    // Expose entry point to Node, AMD or browser globals
+    // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
+    var mainExports = newRequire(entry[entry.length - 1]);
+
+    // CommonJS
+    if (typeof exports === "object" && typeof module !== "undefined") {
+      module.exports = mainExports;
+
+    // RequireJS
+    } else if (typeof define === "function" && define.amd) {
+     define(function () {
+       return mainExports;
+     });
+
+    // <script>
+    } else if (globalName) {
+      this[globalName] = mainExports;
+    }
+  }
+
+  // Override the current require with this new one
+  parcelRequire = newRequire;
+
+  if (error) {
+    // throw error from earlier, _after updating parcelRequire_
+    throw error;
+  }
+
+  return newRequire;
+})({"Sw79":[function(require,module,exports) {
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = void 0;
+
+/**
+ * WordPress dependencies.
+ */
+var _wp = wp,
+    InspectorControls = _wp.blockEditor.InspectorControls,
+    _wp$components = _wp.components,
+    Disabled = _wp$components.Disabled,
+    Notice = _wp$components.Notice,
+    PanelBody = _wp$components.PanelBody,
+    ToggleControl = _wp$components.ToggleControl,
+    _wp$element = _wp.element,
+    Fragment = _wp$element.Fragment,
+    createElement = _wp$element.createElement,
+    __ = _wp.i18n.__;
+/**
+ * BuddyPress dependencies.
+ */
+
+var _bp = bp,
+    ServerSideRender = _bp.blockComponents.ServerSideRender,
+    getCurrentWidgetsSidebar = _bp.blockData.getCurrentWidgetsSidebar;
+
+var editPrimaryNavBlock = function editPrimaryNavBlock(_ref) {
+  var attributes = _ref.attributes,
+      setAttributes = _ref.setAttributes,
+      clientId = _ref.clientId;
+  var displayTitle = attributes.displayTitle;
+  var currentSidebar = getCurrentWidgetsSidebar(clientId);
+  var disabledSidebars = ['sidebar-buddypress-members', 'sidebar-buddypress-groups'];
+
+  if (currentSidebar && currentSidebar.id && -1 !== disabledSidebars.indexOf(currentSidebar.id)) {
+    return createElement(Notice, {
+      status: "error",
+      isDismissible: false
+    }, createElement("p", null, __('The BuddyPress Primary Navigation block shouldn\'t be used into this widget area. Please remove it.', 'buddypress')));
+  }
+
+  return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, {
+    title: __('Settings', 'buddypress'),
+    initialOpen: true
+  }, createElement(ToggleControl, {
+    label: __('Include navigation title', 'buddypress'),
+    checked: !!displayTitle,
+    onChange: function onChange() {
+      setAttributes({
+        displayTitle: !displayTitle
+      });
+    }
+  }))), createElement(Disabled, null, createElement(ServerSideRender, {
+    block: "bp/primary-nav",
+    attributes: attributes
+  })));
+};
+
+var _default = editPrimaryNavBlock;
+exports.default = _default;
+},{}],"uKqo":[function(require,module,exports) {
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = void 0;
+
+/**
+ * WordPress dependencies.
+ */
+var _wp = wp,
+    createBlock = _wp.blocks.createBlock;
+/**
+ * Transforms Legacy Widget to Primary Nav Block.
+ *
+ * @type {Object}
+ */
+
+var transforms = {
+  from: [{
+    type: 'block',
+    blocks: ['core/legacy-widget'],
+    isMatch: function isMatch(_ref) {
+      var idBase = _ref.idBase,
+          instance = _ref.instance;
+
+      if (!(instance !== null && instance !== void 0 && instance.raw)) {
+        return false;
+      }
+
+      return idBase === 'bp_nouveau_sidebar_object_nav_widget';
+    },
+    transform: function transform(_ref2) {
+      var instance = _ref2.instance;
+      return createBlock('bp/primary-nav', {
+        displayTitle: instance.raw.bp_nouveau_widget_title
+      });
+    }
+  }]
+};
+var _default = transforms;
+exports.default = _default;
+},{}],"ygAa":[function(require,module,exports) {
+"use strict";
+
+var _edit = _interopRequireDefault(require("./primary-nav/edit"));
+
+var _transforms = _interopRequireDefault(require("./primary-nav/transforms"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * WordPress dependencies.
+ */
+var _wp = wp,
+    registerBlockType = _wp.blocks.registerBlockType,
+    __ = _wp.i18n.__;
+/**
+ * Internal dependencies.
+ */
+
+registerBlockType('bp/primary-nav', {
+  title: __('Primary navigation', 'buddypress'),
+  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'),
+  icon: {
+    background: '#fff',
+    foreground: '#d84800',
+    src: 'buddicons-community'
+  },
+  category: 'buddypress',
+  attributes: {
+    displayTitle: {
+      type: 'boolean',
+      default: true
+    }
+  },
+  edit: _edit.default,
+  transforms: _transforms.default
+});
+},{"./primary-nav/edit":"Sw79","./primary-nav/transforms":"uKqo"}]},{},["ygAa"], null)
\ No newline at end of file
diff --git src/bp-templates/bp-nouveau/css/primary-nav-rtl.css src/bp-templates/bp-nouveau/css/primary-nav-rtl.css
new file mode 100644
index 000000000..8811471c2
--- /dev/null
+++ src/bp-templates/bp-nouveau/css/primary-nav-rtl.css
@@ -0,0 +1,94 @@
+.buddypress_object_nav .bp-navs {
+	background: transparent;
+	clear: both;
+	overflow: hidden;
+}
+
+.buddypress_object_nav .bp-navs ul {
+	margin: 0;
+	padding: 0;
+}
+
+.buddypress_object_nav .bp-navs ul li {
+	list-style: none;
+	margin: 0;
+}
+
+.buddypress_object_nav .bp-navs ul li.last select {
+	max-width: 185px;
+}
+
+.buddypress_object_nav .bp-navs ul li a,
+.buddypress_object_nav .bp-navs ul li span {
+	border: 0;
+	display: block;
+	padding: 5px 10px;
+	text-decoration: none;
+}
+
+.buddypress_object_nav .bp-navs ul li .count {
+	background: #eaeaea;
+	border: 1px solid #ccc;
+	border-radius: 50%;
+	color: #555;
+	display: inline-block;
+	font-size: 12px;
+	margin-right: 2px;
+	padding: 3px 6px;
+	text-align: center;
+	vertical-align: middle;
+}
+
+.buddypress_object_nav .bp-navs ul li.selected a,
+.buddypress_object_nav .bp-navs ul li.current a {
+	color: #333;
+	opacity: 1;
+}
+
+.buddypress_object_nav .bp-navs ul li.selected a .count,
+.buddypress_object_nav .bp-navs ul li.current a .count {
+	background-color: #fff;
+}
+
+.buddypress_object_nav .bp-navs ul li.dynamic a .count,
+.buddypress_object_nav .bp-navs ul li.dynamic.selected a .count,
+.buddypress_object_nav .bp-navs ul li.dynamic.current a .count {
+	background-color: #5087e5;
+	border: 0;
+	color: #fafafa;
+}
+
+.buddypress_object_nav .bp-navs ul li.dynamic a:hover .count {
+	background-color: #5087e5;
+	border: 0;
+	color: #fff;
+}
+
+.buddypress_object_nav .bp-navs ul li a .count:empty {
+	display: none;
+}
+
+.buddypress_object_nav .main-navs.dir-navs {
+	margin-bottom: 20px;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) {
+	color: #767676;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a {
+	color: #767676;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a:focus, .buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a:hover {
+	background: none;
+	color: #555;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a[disabled]:focus, .buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a[disabled]:hover {
+	color: #767676;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li.current a {
+	text-align: center;
+}
diff --git src/bp-templates/bp-nouveau/css/primary-nav.css src/bp-templates/bp-nouveau/css/primary-nav.css
new file mode 100644
index 000000000..01f3e6c2d
--- /dev/null
+++ src/bp-templates/bp-nouveau/css/primary-nav.css
@@ -0,0 +1,94 @@
+.buddypress_object_nav .bp-navs {
+	background: transparent;
+	clear: both;
+	overflow: hidden;
+}
+
+.buddypress_object_nav .bp-navs ul {
+	margin: 0;
+	padding: 0;
+}
+
+.buddypress_object_nav .bp-navs ul li {
+	list-style: none;
+	margin: 0;
+}
+
+.buddypress_object_nav .bp-navs ul li.last select {
+	max-width: 185px;
+}
+
+.buddypress_object_nav .bp-navs ul li a,
+.buddypress_object_nav .bp-navs ul li span {
+	border: 0;
+	display: block;
+	padding: 5px 10px;
+	text-decoration: none;
+}
+
+.buddypress_object_nav .bp-navs ul li .count {
+	background: #eaeaea;
+	border: 1px solid #ccc;
+	border-radius: 50%;
+	color: #555;
+	display: inline-block;
+	font-size: 12px;
+	margin-left: 2px;
+	padding: 3px 6px;
+	text-align: center;
+	vertical-align: middle;
+}
+
+.buddypress_object_nav .bp-navs ul li.selected a,
+.buddypress_object_nav .bp-navs ul li.current a {
+	color: #333;
+	opacity: 1;
+}
+
+.buddypress_object_nav .bp-navs ul li.selected a .count,
+.buddypress_object_nav .bp-navs ul li.current a .count {
+	background-color: #fff;
+}
+
+.buddypress_object_nav .bp-navs ul li.dynamic a .count,
+.buddypress_object_nav .bp-navs ul li.dynamic.selected a .count,
+.buddypress_object_nav .bp-navs ul li.dynamic.current a .count {
+	background-color: #5087e5;
+	border: 0;
+	color: #fafafa;
+}
+
+.buddypress_object_nav .bp-navs ul li.dynamic a:hover .count {
+	background-color: #5087e5;
+	border: 0;
+	color: #fff;
+}
+
+.buddypress_object_nav .bp-navs ul li a .count:empty {
+	display: none;
+}
+
+.buddypress_object_nav .main-navs.dir-navs {
+	margin-bottom: 20px;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) {
+	color: #767676;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a {
+	color: #767676;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a:focus, .buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a:hover {
+	background: none;
+	color: #555;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a[disabled]:focus, .buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a[disabled]:hover {
+	color: #767676;
+}
+
+.buddypress_object_nav .bp-navs.group-create-links ul li.current a {
+	text-align: center;
+}
diff --git src/bp-templates/bp-nouveau/includes/functions.php src/bp-templates/bp-nouveau/includes/functions.php
index 77c1f93ef..105a65bc2 100644
--- src/bp-templates/bp-nouveau/includes/functions.php
+++ src/bp-templates/bp-nouveau/includes/functions.php
@@ -3,7 +3,7 @@
  * Common functions
  *
  * @since 3.0.0
- * @version 8.0.0
+ * @version 9.0.0
  */
 
 // Exit if accessed directly.
@@ -1489,3 +1489,149 @@ function bp_nouveau_get_component_slug( $component_id = '' ) {
 	 */
 	return apply_filters( 'bp_nouveau_get_component_slug', $slug, $component_id );
 }
+
+/**
+ * Registers the 'bp/primary-nav' Widget Block.
+ *
+ * @since 9.0.0
+ *
+ * @param array $blocks The Core Blocks list.
+ * @return array The Core Blocks list.
+ */
+function bp_nouveau_register_primary_nav_widget_block( $blocks = array() ) {
+	$editor_style = bp_locate_template_asset( 'css/primary-nav.css' );
+
+	$blocks['bp/primary-nav'] = array(
+		'name'               => 'bp/primary-nav',
+		'editor_script'      => 'bp-primary-nav-block',
+		'editor_script_url'  => trailingslashit( buddypress()->plugin_url . 'bp-core' ) . 'js/blocks/primary-nav.js',
+		'editor_script_deps' => array(
+			'wp-blocks',
+			'wp-element',
+			'wp-components',
+			'wp-i18n',
+			'wp-block-editor',
+			'bp-block-data',
+			'bp-block-components',
+		),
+		'editor_style'       => 'bp-primary-nav-block',
+		'editor_style_url'   => $editor_style['uri'],
+		'attributes'         => array(
+			'displayTitle' => array(
+				'type'    => 'boolean',
+				'default' => true,
+			),
+		),
+		'render_callback'    => 'bp_nouveau_render_primary_nav_block',
+	);
+
+	return $blocks;
+}
+add_filter( 'bp_core_register_blocks', 'bp_nouveau_register_primary_nav_widget_block', 20, 1 );
+
+/**
+ * Registers the 'bp/primary-nav' Widget Block classnames.
+ *
+ * @since 9.0.0
+ *
+ * @param array $block_globals The list of global properties for Core blocks.
+ * @return array               The list of global properties for Core blocks.
+ */
+function bp_nouveau_register_core_block_globals( $block_globals = array() ) {
+	$block_globals['bp/primary-nav'] = array(
+		'widget_classnames' => array( 'widget_nav_menu', 'buddypress_object_nav', 'buddypress' ),
+	);
+
+	return $block_globals;
+}
+add_filter( 'bp_core_block_globals', 'bp_nouveau_register_core_block_globals', 10, 1 );
+
+/**
+ * Unregister the 'bp/primary-nav' Block from the post context.
+ *
+ * @since 9.0.0
+ */
+function bp_nouveau_unregister_blocks_for_post_context() {
+	unregister_block_type( 'bp/primary-nav' );
+}
+add_action( 'load-post.php', 'bp_nouveau_unregister_blocks_for_post_context' );
+add_action( 'load-post-new.php', 'bp_nouveau_unregister_blocks_for_post_context' );
+
+/**
+ * Callback function to render the BP Primary Nav Block.
+ *
+ * @since 9.0.0
+ *
+ * @param array $attributes The block attributes.
+ * @return string           HTML output.
+ */
+function bp_nouveau_render_primary_nav_block( $attributes = array() ) {
+	$widget_content = '';
+	$widget_title   = '';
+	$block_args     = bp_parse_args(
+		$attributes,
+		array(
+			'displayTitle' => true,
+		),
+		'widget_object_nav'
+	);
+
+	// Previewing the Block inside the editor.
+	if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
+		$widget_title = bp_get_loggedin_user_fullname();
+
+		ob_start();
+
+		// Temporary override the displayed user by the logged in one.
+		add_filter( 'bp_displayed_user_id', 'bp_loggedin_user_id' );
+
+		bp_get_template_part( 'members/single/parts/item-nav' );
+		$widget_content = ob_get_clean();
+
+		// Remove the temporary override.
+		remove_filter( 'bp_displayed_user_id', 'bp_loggedin_user_id' );
+	} else {
+		ob_start();
+
+		if ( bp_is_user() ) {
+			$widget_title = bp_get_displayed_user_fullname();
+			bp_get_template_part( 'members/single/parts/item-nav' );
+		} elseif ( bp_is_group() ) {
+			$widget_title = bp_get_current_group_name();
+			bp_get_template_part( 'groups/single/parts/item-nav' );
+		} elseif ( bp_is_directory() ) {
+			$widget_title = bp_get_directory_title( bp_current_component() );
+			bp_get_template_part( 'common/nav/directory-nav' );
+		}
+
+		$widget_content = ob_get_clean();
+	}
+
+	if ( ! $widget_content ) {
+		return '';
+	}
+
+	// Set the Block's title.
+	if ( true === $block_args['displayTitle'] ) {
+		$widget_content = sprintf(
+			'<h2 class="widget-title">%1$s</h2>
+			%2$s',
+			esc_html( $widget_title ),
+			$widget_content
+		);
+	}
+
+	// Only add a block wrapper if not loaded into a Widgets sidebar.
+	if ( ! did_action( 'dynamic_sidebar_before' ) ) {
+		$classnames         = 'widget_nav_menu buddypress_object_nav buddypress widget';
+		$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
+
+		return sprintf(
+			'<div %1$s>%2$s</div>',
+			$wrapper_attributes,
+			$widget_content
+		);
+	}
+
+	return $widget_content;
+}
diff --git src/bp-templates/bp-nouveau/sass/primary-nav.scss src/bp-templates/bp-nouveau/sass/primary-nav.scss
new file mode 100644
index 000000000..e115e5d33
--- /dev/null
+++ src/bp-templates/bp-nouveau/sass/primary-nav.scss
@@ -0,0 +1,141 @@
+// BP primary navigation - directory and single screens
+
+// all devices & generic styles sitewide
+.buddypress_object_nav {
+
+	.bp-navs {
+		background: transparent;
+		clear: both;
+		overflow: hidden;
+
+		ul {
+			margin: 0;
+			padding: 0;
+
+			li {
+				list-style: none;
+				margin: 0;
+			}
+
+			li.last {
+
+				select {
+					max-width: 185px;
+				}
+			}
+
+			li {
+
+				a,
+				span {
+					border: 0;
+					display: block;
+					padding: 5px 10px;
+					text-decoration: none;
+				}
+
+				.count {
+					background: #eaeaea;
+					border: 1px solid #ccc;
+					border-radius: 50%;
+					color: #555;
+					display: inline-block;
+
+					font-size: 12px;
+					margin-left: 2px;
+					padding: 3px 6px;
+					text-align: center;
+					vertical-align: middle;
+				}
+			}
+
+			li.selected,
+			li.current {
+
+				a {
+					color: #333;
+					opacity: 1;
+
+					.count {
+						background-color: #fff;
+					}
+				}
+			}
+
+			li.dynamic,
+			li.dynamic.selected,
+			li.dynamic.current {
+
+				a {
+
+					.count {
+						background-color: #5087e5;
+						border: 0;
+						color: #fafafa;
+					}
+				}
+			}
+
+			li.dynamic {
+
+				a:hover {
+
+					.count {
+						background-color: #5087e5;
+						border: 0;
+						color: #fff;
+					}
+				}
+			}
+
+			li {
+
+				a {
+
+					.count:empty {
+						display: none;
+					}
+				}
+			}
+		}
+	}
+
+	.main-navs.dir-navs {
+		margin-bottom: 20px;
+	}
+
+	.bp-navs.group-create-links {
+
+		ul {
+
+			li:not(.current) {
+				color: #767676;
+
+				a {
+					color: #767676;
+
+					&:focus,
+					&:hover {
+						background: none;
+						color: #555;
+					}
+				}
+
+				a[disabled] {
+
+					&:focus,
+					&:hover {
+						color: #767676;
+					}
+				}
+			}
+
+			li.current {
+
+				a {
+					text-align: center;
+				}
+			}
+		}
+	}
+}
diff --git src/js/bp-core/js/blocks/primary-nav.js src/js/bp-core/js/blocks/primary-nav.js
new file mode 100644
index 000000000..efc451eea
--- /dev/null
+++ src/js/bp-core/js/blocks/primary-nav.js
@@ -0,0 +1,36 @@
+/**
+ * WordPress dependencies.
+ */
+const {
+	blocks: {
+		registerBlockType,
+	},
+	i18n: {
+		__,
+	},
+} = wp;
+
+/**
+ * Internal dependencies.
+ */
+import editPrimaryNavBlock from './primary-nav/edit';
+import transforms from './primary-nav/transforms';
+
+registerBlockType( 'bp/primary-nav', {
+	title: __( 'Primary navigation', 'buddypress' ),
+	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' ),
+	icon: {
+		background: '#fff',
+		foreground: '#d84800',
+		src: 'buddicons-community',
+	},
+	category: 'buddypress',
+	attributes: {
+		displayTitle: {
+			type: 'boolean',
+			default: true,
+		},
+	},
+	edit: editPrimaryNavBlock,
+	transforms: transforms,
+} );
diff --git src/js/bp-core/js/blocks/primary-nav/edit.js src/js/bp-core/js/blocks/primary-nav/edit.js
new file mode 100644
index 000000000..8aa4b4375
--- /dev/null
+++ src/js/bp-core/js/blocks/primary-nav/edit.js
@@ -0,0 +1,70 @@
+/**
+ * WordPress dependencies.
+ */
+const {
+	blockEditor: {
+		InspectorControls,
+	},
+	components: {
+		Disabled,
+		Notice,
+		PanelBody,
+		ToggleControl,
+	},
+	element: {
+		Fragment,
+		createElement,
+	},
+	i18n: {
+		__,
+	},
+} = wp;
+
+/**
+ * BuddyPress dependencies.
+ */
+const {
+	blockComponents: {
+		ServerSideRender,
+	},
+	blockData: {
+		getCurrentWidgetsSidebar,
+	}
+} = bp;
+
+const editPrimaryNavBlock = ( { attributes, setAttributes, clientId } ) => {
+	const { displayTitle } = attributes;
+	const currentSidebar = getCurrentWidgetsSidebar( clientId );
+	const disabledSidebars = ['sidebar-buddypress-members', 'sidebar-buddypress-groups'];
+
+	if ( currentSidebar && currentSidebar.id && -1 !== disabledSidebars.indexOf( currentSidebar.id ) ) {
+		return (
+			<Notice status="error" isDismissible={ false }>
+				<p>
+					{ __( 'The BuddyPress Primary Navigation block shouldn\'t be used into this widget area. Please remove it.', 'buddypress' ) }
+				</p>
+			</Notice>
+		);
+	}
+
+	return (
+		<Fragment>
+			<InspectorControls>
+				<PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true }>
+					<ToggleControl
+						label={ __( 'Include navigation title', 'buddypress' ) }
+						checked={ !! displayTitle }
+						onChange={ () => {
+							setAttributes( { displayTitle: ! displayTitle } );
+						} }
+					/>
+				</PanelBody>
+			</InspectorControls>
+			<Disabled>
+				<ServerSideRender block="bp/primary-nav" attributes={ attributes } />
+			</Disabled>
+		</Fragment>
+	);
+};
+
+export default editPrimaryNavBlock;
diff --git src/js/bp-core/js/blocks/primary-nav/transforms.js src/js/bp-core/js/blocks/primary-nav/transforms.js
new file mode 100644
index 000000000..ea9e49887
--- /dev/null
+++ src/js/bp-core/js/blocks/primary-nav/transforms.js
@@ -0,0 +1,36 @@
+/**
+ * WordPress dependencies.
+ */
+ const {
+	blocks: {
+		createBlock,
+	},
+} = wp;
+
+/**
+ * Transforms Legacy Widget to Primary Nav Block.
+ *
+ * @type {Object}
+ */
+const transforms = {
+	from: [
+		{
+			type: 'block',
+			blocks: [ 'core/legacy-widget' ],
+			isMatch: ( { idBase, instance } ) => {
+				if ( ! instance?.raw ) {
+					return false;
+				}
+
+				return idBase === 'bp_nouveau_sidebar_object_nav_widget';
+			},
+			transform: ( { instance } ) => {
+				return createBlock( 'bp/primary-nav', {
+					displayTitle: instance.raw.bp_nouveau_widget_title,
+				} );
+			},
+		},
+	],
+};
+
+export default transforms;
