diff --git Gruntfile.js Gruntfile.js
index 16635088d..bb010cd0c 100644
--- Gruntfile.js
+++ Gruntfile.js
@@ -39,7 +39,8 @@ module.exports = function( grunt ) {
 			'!bp-groups/css/blocks/group.css',
 			'!bp-members/css/blocks/members.css',
 			'!bp-groups/css/blocks/groups.css',
-			'!bp-core/css/blocks/login-form.css'
+			'!bp-core/css/blocks/login-form.css',
+			'!bp-activity/css/blocks/latest-activities.css'
 		],
 
 		autoprefixer = require('autoprefixer');
@@ -158,6 +159,15 @@ module.exports = function( grunt ) {
 				flatten: true,
 				src: ['bp-core/sass/blocks/*.scss'],
 				dest: SOURCE_DIR + 'bp-core/css/blocks/'
+			},
+			activity_blocks: {
+				cwd: SOURCE_DIR,
+				extDot: 'last',
+				expand: true,
+				ext: '.css',
+				flatten: true,
+				src: ['bp-activity/sass/blocks/*.scss'],
+				dest: SOURCE_DIR + 'bp-activity/css/blocks/'
 			}
 		},
 		rtlcss: {
diff --git src/bp-activity/bp-activity-blocks.php src/bp-activity/bp-activity-blocks.php
index 116badd6a..fcaf9d4c1 100644
--- src/bp-activity/bp-activity-blocks.php
+++ src/bp-activity/bp-activity-blocks.php
@@ -11,3 +11,145 @@
 if ( ! defined( 'ABSPATH' ) ) {
 	exit;
 }
+
+/**
+ * Callback function to render the Latest Activities Block.
+ *
+ * @since 9.0.0
+ *
+ * @param array $attributes The block attributes.
+ * @return string           HTML output.
+ */
+function bp_activity_render_latest_activities_block( $attributes = array() ) {
+	$block_args = wp_parse_args(
+		$attributes,
+		array(
+			'title'         => __( 'Latest updates', 'buddypress' ),
+			'maxActivities' => 5,
+			'type'          => array( 'activity_update' ),
+			'postId'        => 0,
+		)
+	);
+
+	$max_activities = (int) $block_args['maxActivities'];
+
+	// Should we get a specific member's activities?
+	$member_id = 0;
+	if ( $block_args['postId'] ) {
+		$member_id = (int) get_post_field( 'post_author', $block_args['postId'] );
+	} else {
+		$member_id = bp_displayed_user_id();
+	}
+
+	// Set the widget's wrapper attributes.
+	$types              = (array) $block_args['type'];
+	$classnames         = array_map( 'sanitize_html_class', array_merge( $types, array( 'bp-latest-activities', 'buddypress', 'widget' ) ) );
+	$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) );
+
+	// Set the Block's title.
+	$widget_content = sprintf( '<h2 class="widget-title">%s</h2>', esc_html( $block_args['title'] ) );
+
+	// Avoid conflicts with other activity loops.
+	$reset_activities_template = null;
+	if ( ! empty( $GLOBALS['activities_template'] ) ) {
+		$reset_activities_template = $GLOBALS['activities_template'];
+	}
+
+	$widget_args = array(
+		'max'          => $max_activities,
+		'scope'        => 'all',
+		'user_id'      => $member_id,
+		'object'       => false,
+		'action'       => implode( ',', $types ),
+		'primary_id'   => 0,
+		'secondary_id' => 0,
+	);
+
+	// Build the activity loop.
+	if ( 'nouveau' === bp_get_theme_compat_id() ) {
+		$bp_nouveau = bp_nouveau();
+
+		// Globalize the activity widget arguments.
+		$bp_nouveau->activity->widget_args = $widget_args;
+
+		ob_start();
+		bp_get_template_part( 'activity/widget' );
+		$widget_content .= ob_get_clean();
+
+		// Reset the global.
+		$bp_nouveau->activity->widget_args = array();
+	} else {
+		$activity_loop = sprintf( '<div class="widget-error"><p>%s</p></div>', esc_html__( 'Sorry, there was no activity found. Please try a different filter.', 'buddypress' ) );
+
+		if ( bp_has_activities( $widget_args ) ) {
+			$activity_loop = '';
+
+			while ( bp_activities() ) {
+				bp_the_activity();
+
+				$activity_footer  = '';
+				$activity_classes = 'activity-item';
+				if ( bp_activity_has_content() ) {
+					$activity_content = bp_get_activity_content_body();
+					$activity_footer  = sprintf(
+						'<footer>
+							<cite>
+								<a href="%1$s" class="bp-tooltip" data-bp-tooltip="%2$s">
+									%3$s
+								</a>
+							</cite>
+							%4$s
+						</footer>',
+						bp_get_activity_user_link(),
+						bp_get_activity_member_display_name(),
+						bp_get_activity_avatar(
+							array(
+								'type'   => 'thumb',
+								'width'  => '40',
+								'height' => '40',
+							)
+						),
+						bp_insert_activity_meta()
+					);
+				} else {
+					$activity_classes .= ' mini';
+					$activity_content  = bp_get_activity_action();
+				}
+
+				$activity_loop .= sprintf(
+					'<blockquote>
+						<div class="%1$s">%2$s</div>
+						%3$s
+					</blockquote>',
+					$activity_classes,
+					$activity_content,
+					$activity_footer
+				);
+			}
+		}
+
+		$widget_content .= sprintf(
+			'<div class="activity-list item-list">
+				%1$s
+			</div>',
+			$activity_loop
+		);
+	}
+
+	// Adds a container to make sure the block is styled even when used into the Columns parent block.
+	$widget_content = sprintf( '<div class="bp-latest-activities-block">%s</div>', "\n" . $widget_content . "\n" );
+
+	// Reset the global template loop.
+	$GLOBALS['activities_template'] = $reset_activities_template;
+
+	// Only add a block wrapper if not loaded into a Widgets sidebar.
+	if ( ! did_action( 'dynamic_sidebar_before' ) ) {
+		return sprintf(
+			'<div %1$s>%2$s</div>',
+			$wrapper_attributes,
+			$widget_content
+		);
+	}
+
+	return $widget_content;
+}
diff --git src/bp-activity/classes/class-bp-activity-component.php src/bp-activity/classes/class-bp-activity-component.php
index 398550378..d54966b49 100644
--- src/bp-activity/classes/class-bp-activity-component.php
+++ src/bp-activity/classes/class-bp-activity-component.php
@@ -207,6 +207,11 @@ class BP_Activity_Component extends BP_Component {
 			'search_string'         => __( 'Search Activity...', 'buddypress' ),
 			'global_tables'         => $global_tables,
 			'meta_tables'           => $meta_tables,
+			'block_globals'         => array(
+				'bp/latest-activities' => array(
+					'widget_classnames' => array( 'wp-block-bp-latest-activities', 'buddypress' ),
+				)
+			),
 		);
 
 		parent::setup_globals( $args );
