2026年8月11日

2026年8月11日

WordPressのブロックエディターに独自のキーボードショートカットを追加する方法

ブロックエディターに独自のショートカットを足すには、@wordpress/keyboard-shortcuts パッケージの registerShortcut でキーの組み合わせを登録し、useShortcut で押されたときの処理を結びつけます。この記事では、選択中のブロックの下に区切りブロックを挿入するショートカットを例に、小さなプラグインとして実装し、ヘルプ画面に表示させ、既存のショートカットとの衝突を避けるところまでを説明します。

仕組みの全体像

ブロックエディターのショートカットは、ブラウザーの keydown を自前で拾うのではなく、core/keyboard-shortcuts というデータストアで一元管理されています。保存(Ctrl+S)やブロックの複製、リスト表示の切り替えなど、コアのショートカットの多くもこのストアに名前付きで登録されています。

独自のショートカットも同じ流れに乗せるのが筋です。理由は三つあります。

  • 編集キャンバスは iframe の中に描画されることが多く、document.addEventListener( 'keydown', ... ) で拾おうとすると、カーソルがキャンバス内にあるときに反応しないことがある
  • ストアに登録すると、ショートカット一覧のヘルプ画面にも説明つきで表示される
  • 名前で管理されるので、ほかのプラグインからの参照や解除がしやすい

実装は「登録(registerShortcut)」と「処理の割り当て(useShortcut)」の二段構えです。どちらも React コンポーネントの中で使うため、@wordpress/plugins の registerPlugin で画面に何も描画しないコンポーネントを差し込み、その中で両方を呼び出します。

準備:プラグインの骨組みを作る

テーマの functions.php ではなく、独立した小さなプラグインにするのがおすすめです。テーマを変えてもショートカットが残り、不具合が出たときはプラグインを無効化するだけで切り分けられます。本番サイトで試す前に、ステージング環境かローカル環境で動作を確かめ、念のためバックアップも取っておいてください。

JavaScript は @wordpress/scripts でビルドする前提で書きます。ビルドすると build/index.js と一緒に build/index.asset.php が生成され、そこに依存スクリプト(wp-keyboard-shortcuts など)とバージョン文字列が自動で書き出されます。依存関係を手で書くと漏れやすいので、このファイルを読み込む形にしておくと安全です。

my-editor-shortcuts/
├── my-editor-shortcuts.php
├── package.json
├── src/
│   └── index.js
└── build/        ← npm run build で生成
cd wp-content/plugins/my-editor-shortcuts
npm init -y
npm install --save-dev @wordpress/scripts
# package.json の scripts に "build": "wp-scripts build" と "start": "wp-scripts start" を追加
npm run build

PHP 側では enqueue_block_editor_assets フックでスクリプトを読み込みます。このフックはブロックエディターの画面でだけ実行されるので、フロントエンドや他の管理画面に余計なスクリプトが載りません。

