# Creating Sidebars in WordPress: Block, Post, Plugin, and Full Site Editor

In this guide, we’ll explore sidebars within WordPress, including block sidebar controls (for new and existing blocks), post sidebar controls. We’ll also delve into creating a fully custom plugin sidebar, and for those feeling adventurous, we will wrap up with a Full Site Editor (FSE) sidebar!

Sidebars serve as quick-access control panels within the block editor, perfect for custom settings and content controls.

You’ll see how to set up each one with `@wordpress/create-block` or in some cases `@wordpress/scripts`, and we will add unique settings and functionality to each sidebar.

If you are completely new to WordPress development environments and block creation, please [read the getting started with WordPress development guide](https://mattwatson.blog/getting-started-with-wordpress-block-development-using-studio-by-wordpresscom) first.

## What are WordPress Sidebars?

In the WordPress block editor, sidebars are panels on the right-hand side of the screen that offer quick access to settings and configuration options. These sidebars can be customised to provide controls specific to your content and enhance the editing experience.

There are several types of sidebars you can create:

1. **Block Sidebar (Inspector Controls)**: Ideal for configuring individual block settings, such as adding specific styling options, or other customisation for specific blocks in a post or page.
    
2. **Block Filters for All Blocks**: By using block filters, you can add controls to all blocks (even core blocks). This allows for consistent settings across different block types without modifying each block individually.
    
3. **Post Sidebar**: Provides options applicable to the entire post, such as a control for post meta.
    
4. **Custom Plugin Sidebar**: Acts as a dedicated settings panel, usually for broader configurations that need to be accessed across different content types or pages.
    
5. **Full Site Editor (FSE) Sidebar**: Ideal for site-wide settings and controls when working within the FSE, allowing global options that apply to all pages and posts.
    

In this article we will take a look at how to implement each type of sidebar and controls.

## 1\. Block-Level Sidebar: Toggle Block Visibility

Blocks can render pretty much any type of content. When you select a block the block sidebar usually becomes visible. It is here we can add controls so that we can customise our blocks layout, style or behaviour.

To showcase our block sidebar, we’ll create a custom block with a visibility toggle. When disabled, this toggle will prevent the block from rendering on the front end.

### 1.1: Setting Up the Block Attributes

First, we’ll use `@wordpress/create-block` to scaffold a new block plugin. Open your terminal and run the following command:

```bash
npx @wordpress/create-block block-visibility-toggle
```

This command will generate all the necessary files for a basic block plugin called `block-visibility-toggle`.

Next, open the generated `src/block.json` file in your code editor. We’ll need to add an attribute to control the visibility of the block. To do this add the following code inside the generated "attributes" object.

```json
"attributes": {
    "isVisible": {
        "type": "boolean",
        "default": true
    }
}
```

Your `block.json` file should now look like the following screenshot.

![The block.json file with added attributes](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244300141/8f2b176d-3348-46d5-a767-530e41db3412.png align="center")

### 1.2: Building the Sidebar Toggle

Next, we’ll create a toggle control in the block’s sidebar to allow users to show or hide the block. Open the `src/edit.js` file and modify it as follows:

```javascript
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { ToggleControl, PanelBody } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function Edit( { attributes, setAttributes } ) {
    const { isVisible } = attributes;

    return (
        <>
            <InspectorControls>
                <PanelBody title={ __( 'Block Settings', 'block-visibility-toggle' ) }>
                    <ToggleControl
                        label={ __( 'Display Block', 'block-visibility-toggle' ) }
                        checked={ isVisible }
                        onChange={ ( value ) => setAttributes( { isVisible: value } ) }
                    />
                </PanelBody>
            </InspectorControls>
            <div { ...useBlockProps() }>
                { isVisible ?
                    <p>{ __( 'Your content here.', 'block-visibility-toggle' ) }</p>
                :
					<p>{ __( 'Your block will be hidden.', 'block-visibility-toggle' ) }</p>
				}
            </div>
        </>
    );
}
```

#### 1.2.1: Display Controls to the Advanced Section

If you prefer, you can place the visibility toggle under the “Advanced” section of the block sidebar.

To do this, replace `InspectorControls` with `InspectorAdvancedControls` in your `edit.js` file. You can also remove the PanelBody too, as the Advanced section acts as its own Panel.

```javascript
import { InspectorAdvancedControls, useBlockProps } from '@wordpress/block-editor';
import { ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function Edit( { attributes, setAttributes } ) {
    const { isVisible } = attributes;

    return (
        <>
            <InspectorAdvancedControls>
                <ToggleControl
                    label={ __( 'Display Block', 'block-visibility-toggle' ) }
                    checked={ isVisible }
                    onChange={ ( value ) => setAttributes( { isVisible: value } ) }
                />
            </InspectorAdvancedControls>
            <div { ...useBlockProps() }>
                { isVisible ?
                    <p>{ __( 'Your content here.', 'block-visibility-toggle' ) }</p>
                :
					<p>{ __( 'Your block will be hidden.', 'block-visibility-toggle' ) }</p>
				}
            </div>
        </>
    );
}
```

### 1.3: Altering the Save Function to Hide the Block

Modify the save function in `src/save.js` to check the `isVisible` attribute. Open `src/save.js` and update it as follows:

```javascript
import { useBlockProps } from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';

export default function save( { attributes } ) {
    const { isVisible } = attributes;

    if ( ! isVisible ) {
        // If the block is set to not visible, return null to render nothing.
        return null;
    }

    return (
        <div { ...useBlockProps.save() }>
            <p>{ __( 'Your content here.', 'block-visibility-toggle' ) }</p>
        </div>
    );
}
```

By returning `null` when `isVisible` is false, the block will not output any HTML on the front end, effectively hiding it.

### 1.4: Using the Sidebar

Remember to run `npm run build` in your block directory and to activate the block.

![Activate the Block Visibility Toggle Plugin](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244403632/797e442a-8dbc-46f3-b3c8-6367a689d961.png align="center")

Once you have done this, you can insert the custom block you created by typing `/` and searching for `Block Visibility Toggle`.

![Inserting the Block Visibility Toggle Plugin](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244409757/386bfde0-bad7-42f1-b095-1d2bcceabed2.png align="center")

After you have inserted the block, click on it to reveal the “Block” section of the “Post” sidebar. Here you will see the new “Display Block” toggle.

![The inserted block and the Display Block Toggle](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244421272/0eed4b2e-134c-4d0a-896a-6c1c26e1f29a.png align="center")

Do not toggle it just yet, first check that the block displays as expected on the front end.

![The block is showing on the front end.](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244434016/f94dbe07-0f41-45b2-a275-bd3facc1d8ca.png align="center")

Now toggle the “Display Block” toggle in the backend, and save your post.

![Toggle the "Display Block" toggle](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244448695/b3bb03a2-a29b-42ba-b46e-f3f60b847635.png align="center")

If all worked as expected, you should no longer be able to see the block on the front end of the site.

![The block is no longer displayed on the front end of the site](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244460747/c1ac0d30-ebeb-4eb3-8fd7-fd63becea9eb.png align="center")

As mentioned in section 1.2.1 you can display controls in the Advanced section of the sidebar with `InspectorAdvancedControls`. That should look a little like the following screenshot.

![Display block toggle showing in the Advanced controls section](https://cdn.hashnode.com/res/hashnode/image/upload/v1730326209899/9ffbee8b-2f50-4ee0-9ea1-1faa8b077b9e.png align="center")

## 2\. Using Block Filters: Adding Block Visibility Toggle to All Blocks

Sometimes you cannot alter the markup of a block. Perhaps it is a WordPress Core block that you wish to add additional controls to, or one provided by a plugin, or perhaps you just want to register one control that can be used on several blocks (gotta keep it <abbr>DRY</abbr>).

We will showcase this by using block filters to inject the toggle control into the sidebar of every block (realistically you would probably restrict which blocks use it).

### 2.1: Setting Up the Plugin

Since we need to create a plugin that modifies existing blocks, `@wordpress/create-block` might not be the most suitable tool. Instead, we’ll manually create a plugin and use `@wordpress/scripts` (also known as `wp-scripts`) to handle the build process.

Create a new folder in your `wp-content/plugins` directory called `global-block-visibility-toggle`. Inside this folder, create a PHP file named `global-block-visibility-toggle.php` and add the following plugin header:

```php
<?php
/**
 * Plugin Name: Global Block Visibility Toggle
 * Description: Adds a visibility toggle to all blocks using a block filter.
 * Version: 1.0.0
 * Author: Your Name
 * Text Domain: global-block-visibility-toggle
 */
```

### 2.2: Setting Up the Development Environment with `wp-scripts`

We’ll use `@wordpress/scripts` to simplify our build process. This package provides a pre-configured build setup for WordPress development, allowing us to write modern JavaScript without manually configuring tools like webpack and Babel.

`wp-scripts` gives you a build process very similar to the `create-block` script. To do this we will need to run a few commands, if you need to re-familiarise yourself with some of the concepts, give the [WordPress development guide](https://mattwatson.blog/getting-started-with-wordpress-block-development-using-studio-by-wordpresscom) a read.

#### 2.2.1: Initialise `package.json`

Make sure you are in the `plugins` directory. Open your terminal and navigate to the plugin directory:

```bash
cd global-block-visibility-toggle
```

Initialize a new `package.json` file by running:

```bash
npm init -y
```

This will create a basic `package.json` file in your plugin directory.

#### 2.2.2: Install `@wordpress/scripts`

Install `@wordpress/scripts` as a development dependency:

```bash
npm install @wordpress/scripts --save-dev
```

#### 2.2.3: Update `package.json` Scripts

In your package.json file, add the following scripts:

```json
"scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start",
    "format": "wp-scripts format",
    "lint:css": "wp-scripts lint-style",
    "lint:js": "wp-scripts lint-js",
    "lint:md:docs": "wp-scripts lint-md-docs"
},
```

To add in the description and to save some time, you can copy the below to your \`package.json file.

```json
{
  "name": "global-block-visibility-toggle",
  "version": "1.0.0",
  "description": "Adds a visibility toggle to all blocks using a block filter.",
  "main": "index.js",
  "scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start",
    "format": "wp-scripts format",
    "lint:css": "wp-scripts lint-style",
    "lint:js": "wp-scripts lint-js",
    "lint:md:docs": "wp-scripts lint-md-docs"
  },
  "author": "Your Name",
  "license": "GPL-2.0-or-later",
  "devDependencies": {
    "@wordpress/scripts": "^24.0.0"
  }
}
```

#### 2.2.4: Create the `src` Directory and `index.js` File

Create a src directory inside your plugin folder:

```bash
mkdir src
```

Inside the `src` directory, create a file named `index.js`. This is where we’ll write our JavaScript code to add the visibility toggle to all blocks.

### 2.3: Registering the Block Filter

In `src/index.js`, add the following code:

```javascript
import { addFilter } from '@wordpress/hooks';
import { InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
 * Add the 'isVisible' attribute to save the visibility state.
 *
 * @param {Object} settings Original block settings.
 * @returns {Object} Modified block settings with new attribute.
 */
function addVisibilityAttribute( settings ) {
    settings.attributes = {
        ...settings.attributes,
        isVisible: {
            type: 'boolean',
            default: true,
        },
    };

    return settings;
}

addFilter(
    'blocks.registerBlockType',
    'gbvt/add-visibility-attribute',
    addVisibilityAttribute
);

/**
 * Wraps the block's edit component to include the visibility toggle control in advanced settings.
 *
 * @param {Function} BlockEdit The original block edit component.
 * @returns {Function} Wrapped component with visibility toggle control.
 */
const addVisibilityToggleControl = ( BlockEdit ) => ( props ) => {
    const { attributes, setAttributes } = props;
    const { isVisible } = attributes;

    return (
        <>
            <BlockEdit { ...props } />
            <InspectorControls>
                <PanelBody title={ __( 'Block Settings', 'block-visibility-toggle' ) }>
                    <ToggleControl
                        label={ __( 'Display Block', 'global-block-visibility-toggle' ) }
                        checked={ isVisible }
                        onChange={ ( value ) => setAttributes( { isVisible: value } ) }
                        help={ __( 'Toggle block visibility on the front end.', 'global-block-visibility-toggle' ) }
                    />
                </PanelBody>
            </InspectorControls>
        </>
    );
};

addFilter(
    'editor.BlockEdit',
    'gbvt/add-visibility-toggle-control',
    addVisibilityToggleControl
);
```

### 2.4: Applying the Visibility on the Front End

Now, we need to ensure that blocks with `isVisible` set to false do not render on the front end. We’ll use a PHP filter to modify the rendered content.

In your `global-block-visibility-toggle.php` file, add the following code:

```php
<?php
/**
 * Plugin Name: Global Block Visibility Toggle
 * Description: Adds a visibility toggle to all blocks using a block filter.
 * Version: 1.0.0
 * Author: Your Name
 * Text Domain: global-block-visibility-toggle
 */

/**
 * Enqueue block editor assets.
 */
function gbvt_enqueue_block_editor_assets() {
    wp_enqueue_script(
        'gbvt-editor-script',
        plugins_url( 'build/index.js', __FILE__ ),
        [ 'wp-blocks', 'wp-dom-ready', 'wp-edit-post', 'wp-hooks' ],
        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
    );
}
add_action( 'enqueue_block_editor_assets', 'gbvt_enqueue_block_editor_assets' );

/**
 * Filter block content to control visibility on the front end.
 *
 * @param string $block_content The block content.
 * @param array  $block         The block settings.
 * @return string Modified block content.
 */
function gbvt_filter_block_visibility( $block_content, $block ) {
    if ( isset( $block['attrs']['isVisible'] ) && ! $block['attrs']['isVisible'] ) {
        return ''; // Do not render the block
    }
    return $block_content;
}
add_filter( 'render_block', 'gbvt_filter_block_visibility', 10, 2 );
```

### 2.5: Building and Activating the Plugin

We need to build our JavaScript code into a `build/index.js` file that can be enqueued.

With `@wordpress/scripts`, we can use the following command to build our JavaScript files:

```bash
npm run build
```

This will compile `src/index.js` and output the result to `build/index.js`.

Alternatively, if you want to watch for changes and rebuild automatically during development, you can use:

```bash
npm run start
```

This command runs in watch mode, rebuilding the code whenever you save changes.

### 2.6: Using the Sidebar

Remember after you have ran `npm run build` that you need to activate the plugin.

![Activate the Global Block Visibility Toggle](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244619121/71099cb7-0714-4553-be44-63bc7570cdaa.png align="center")

Select any block (in this case I’m selecting the paragraph block) and note that the Display Block toggle is now visible.

Toggle this so that it no longer displays, and save the post.

![The paragraph block now has the display block toggle](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244631695/c31adc02-c627-4619-8296-67ff40fb0953.png align="center")

When you view the post on the front end, that block (the paragraph block) is no longer visible.

![The paragraph block is no longer visible](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244656198/1ba68ece-b096-4fd8-b196-bc8d81d98d9c.png align="center")

## 3\. Post-Level Sidebar: Toggle Post Content Visibility

If you would like to add a control that impacts the entire post, you can add controls to the post sidebar. In this type of sidebar it might make sense for the controls to alter post meta data.

To showcase a post-level sidebar that allows you to toggle the visibility of the post content. If disabled, the content will not display on the front end, and a custom message will be shown instead.

### 3.1: Setting Up the Plugin

Create a new plugin folder called `post-content-visibility` in your WordPress `wp-content/plugins` directory.

Inside this folder, create a `src` folder for your JavaScript code and a `post-content-visibility.php` file for the plugin’s PHP code.

As per the last example we are going to use `wp-scripts`. We will take a bit of a shortcut this time, by setting up the `package.json` file and then running our setup command.

In the `post-content-visibility` folder, initialise your package with `wp-scripts` creating the following `package.json` file in the root of the plugin.

```json
{
    "name": "post-content-visibility",
    "version": "1.0.0",
    "description": "Toggle the visibility of post content from the editor sidebar.",
    "main": "index.js",
    "scripts": {
        "build": "wp-scripts build",
        "start": "wp-scripts start"
    },
    "keywords": [],
    "author": "Your Name",
    "license": "ISC",
    "dependencies": {
        "@wordpress/scripts": "^25.0.0"
    }
}
```

Now run `npm install` from inside the `post-content-visibility` folder, and wait for the package to initialise. You can now build and run your JavaScript using `npm run build` or `npm start`.

### 3.2: Registering Post Meta

We need to register a post meta field to store the visibility setting. Open the `post-content-visibility.php` file in the plugin directory and add the following code:

```php
<?php
/**
 * Plugin Name:       Post Content Visibility
 * Description:       Adds a toggle to control the visibility of post content on the front end.
 * Version:           1.0.0
 * Author:            Your Name
 * Text Domain:       post-content-visibility
 */

function pcv_register_post_meta() {
    register_post_meta( '', 'pcv_display_post_content', [
        'show_in_rest' => true,
        'single'       => true,
        'type'         => 'boolean',
        'default'      => true,
    ] );
}
add_action( 'init', 'pcv_register_post_meta' );
```

By registering the meta for all post types (denoted by the empty string `''`), we can use this setting across different content types.

### 3.3: Enqueuing the Sidebar Toggle Script

Add the following code to your `post-content-visibility.php` file to enqueue the sidebar toggle script in the block editor:

```php
function pcv_enqueue_editor_assets() {
    wp_enqueue_script(
        'post-content-visibility',
        plugins_url( 'build/index.js', __FILE__ ),
        array( 'wp-plugins', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-data', 'wp-i18n' ),
        '1.0.0',
        true
    );
}
add_action( 'enqueue_block_editor_assets', 'pcv_enqueue_editor_assets' );
```

This function ensures that the script is loaded in all editors that support the block editor.

### 3.4: Building the Toggle in the Post Sidebar

We’ll use the `PluginDocumentSettingPanel` component to add a custom panel in the post sidebar. Open `src/index.js` and replace its content with the following code.

```javascript
import { PluginDocumentSettingPanel } from '@wordpress/editor';
import { ToggleControl } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { registerPlugin } from '@wordpress/plugins';
import { __ } from '@wordpress/i18n';

const PostContentVisibility = () => {
    const { editPost } = useDispatch( 'core/editor' );
    const displayContent = useSelect(
        ( select ) => select( 'core/editor' )?.getEditedPostAttribute( 'meta' )?.['pcv_display_post_content'],
        []
    );

    return (
        <PluginDocumentSettingPanel
            name="post-content-visibility"
            title={ __( 'Post Content Visibility', 'post-content-visibility' ) }
            className="post-content-visibility-panel"
        >
            <ToggleControl
                label={ __( 'Display Post Content', 'post-content-visibility' ) }
                checked={ displayContent }
                onChange={ ( value ) => editPost( { meta: { pcv_display_post_content: value } } ) }
                help={ __( 'Toggle the visibility of the post content on the front end.', 'post-content-visibility' ) }
            />
        </PluginDocumentSettingPanel>
    );
};

// Check if we're in the Post Editor before registering the plugin.
if ( window.pagenow !== 'site-editor' ) {
    registerPlugin( 'post-content-visibility', {
        render: PostContentVisibility,
        icon: 'visibility',
    } );
}
```

This component fetches the `pcv_display_post_content` meta field and updates it when the toggle is changed.

### 3.5: Modifying the Front-End Display

We need to check the meta value when rendering the post content and conditionally display it. In `post-content-visibility.php`, add the following code:

```php
function pcv_filter_the_content( $content ) {
    if ( is_singular() ) {
        $display_content = get_post_meta( get_the_ID(), 'pcv_display_post_content', true );
        if ( ! $display_content ) {
            return '<p>' . __( 'This post is hidden from view.', 'post-content-visibility' ) . '</p>';
        }
    }
    return $content;
}
add_filter( 'the_content', 'pcv_filter_the_content' );
```

This function checks if the `pcv_display_post_content` meta is `false` and replaces the content with a custom message if so.

### 3.6: Building the Plugin

After updating `src/index.js`, build your JavaScript file using `wp-scripts`:

```bash
npm run build
```

This will generate a `build/index.js` file. Your plugin is now ready to use!

### Step 7: Using the Sidebar

Remember to activate the plugin.

![Activate the Post Content Visibility Sidebar](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244722333/fbc8e72b-6cd1-4cf5-9c53-717985e4b7f6.png align="center")

Note that in the post sidebar we now have the Display Post Content toggle.

Switch the toggle and save the post.

![The Display Post Content toggle is available in the post sidebar](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244730696/58b72d05-42a2-49ec-993c-126a25e8b752.png align="center")

Note that we have now replaced the content of the entire post.

![The post content has now been replaced](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244756112/7cffac99-3de0-4b2b-9c6b-ef9fd5b30d28.png align="center")

## 4\. Custom Plugin Sidebar: Toggle Entire Post Visibility

Sometimes you might have a plugin that adds many post controls, when this happens it might make sense to put all of these in a custom sidebar so that they are all together, easily identifiable and reduce post sidebar clutter.

In this section, we’ll create a custom plugin sidebar that allows you to toggle the entire post’s visibility. When disabled, the post will not be accessible on the front end, and visitors will see a 404 error.

### 4.1: Setting Up the Plugin

Create a new plugin folder called `post-visibility-toggle` in your WordPress `wp-content/plugins` directory.

Inside this folder, create a `src` folder for your JavaScript code and a `post-visibility-toggle.php` file for the plugin’s PHP code.

As per the last couple of examples, we are going to use `wp-scripts`. In the `post-visibility-toggle` folder, initialise your package with `wp-scripts` by creating the following `package.json` file in the root of the plugin:

```json
{
    "name": "post-visibility-toggle",
    "version": "1.0.0",
    "description": "Toggle the visibility of the entire post from the editor sidebar.",
    "main": "index.js",
    "scripts": {
        "build": "wp-scripts build",
        "start": "wp-scripts start"
    },
    "keywords": [],
    "author": "Your Name",
    "license": "ISC",
    "dependencies": {
        "@wordpress/scripts": "^25.0.0"
    }
}
```

Now run `npm install` from inside the `post-visibility-toggle` folder, and wait for the package to initialise. You can now build and run your JavaScript using `npm run build` or `npm start`.

### 4.2: Registering Post Meta

Open the `post-visibility-toggle.php` file, make sure the enqueue for the editor and register a post meta field to store the visibility setting:

```php
<?php
/**
 * Plugin Name:       Post Visibility Toggle
 * Description:       Adds a toggle to control the visibility of the entire post on the front end.
 * Version:           1.0.0
 * Author:            Your Name
 * Text Domain:       post-visibility-toggle
 */

function pvt_enqueue_editor_assets() {
    wp_enqueue_script(
        'post-visibility-toggle',
        plugins_url( 'build/index.js', __FILE__ ),
        [ 'wp-plugins', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-data', 'wp-i18n' ],
        '1.0.0',
        true
    );
}
add_action( 'enqueue_block_editor_assets', 'pvt_enqueue_editor_assets' );

function pvt_register_post_meta() {
    register_post_meta( '', 'pvt_display_post', [
        'show_in_rest' => true,
        'single'       => true,
        'type'         => 'boolean',
        'default'      => true,
    ] );
}
add_action( 'init', 'pvt_register_post_meta' );
```

### 4.3: Creating the Plugin Sidebar

In `src/index.js`, create the plugin sidebar with a toggle control:

```javascript
import { PluginSidebar } from '@wordpress/editor';
import { ToggleControl, PanelBody } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { registerPlugin } from '@wordpress/plugins';
import { __ } from '@wordpress/i18n';

const PostVisibilityToggle = () => {
    const { editPost } = useDispatch('core/editor');
    const displayPost = useSelect(
        ( select ) => select( 'core/editor' )?.getEditedPostAttribute( 'meta' )?.['pvt_display_post'],
        []
    );

    return (
        <PluginSidebar
            name="post-visibility-toggle"
            title={ __( 'Post Visibility', 'post-visibility-toggle' ) }
            icon="visibility"
        >
            <PanelBody title={ __('Post Visibility Settings', 'post-visibility-toggle' ) }>
                <ToggleControl
                    label={ __( 'Display Post', 'post-visibility-toggle' ) }
                    checked={ displayPost }
                    onChange={ ( value ) => editPost( { meta: { pvt_display_post: value } } ) }
                    help={ __( 'Toggle the visibility of the entire post on the front end.', 'post-visibility-toggle' ) }
                />
            </PanelBody>
        </PluginSidebar>
    );
};

// Check if we're in the Post Editor before registering the plugin.
if ( window.pagenow !== 'site-editor' ) {
    registerPlugin( 'post-visibility-toggle', {
        render: PostVisibilityToggle,
        icon: 'visibility',
    } );
}
```

This code creates a sidebar that appears in the editor where you can toggle the entire post’s visibility.

### 4.4: Redirecting Hidden Posts to 404

In the plugin’s PHP file, we’ll add an action to redirect to a 404 page if the post is hidden:

```php
function pvt_redirect_hidden_posts() {
    if ( is_singular() && !is_admin() ) {
        $display_post = get_post_meta( get_the_ID(), 'pvt_display_post', true );
        if ( ! $display_post ) {
            global $wp_query;
            $wp_query->set_404();
            status_header( 404 );
            nocache_headers();
            include( get_query_template( '404' ) );
            exit;
        }
    }
}
add_action( 'template_redirect', 'pvt_redirect_hidden_posts' );
```

This function checks if the post should be displayed and, if not, sets a 404 status and loads the 404 template.

### 4.5: Using the Sidebar

Remember to run `npm run build` in your block directory and to activate the plugin.

![Activate the Post Visibility Toggle](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244790373/70a3d4e1-f60a-495a-bf0b-61459a7ad826.png align="center")

Now you should be able to see your custom Post Visibility sidebar, identified by the “eye” icon. Click the icon and it should open up the sidebar. Once you have done this you should be able to see the controls that you registered for the sidebar.

Be sure to switch the toggle and save the post.

![You can select the Post Visibility Sidebar](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244799780/2cd14481-6387-4af1-83fa-2839776b1452.png align="center")

As per the logic we set, this will redirect the post to a 404 page on the front end.

![Our custom logic redirects the post to a 404](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244809627/47143d70-ba69-4a61-87a0-72c1d46c4625.png align="center")

## 5\. Full Site Editor (FSE) Sidebar: Global Settings

We have explored block settings with block sidebars, post settings with post sidebars and custom sidebars. What if we want something that impacts the entire site? Say something that is stored in an option?

To explore this we’ll create a sidebar in the Full Site Editor (FSE) to manage global site-wide settings. This sidebar can control settings that affect the entire website.

In this example, we will prevent the entire site from displaying with a `wp_die()`. **This is absolutely overkill (and you should never do this)**, but it serves to prove how this kind of sidebar can be used.

### 5.1: Setting Up the Plugin

Create a new plugin folder called `fse-global-settings` in your WordPress `wp-content/plugins` directory.

Inside this folder, create a `src` folder for your JavaScript code and a `fse-global-settings.php` file for the plugin’s PHP code.

As per the last few examples, we are going to use `wp-scripts`. In the `fse-global-settings` folder, initialise your package with `wp-scripts` by creating the following `package.json` file in the root of the plugin:

```json
{
    "name": "fse-global-settings",
    "version": "1.0.0",
    "description": "Adds a custom sidebar to the Full Site Editor for global settings.",
    "main": "index.js",
    "scripts": {
        "build": "wp-scripts build",
        "start": "wp-scripts start"
    },
    "keywords": [],
    "author": "Your Name",
    "license": "ISC",
    "dependencies": {
        "@wordpress/scripts": "^25.0.0"
    }
}
```

Now run `npm install` from inside the `fse-global-settings` folder, and wait for the package to initialise. You can now build and run your JavaScript using `npm run build` or `npm start`.

### 5.2: Enqueueing Scripts and Styles

We need to include our plugin header in the root plugin file.

We’ll also enqueue our JavaScript file that registers the sidebar component. In `fse-global-settings.php`, add the following code:

```php
<?php
/**
 * Plugin Name: FSE Global Settings
 * Description: Adds a custom sidebar to the Full Site Editor for global settings.
 * Version: 1.0.0
 * Author: Your Name
 * Text Domain: fse-global-settings
 */

function fse_gs_enqueue_assets() {
    wp_enqueue_script(
        'fse-gs-editor-script',
        plugins_url( 'build/index.js', __FILE__ ),
        [ 'wp-edit-site', 'wp-plugins', 'wp-element', 'wp-data', 'wp-components', 'wp-i18n' ],
        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
    );
}
add_action( 'enqueue_block_editor_assets', 'fse_gs_enqueue_assets' );
```

### 5.3: Creating the Sidebar Component

Now, we’ll add the code for the sidebar. In `src/index.js`, add the following:

```javascript
import { registerPlugin } from '@wordpress/plugins';
import { PluginSidebar } from '@wordpress/edit-site';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';

const GlobalSettingsSidebar = () => {
    const { editEntityRecord } = useDispatch( 'core' );
    const globalVisibility = useSelect( ( select ) => {
        const settings = select('core').getEntityRecord( 'root', '__experimentalSite' );
        return settings ? settings.global_visibility : true;
    }, []);

    const onChange = (value) => {
        editEntityRecord( 'root', '__experimentalSite', undefined, { global_visibility: value } );
    };

    return (
        <PluginSidebar
            name="fse-global-settings"
            title={ __( 'Global Settings', 'fse-global-settings' ) }
            icon="admin-site"
        >
            <PanelBody title={ __( 'Site-Wide Settings', 'fse-global-settings' ) }>
                <ToggleControl
                    label={ __('Enable Global Content Visibility', 'fse-global-settings' ) }
                    checked={ globalVisibility }
                    onChange={ onChange }
                    help={ __( 'Toggle global visibility settings for the site.', 'fse-global-settings' ) }
                />
            </PanelBody>
        </PluginSidebar>
    );
};

// Check if we're in the Site Editor before registering the plugin.
if ( window.pagenow === 'site-editor' ) {
    registerPlugin( 'fse-global-settings', {
        render: GlobalSettingsSidebar,
    } );
}
```

### 5.4: Registering Global Settings

We need to register the `global_visibility` setting so it can be saved and retrieved. In `fse-global-settings.php`, add:

```php
function fse_gs_register_settings() {
    register_setting( 'general', 'global_visibility', [
        'type'         => 'boolean',
        'default'      => true,
        'show_in_rest' => true,
    ] );
}
add_action( 'init', 'fse_gs_register_settings' );
```

### 5.5: Applying Global Settings on the Front End

Finally, we’ll check the `global_visibility` setting when rendering the site. In your theme’s `functions.php` or within the plugin, add:

```php
function fse_gs_check_global_visibility() {
    $global_visibility = get_option( 'global_visibility', true );
    if ( ! $global_visibility ) {
        // Redirect to maintenance page or display a message.
        wp_die( __( 'The site is currently not visible.', 'fse-global-settings' ) );
    }
}
add_action( 'template_redirect', 'fse_gs_check_global_visibility' );
```

This function checks the `global_visibility` option and, if set to `false`, prevents the site from displaying.

### 5.6: Using the Sidebar

Remember to run `npm run build` in your block directory and to activate the plugin.

![Activate the FSE Global Settings plugin](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244832299/19206c17-26c1-4c65-b794-0bb1872591c6.png align="center")

Now, when you edit a template in the Full Site Editor, you will see the “globe” icon. Clicking on this icon will open the sidebar we just created.

Again, the control we added to the sidebar is visible. Toggle this and save the sidebar.

You will likely then be prompted by another confirmation sidebar, save the setting here too.

![The Global Settings sidebar is now visible](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244842808/766ff3bc-8470-4b70-b9ff-5413d7221bf8.png align="center")

As per our logic, we get a side wide message, preventing us from loading the site.

![The logic relating to our custom control is shown](https://cdn.hashnode.com/res/hashnode/image/upload/v1730244849551/1e03f086-9561-4e87-bf8b-7b508800e279.png align="center")

---

## Conclusion

You’ve learned how to create four distinct types of sidebars in WordPress: block-level controls, post-specific options, a custom plugin sidebar, and a Full Site Editor sidebar. Each of these sidebars provides specialized content control options, enhancing both the editing experience and the front-end behavior of your site.

We also explored how to use block filters to add features to all blocks, and discussed when `@wordpress/create-block` is suitable for plugin creation and when manual `@wordpress/scripts` is more appropriate.

If you have any questions, please drop them below in the comments.