@@ -483,24 +488,62 @@ class BP_Activity_Component extends BP_Component {
 	 *                      description.
 	 */
 	public function blocks_init( $blocks = array() ) {
-		parent::blocks_init(
-			array(
-				'bp/embed-activity' => array(
-					'name'               => 'bp/embed-activity',
-					'editor_script'      => 'bp-embed-activity-block',
-					'editor_script_url'  => plugins_url( 'js/blocks/embed-activity.js', dirname(  __FILE__ ) ),
-					'editor_script_deps' => array(
-						'wp-blocks',
-						'wp-element',
-						'wp-i18n',
-						'wp-components',
-						'wp-block-editor',
-						'wp-data',
-						'wp-compose',
-						'bp-block-data',
+		$blocks = array(
+			'bp/latest-activities' => array(
+				'name'               => 'bp/latest-activities',
+				'editor_script'      => 'bp-latest-activities-block',
+				'editor_script_url'  => plugins_url( 'js/blocks/latest-activities.js', dirname(  __FILE__ ) ),
+				'editor_script_deps' => array(
+					'wp-blocks',
+					'wp-element',
+					'wp-components',
+					'wp-i18n',
+					'wp-block-editor',
+					'bp-block-data',
+					'bp-block-components',
+				),
+				'style'              => 'bp-latest-activities-block',
+				'style_url'          => plugins_url( 'css/blocks/latest-activities.css', dirname(  __FILE__ ) ),
+				'attributes'         => array(
+					'title'         => array(
+						'type'    => 'string',
+						'default' => __( 'Latest updates', 'buddypress' ),
+					),
+					'maxActivities' => array(
+						'type'    => 'number',
+						'default' => 5,
+					),
+					'type'          => array(
+						'type'    => 'array',
+						'default' => array( 'activity_update' ),
+					),
+					'postId'        => array(
+						'type'    => 'number',
+						'default' => 0,
 					),
 				),
-			)
+				'render_callback'    => 'bp_activity_render_latest_activities_block',
+			),
 		);
+
+		if ( bp_is_active( $this->id, 'embeds' ) ) {
+			$blocks['bp/embed-activity'] = array(
+				'name'               => 'bp/embed-activity',
+				'editor_script'      => 'bp-embed-activity-block',
+				'editor_script_url'  => plugins_url( 'js/blocks/embed-activity.js', dirname(  __FILE__ ) ),
+				'editor_script_deps' => array(
+					'wp-blocks',
+					'wp-element',
+					'wp-i18n',
+					'wp-components',
+					'wp-block-editor',
+					'wp-data',
+					'wp-compose',
+					'bp-block-data',
+				),
+			);
+		}
+
+		parent::blocks_init( $blocks );
 	}
 }
diff --git src/bp-activity/css/blocks/latest-activities-rtl.css src/bp-activity/css/blocks/latest-activities-rtl.css
new file mode 100644
index 000000000..7eaa9c840
--- /dev/null
+++ src/bp-activity/css/blocks/latest-activities-rtl.css
@@ -0,0 +1,81 @@
+.bp-latest-activities .components-flex.components-select-control select[multiple] {
+	height: auto;
+	padding: 0 8px;
+}
+
+.bp-latest-activities .components-flex.components-select-control select[multiple] + .components-input-control__suffix svg {
+	display: none;
+}
+
+.bp-latest-activities-block a,
+.entry .entry-content .bp-latest-activities-block a {
+	border: none;
+	text-decoration: none;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote {
+	padding: 0;
+	border: none;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini) {
+	position: relative;
+	box-shadow: -1px 0 4px rgba(0, 0, 0, 0.15);
+	padding: 0 1em;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after, .bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
+	position: absolute;
+	right: 15px;
+	display: block;
+	width: 0;
+	height: 0;
+	border-style: solid;
+	border-color: transparent;
+	content: "";
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
+	bottom: -18px;
+	border-top-color: rgba(0, 0, 0, 0.15);
+	border-width: 9px;
+	right: 14px;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after {
+	bottom: -16px;
+	border-top-color: #fff;
+	border-width: 8px;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item.mini .avatar {
+	display: inline-block;
+	width: 20px;
+	height: 20px;
+	vertical-align: middle;
+	margin-left: 2px;
+}
+
+.bp-latest-activities-block .activity-list.item-list footer {
+	display: flex;
+	align-items: center;
+}
+
+.bp-latest-activities-block .activity-list.item-list footer img.avatar {
+	display: inline-block;
+	border: none;
+	margin-left: 0.5em;
+}
+
+.bp-latest-activities-block .activity-list.item-list footer .activity-time-since {
+	font-size: 90%;
+}
+
+.bp-latest-activities-block .widget-error {
+	border-right: solid 4px #0b80a4;
+	box-shadow: -1px 0 4px rgba(0, 0, 0, 0.15);
+}
+
+.bp-latest-activities-block .widget-error p {
+	padding: 0 1em;
+}
diff --git src/bp-activity/css/blocks/latest-activities.css src/bp-activity/css/blocks/latest-activities.css
new file mode 100644
index 000000000..63759731c
--- /dev/null
+++ src/bp-activity/css/blocks/latest-activities.css
@@ -0,0 +1,81 @@
+.bp-latest-activities .components-flex.components-select-control select[multiple] {
+	height: auto;
+	padding: 0 8px;
+}
+
+.bp-latest-activities .components-flex.components-select-control select[multiple] + .components-input-control__suffix svg {
+	display: none;
+}
+
+.bp-latest-activities-block a,
+.entry .entry-content .bp-latest-activities-block a {
+	border: none;
+	text-decoration: none;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote {
+	padding: 0;
+	border: none;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini) {
+	position: relative;
+	box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
+	padding: 0 1em;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after, .bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
+	position: absolute;
+	left: 15px;
+	display: block;
+	width: 0;
+	height: 0;
+	border-style: solid;
+	border-color: transparent;
+	content: "";
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
+	bottom: -18px;
+	border-top-color: rgba(0, 0, 0, 0.15);
+	border-width: 9px;
+	left: 14px;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after {
+	bottom: -16px;
+	border-top-color: #fff;
+	border-width: 8px;
+}
+
+.bp-latest-activities-block .activity-list.item-list blockquote .activity-item.mini .avatar {
+	display: inline-block;
+	width: 20px;
+	height: 20px;
+	vertical-align: middle;
+	margin-right: 2px;
+}
+
+.bp-latest-activities-block .activity-list.item-list footer {
+	display: flex;
+	align-items: center;
+}
+
+.bp-latest-activities-block .activity-list.item-list footer img.avatar {
+	display: inline-block;
+	border: none;
+	margin-right: 0.5em;
+}
+
+.bp-latest-activities-block .activity-list.item-list footer .activity-time-since {
+	font-size: 90%;
+}
+
+.bp-latest-activities-block .widget-error {
+	border-left: solid 4px #0b80a4;
+	box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
+}
+
+.bp-latest-activities-block .widget-error p {
+	padding: 0 1em;
+}
diff --git src/bp-activity/js/blocks/latest-activities.js src/bp-activity/js/blocks/latest-activities.js
new file mode 100644
index 000000000..614751c24
--- /dev/null
+++ src/bp-activity/js/blocks/latest-activities.js
@@ -0,0 +1,320 @@
+// 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;
+})({"DIzr":[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,
+    PanelBody = _wp$components.PanelBody,
+    RangeControl = _wp$components.RangeControl,
+    SelectControl = _wp$components.SelectControl,
+    TextControl = _wp$components.TextControl,
+    _wp$element = _wp.element,
+    Fragment = _wp$element.Fragment,
+    createElement = _wp$element.createElement,
+    __ = _wp.i18n.__;
+/**
+ * BuddyPress dependencies.
+ */
+
+var _bp = bp,
+    ServerSideRender = _bp.blockComponents.ServerSideRender,
+    _bp$blockData = _bp.blockData,
+    currentPostId = _bp$blockData.currentPostId,
+    activityTypes = _bp$blockData.activityTypes;
+
+var editDynamicActivitiesBlock = function editDynamicActivitiesBlock(_ref) {
+  var attributes = _ref.attributes,
+      setAttributes = _ref.setAttributes;
+  var postId = attributes.postId,
+      maxActivities = attributes.maxActivities,
+      type = attributes.type,
+      title = attributes.title;
+  var post = currentPostId();
+  var types = activityTypes();
+
+  if (!postId && post) {
+    setAttributes({
+      postId: post
+    });
+  }
+
+  return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, {
+    title: __('Settings', 'buddypress'),
+    initialOpen: true,
+    className: "bp-latest-activities"
+  }, createElement(TextControl, {
+    label: __('Title', 'buddypress'),
+    value: title,
+    onChange: function onChange(text) {
+      setAttributes({
+        title: text
+      });
+    }
+  }), createElement(RangeControl, {
+    label: __('Maximum amount to display', 'buddypress'),
+    value: maxActivities,
+    onChange: function onChange(value) {
+      return setAttributes({
+        maxActivities: value
+      });
+    },
+    min: 1,
+    max: 10,
+    required: true
+  }), createElement(SelectControl, {
+    multiple: true,
+    label: __('Type', 'buddypress'),
+    value: type,
+    options: types,
+    onChange: function onChange(option) {
+      setAttributes({
+        type: option
+      });
+    }
+  }))), createElement(Disabled, null, createElement(ServerSideRender, {
+    block: "bp/latest-activities",
+    attributes: attributes
+  })));
+};
+
+var _default = editDynamicActivitiesBlock;
+exports.default = _default;
+},{}],"yqpU":[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 Nouveau Activity Widget to Activity 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_latest_activities';
+    },
+    transform: function transform(_ref2) {
+      var instance = _ref2.instance;
+      var regex = /i:\d*;s:\d*:"(.*?)";/gmi;
+      var types = [];
+      var matches;
+
+      while ((matches = regex.exec(instance.raw.type)) !== null) {
+        if (matches.index === regex.lastIndex) {
+          regex.lastIndex++;
+        }
+
+        matches.forEach(function (match, groupIndex) {
+          if (1 === groupIndex) {
+            types.push(match);
+          }
+        });
+      }
+
+      return createBlock('bp/latest-activities', {
+        title: instance.raw.title,
+        maxActivities: parseInt(instance.raw.max, 10),
+        type: types
+      });
+    }
+  }]
+};
+var _default = transforms;
+exports.default = _default;
+},{}],"q3eE":[function(require,module,exports) {
+"use strict";
+
+var _edit = _interopRequireDefault(require("./latest-activities/edit"));
+
+var _transforms = _interopRequireDefault(require("./latest-activities/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/latest-activities', {
+  title: __('Latest Activities', 'buddypress'),
+  description: __('Display the latest updates of the post author (when used into a page or post), of the displayed user (when viewing their profile) or of your community.', 'buddypress'),
+  icon: {
+    background: '#fff',
+    foreground: '#d84800',
+    src: 'buddicons-activity'
+  },
+  category: 'buddypress',
+  attributes: {
+    title: {
+      type: 'string',
+      default: __('Latest updates', 'buddypress')
+    },
+    maxActivities: {
+      type: 'number',
+      default: 5
+    },
+    type: {
+      type: 'array',
+      default: ['activity_update']
+    },
+    postId: {
+      type: 'number',
+      default: 0
+    }
+  },
+  edit: _edit.default,
+  transforms: _transforms.default
+});
+},{"./latest-activities/edit":"DIzr","./latest-activities/transforms":"yqpU"}]},{},["q3eE"], null)
\ No newline at end of file
diff --git src/bp-activity/sass/blocks/latest-activities.scss src/bp-activity/sass/blocks/latest-activities.scss
new file mode 100644
index 000000000..345258ee6
--- /dev/null
+++ src/bp-activity/sass/blocks/latest-activities.scss
@@ -0,0 +1,100 @@
+.bp-latest-activities {
+
+	.components-flex.components-select-control {
+
+		select[multiple] {
+			height: auto;
+			padding: 0 8px;
+
+			+ .components-input-control__suffix svg {
+				display: none;
+			}
+		}
+	}
+}
+
+.bp-latest-activities-block {
+
+	a,
+	.entry .entry-content & a {
+		border: none;
+		text-decoration: none;
+	}
+
+	.activity-list.item-list {
+
+		blockquote {
+			padding: 0;
+			border: none;
+
+			.activity-item {
+
+				&:not(.mini) {
+					position: relative;
+					box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
+					padding: 0 1em;
+
+					&:after,
+					&:before {
+						position: absolute;
+						left: 15px;
+						display: block;
+						width: 0;
+						height: 0;
+						border-style: solid;
+						border-color: transparent;
+						content: "";
+					}
+
+					&:before {
+						bottom: -18px;
+						border-top-color: rgba(0, 0, 0, 0.15);
+						border-width: 9px;
+						left: 14px;
+					}
+
+					&:after {
+						bottom: -16px;
+						border-top-color: #fff;
+						border-width: 8px;
+					}
+				}
+
+				&.mini {
+
+					.avatar {
+						display: inline-block;
+						width: 20px;
+						height: 20px;
+						vertical-align: middle;
+						margin-right: 2px;
+					}
+				}
+			}
+		}
+
+		footer {
+			display: flex;
+			align-items: center;
+
+			img.avatar {
+				display: inline-block;
+				border: none;
+				margin-right: 0.5em;
+			}
+
+			.activity-time-since {
+				font-size: 90%;
+			}
+		}
+	}
+
+	.widget-error {
+		border-left: solid 4px #0b80a4;
+		box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
+
+		p {
+			padding: 0 1em;
+		}
+	}
+}
diff --git src/js/bp-activity/js/blocks/latest-activities.js src/js/bp-activity/js/blocks/latest-activities.js
new file mode 100644
index 000000000..11c440455
--- /dev/null
+++ src/js/bp-activity/js/blocks/latest-activities.js
@@ -0,0 +1,48 @@
+/**
+ * WordPress dependencies.
+ */
+const {
+	blocks: {
+		registerBlockType,
+	},
+	i18n: {
+		__,
+	},
+} = wp;
+
+/**
+ * Internal dependencies.
+ */
+import editDynamicActivitiesBlock from './latest-activities/edit';
+import transforms from './latest-activities/transforms';
+
+registerBlockType( 'bp/latest-activities', {
+	title: __( 'Latest Activities', 'buddypress' ),
+	description: __( 'Display the latest updates of the post author (when used into a page or post), of the displayed user (when viewing their profile) or of your community.', 'buddypress' ),
+	icon: {
+		background: '#fff',
+		foreground: '#d84800',
+		src: 'buddicons-activity',
+	},
+	category: 'buddypress',
+	attributes: {
+		title: {
+			type: 'string',
+			default: __( 'Latest updates', 'buddypress' ),
+		},
+		maxActivities: {
+			type: 'number',
+			default: 5
+		},
+		type: {
+			type: 'array',
+			default: ['activity_update'],
+		},
+		postId: {
+			type: 'number',
+			default: 0,
+		},
+	},
+	edit: editDynamicActivitiesBlock,
+	transforms: transforms,
+} );
diff --git src/js/bp-activity/js/blocks/latest-activities/edit.js src/js/bp-activity/js/blocks/latest-activities/edit.js
new file mode 100644
index 000000000..942874abe
--- /dev/null
+++ src/js/bp-activity/js/blocks/latest-activities/edit.js
@@ -0,0 +1,85 @@
+/**
+ * WordPress dependencies.
+ */
+const {
+	blockEditor: {
+		InspectorControls,
+	},
+	components: {
+		Disabled,
+		PanelBody,
+		RangeControl,
+		SelectControl,
+		TextControl,
+	},
+	element: {
+		Fragment,
+		createElement,
+	},
+	i18n: {
+		__,
+	},
+} = wp;
+
+/**
+ * BuddyPress dependencies.
+ */
+const {
+	blockComponents: {
+		ServerSideRender,
+	},
+	blockData: {
+		currentPostId,
+		activityTypes,
+	}
+} = bp;
+
+const editDynamicActivitiesBlock = ( { attributes, setAttributes } ) => {
+	const { postId, maxActivities, type, title } = attributes;
+	const post = currentPostId();
+	const types = activityTypes();
+
+	if ( ! postId && post ) {
+		setAttributes( { postId: post } );
+	}
+
+	return (
+		<Fragment>
+			<InspectorControls>
+				<PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true } className="bp-latest-activities">
+					<TextControl
+						label={ __( 'Title', 'buddypress' ) }
+						value={ title }
+						onChange={ ( text ) => {
+							setAttributes( { title: text } );
+						} }
+					/>
+					<RangeControl
+						label={ __( 'Maximum amount to display', 'buddypress' ) }
+						value={ maxActivities }
+						onChange={ ( value ) =>
+							setAttributes( { maxActivities: value } )
+						}
+						min={ 1 }
+						max={ 10 }
+						required
+					/>
+					<SelectControl
+						multiple
+						label={ __( 'Type', 'buddypress' ) }
+						value={ type }
+						options={ types }
+						onChange={ ( option ) => {
+							setAttributes( { type: option } );
+						} }
+					/>
+				</PanelBody>
+			</InspectorControls>
+			<Disabled>
+				<ServerSideRender block="bp/latest-activities" attributes={ attributes } />
+			</Disabled>
+		</Fragment>
+	);
+};
+
+export default editDynamicActivitiesBlock;
diff --git src/js/bp-activity/js/blocks/latest-activities/transforms.js src/js/bp-activity/js/blocks/latest-activities/transforms.js
new file mode 100644
index 000000000..e7f060625
--- /dev/null
+++ src/js/bp-activity/js/blocks/latest-activities/transforms.js
@@ -0,0 +1,54 @@
+/**
+ * WordPress dependencies.
+ */
+const {
+	blocks: {
+		createBlock,
+	},
+} = wp;
+
+/**
+ * Transforms Nouveau Activity Widget to Activity Block.
+ *
+ * @type {Object}
+ */
+const transforms = {
+	from: [
+		{
+			type: 'block',
+			blocks: [ 'core/legacy-widget' ],
+			isMatch: ( { idBase, instance } ) => {
+				if ( ! instance?.raw ) {
+					return false;
+				}
+
+				return idBase === 'bp_latest_activities';
+			},
+			transform: ( { instance } ) => {
+				const regex = /i:\d*;s:\d*:"(.*?)";/gmi;
+				let types = [];
+				let matches;
+
+				while ( ( matches = regex.exec( instance.raw.type ) ) !== null ) {
+					if ( matches.index === regex.lastIndex ) {
+						regex.lastIndex++;
+					}
+
+					matches.forEach( ( match, groupIndex ) => {
+						if ( 1 === groupIndex ) {
+							types.push( match );
+						}
+					} );
+				}
+
+				return createBlock( 'bp/latest-activities', {
+					title: instance.raw.title,
+					maxActivities: parseInt( instance.raw.max, 10 ),
+					type: types,
+				} );
+			},
+		},
+	],
+};
+
+export default transforms;