<?php
/**
 * Plugin Name: My Editor Shortcuts
 * Description: ブロックエディターに独自のキーボードショートカットを追加します。
 * Version: 1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

add_action( 'enqueue_block_editor_assets', function () {
	$asset_file = plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
	if ( ! file_exists( $asset_file ) ) {
		return; // ビルド前は何もしない
	}
	$asset = require $asset_file;

	wp_enqueue_script(
		'my-editor-shortcuts',
		plugins_url( 'build/index.js', __FILE__ ),
		$asset['dependencies'],
		$asset['version'],
		true
	);
} );

ショートカットを登録して処理を割り当てる

次が本体です。registerShortcut には、ショートカットの一意な名前、カテゴリー、説明文、キーの組み合わせを渡します。名前は プラグイン名/動作名 の形にしておくと、コアや他のプラグインと重なりません。

import { registerPlugin } from '@wordpress/plugins';
import { useEffect } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import {
	store as keyboardShortcutsStore,
	useShortcut,
} from '@wordpress/keyboard-shortcuts';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { createBlock } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';

const SHORTCUT_NAME = 'my-editor-shortcuts/insert-separator';

function MyEditorShortcuts() {
	const { registerShortcut, unregisterShortcut } = useDispatch( keyboardShortcutsStore );
	const { insertBlock } = useDispatch( blockEditorStore );

	// useSelect にストアだけを渡すと、再描画を伴わないセレクターの集合が返る。
	// キー操作のたびに最新の状態を読むので、イベント処理の中で呼び出す。
	const { getSelectedBlockClientId, getBlockRootClientId, getBlockIndex } =
		useSelect( blockEditorStore );

	useEffect( () => {
		registerShortcut( {
			name: SHORTCUT_NAME,
			category: 'block',
			description: __( '選択中のブロックの下に区切りを挿入', 'my-editor-shortcuts' ),
			keyCombination: {
				modifier: 'access', // Windows: Shift+Alt / Mac: Control+Option
				character: 'k',
			},
		} );
		return () => unregisterShortcut( SHORTCUT_NAME );
	}, [ registerShortcut, unregisterShortcut ] );

	useShortcut( SHORTCUT_NAME, ( event ) => {
		const clientId = getSelectedBlockClientId();
		if ( ! clientId ) {
			return; // ブロック未選択なら何もしない
		}
		event.preventDefault();
		const rootClientId = getBlockRootClientId( clientId );
		const index = getBlockIndex( clientId );
		insertBlock( createBlock( 'core/separator' ), index + 1, rootClientId );
	} );

	return null;
}

registerPlugin( 'my-editor-shortcuts', { render: MyEditorShortcuts } );

ポイントをいくつか補足します。

登録は useEffect の中で行う。 コンポーネントの描画のたびに登録し直さないためです。戻り値で unregisterShortcut を呼んでおくと、プラグインが外れたときに登録が残りません。

modifier はキー名ではなく役割名で指定する。 @wordpress/keycodes で定義されている primary(Windows は Ctrl、Mac は Command)、primaryShift、primaryAlt、secondary、access(Windows は Shift+Alt、Mac は Control+Option)などを使います。役割名にしておくと OS ごとの違いをエディター側が吸収してくれます。ctrl や alt のように物理キーを直接指す値もありますが、Mac と Windows で押し心地が変わるので、特別な理由がなければ役割名を選びます。

処理の中で preventDefault を呼ぶ。 ブラウザーや他の要素が同じキーに反応するのを防ぎます。ただし、ブロック未選択時のように処理しない場面では呼ばずに返すほうが、ほかの機能を邪魔しません。

useSelect にストアだけを渡す書き方。 コールバックを渡さずストアを渡すと、購読を伴わないセレクターが返ります。ショートカットが押された瞬間の選択状態を読みたいので、この形がイベント処理向きです。

動作確認とヘルプ画面への表示

ビルド後、投稿の編集画面を開いて段落ブロックを選択し、Shift+Alt+K(Mac は Control+Option+K)を押します。選択中のブロックの直後に区切りブロックが入れば成功です。グループやカラムの中のブロックを選んでも、同じ親の中に挿入されることを確かめてください。

登録したショートカットは、エディターのキーボードショートカット一覧(オプションメニューから開ける一覧で、Windows では Shift+Alt+H で開くことが多い)に、category で指定した区分の中に説明文つきで表示されます。メニューの位置や表記はバージョンによって変わるため、見当たらない場合はオプションメニュー(縦三点のアイコン)の中を探してください(2026年10月現在)。

ブラウザーの開発者ツールのコンソールで、登録内容を直接確かめることもできます。

wp.data.select( 'core/keyboard-shortcuts' ).getShortcutKeyCombination( 'my-editor-shortcuts/insert-separator' );
// { modifier: 'access', character: 'k' } のような値が返れば登録済み

つまずきやすいポイント

既存のショートカットとぶつかる。 コアはすでに多くの組み合わせを使っています。たとえば Ctrl+Alt+T と Ctrl+Alt+Y はブロックの前後への挿入、Shift+Alt+Z はブロックの削除に割り当てられています。登録前にヘルプ画面で空いている組み合わせを確認し、ブラウザーや OS、日本語入力のショートカットとも重ならないか実機で試してください。Ctrl+Alt の組み合わせは、一部のキーボード配列では AltGr として扱われ、文字入力と衝突することがある点にも注意が必要です。

押しても反応しない。 まずコンソールにエラーが出ていないか、build/index.js が読み込まれているかを確認します。依存スクリプトを手書きしていて wp-keyboard-shortcuts が抜けていると、useShortcut が見つからずに止まります。index.asset.php を使う構成なら、この種の漏れはほぼ起きません。

サイトエディターでの挙動。 enqueue_block_editor_assets はサイトエディターでも実行されるため、同じショートカットがそちらでも有効になります。投稿編集画面だけに限りたい場合は、PHP 側で get_current_screen() の値を見て読み込みを分けるなどの対応を検討してください。

キャンバス内で反応しないときの切り分け。 自前の keydown リスナーで実装していると、iframe 化された編集キャンバス内では拾えないことがあります。この記事の方法のようにストア経由で登録すれば、エディター側の仕組みに乗るため、キャンバス内外で同じように動きます。

まとめ

  • ブロックエディターの独自ショートカットは、registerShortcut で登録し、useShortcut で処理を割り当てる
  • 両方とも registerPlugin で差し込んだコンポーネントの中で使い、登録は useEffect で一度だけ行う
  • キーは primary や access などの役割名で指定し、OS 差をエディターに任せる
  • コアやブラウザーの既存ショートカットとの衝突を事前に確認し、ステージング環境で試してから本番に入れる
  • 依存スクリプトは @wordpress/scripts が生成する index.asset.php から読み込むと漏れを防げる

お気軽にご相談ください

お見積りへ お問い合わせへ
▲