diff --git a/lib/blocks.php b/lib/blocks.php
index 70f9ec44cb32e..ac285855625a9 100644
--- a/lib/blocks.php
+++ b/lib/blocks.php
@@ -56,6 +56,7 @@ function gutenberg_reregister_core_block_types() {
'cover.php' => 'core/cover',
'latest-comments.php' => 'core/latest-comments',
'latest-posts.php' => 'core/latest-posts',
+ 'loginout.php' => 'core/loginout',
'navigation.php' => 'core/navigation',
'navigation-link.php' => 'core/navigation-link',
'rss.php' => 'core/rss',
diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js
index 8235b56631154..80bc845b9363e 100644
--- a/packages/block-library/src/index.js
+++ b/packages/block-library/src/index.js
@@ -38,6 +38,7 @@ import * as navigation from './navigation';
import * as navigationLink from './navigation-link';
import * as latestComments from './latest-comments';
import * as latestPosts from './latest-posts';
+import * as loginOut from './loginout';
import * as list from './list';
import * as missing from './missing';
import * as more from './more';
@@ -227,6 +228,7 @@ export const __experimentalRegisterExperimentalCoreBlocks =
queryPaginationNext,
queryPaginationNumbers,
queryPaginationPrevious,
+ loginOut,
postTitle,
postContent,
postAuthor,
diff --git a/packages/block-library/src/loginout/block.json b/packages/block-library/src/loginout/block.json
new file mode 100644
index 0000000000000..5c8240c0d7ca8
--- /dev/null
+++ b/packages/block-library/src/loginout/block.json
@@ -0,0 +1,19 @@
+{
+ "apiVersion": 2,
+ "name": "core/loginout",
+ "category": "design",
+ "attributes": {
+ "displayLoginAsForm": {
+ "type": "boolean",
+ "default": false
+ },
+ "redirectToCurrent": {
+ "type": "boolean",
+ "default": true
+ }
+ },
+ "supports": {
+ "className": true,
+ "fontSize": false
+ }
+}
diff --git a/packages/block-library/src/loginout/edit.js b/packages/block-library/src/loginout/edit.js
new file mode 100644
index 0000000000000..70e90bf84e903
--- /dev/null
+++ b/packages/block-library/src/loginout/edit.js
@@ -0,0 +1,44 @@
+/**
+ * WordPress dependencies
+ */
+import { PanelBody, ToggleControl } from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
+import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
+
+export default function LoginOutEdit( { attributes, setAttributes } ) {
+ const { displayLoginAsForm, redirectToCurrent } = attributes;
+
+ return (
+ <>
+
+
+
+ setAttributes( {
+ displayLoginAsForm: ! displayLoginAsForm,
+ } )
+ }
+ />
+
+ setAttributes( {
+ redirectToCurrent: ! redirectToCurrent,
+ } )
+ }
+ />
+
+
+
+ >
+ );
+}
diff --git a/packages/block-library/src/loginout/index.js b/packages/block-library/src/loginout/index.js
new file mode 100644
index 0000000000000..3f5c6625e0dc7
--- /dev/null
+++ b/packages/block-library/src/loginout/index.js
@@ -0,0 +1,22 @@
+/**
+ * WordPress dependencies
+ */
+import { __, _x } from '@wordpress/i18n';
+import { login as icon } from '@wordpress/icons';
+
+/**
+ * Internal dependencies
+ */
+import edit from './edit';
+import metadata from './block.json';
+
+const { name } = metadata;
+export { metadata, name };
+
+export const settings = {
+ title: _x( 'Login/out', 'block title' ),
+ description: __( 'Show login & logout links.' ),
+ icon,
+ keywords: [ __( 'login' ), __( 'logout' ), __( 'form' ) ],
+ edit,
+};
diff --git a/packages/block-library/src/loginout/index.php b/packages/block-library/src/loginout/index.php
new file mode 100644
index 0000000000000..3f4131ac1e572
--- /dev/null
+++ b/packages/block-library/src/loginout/index.php
@@ -0,0 +1,51 @@
+ false ) );
+ }
+
+ $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
+
+ return '' . $contents . '
';
+}
+
+/**
+ * Registers the `core/latest-posts` block on server.
+ */
+function register_block_core_loginout() {
+ register_block_type_from_metadata(
+ __DIR__ . '/loginout',
+ array(
+ 'render_callback' => 'render_block_core_loginout',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_loginout' );
diff --git a/packages/e2e-tests/fixtures/blocks/core__loginout.html b/packages/e2e-tests/fixtures/blocks/core__loginout.html
new file mode 100644
index 0000000000000..dab3964df07c5
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__loginout.html
@@ -0,0 +1 @@
+
diff --git a/packages/e2e-tests/fixtures/blocks/core__loginout.json b/packages/e2e-tests/fixtures/blocks/core__loginout.json
new file mode 100644
index 0000000000000..67eaab753bff3
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__loginout.json
@@ -0,0 +1,13 @@
+[
+ {
+ "clientId": "_clientId_0",
+ "name": "core/loginout",
+ "isValid": true,
+ "attributes": {
+ "displayLoginAsForm": false,
+ "redirectToCurrent": true
+ },
+ "innerBlocks": [],
+ "originalContent": ""
+ }
+]
diff --git a/packages/e2e-tests/fixtures/blocks/core__loginout.parsed.json b/packages/e2e-tests/fixtures/blocks/core__loginout.parsed.json
new file mode 100644
index 0000000000000..96c310c7e1456
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__loginout.parsed.json
@@ -0,0 +1,18 @@
+[
+ {
+ "blockName": "core/loginout",
+ "attrs": {},
+ "innerBlocks": [],
+ "innerHTML": "",
+ "innerContent": []
+ },
+ {
+ "blockName": null,
+ "attrs": {},
+ "innerBlocks": [],
+ "innerHTML": "\n",
+ "innerContent": [
+ "\n"
+ ]
+ }
+]
diff --git a/packages/e2e-tests/fixtures/blocks/core__loginout.serialized.html b/packages/e2e-tests/fixtures/blocks/core__loginout.serialized.html
new file mode 100644
index 0000000000000..dab3964df07c5
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__loginout.serialized.html
@@ -0,0 +1 @@
+
diff --git a/packages/icons/src/index.js b/packages/icons/src/index.js
index c90d743bb76d3..0e927cad85028 100644
--- a/packages/icons/src/index.js
+++ b/packages/icons/src/index.js
@@ -108,6 +108,7 @@ export { default as linkOff } from './library/link-off';
export { default as list } from './library/list';
export { default as listView } from './library/list-view';
export { default as lock } from './library/lock';
+export { default as login } from './library/login';
export { default as loop } from './library/loop';
export { default as mapMarker } from './library/map-marker';
export { default as media } from './library/media';
diff --git a/packages/icons/src/library/login.js b/packages/icons/src/library/login.js
new file mode 100644
index 0000000000000..9f529a0229fa4
--- /dev/null
+++ b/packages/icons/src/library/login.js
@@ -0,0 +1,12 @@
+/**
+ * WordPress dependencies
+ */
+import { SVG, Path } from '@wordpress/primitives';
+
+const login = (
+
+);
+
+export default login;