2026年6月17日

2026年6月17日

MediaUploadの使い方|Gutenbergのカスタムブロックでメディアライブラリから画像を選ぶ

MediaUpload は、ブロックエディターでWordPressのメディアライブラリ(画像などを選ぶ画面)を開くためのReactコンポーネントです。自作のブロックに「画像を選択」ボタンを付け、選んだ画像のIDやURLをブロックの属性に保存するときに使います。

この記事では、@wordpress/create-block で作った雛形のブロックに、画像の選択・変更・削除を付ける例で使い方を説明します。手順とコードは2026年10月時点の公式ドキュメントと雛形に合わせています。カスタムブロックの作り方そのものは、Gutenbergのカスタムブロックを作る方法で説明しています。

MediaUploadとMediaUploadCheck

どちらも @wordpress/block-editor パッケージから読み込みます。

import { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';
コンポーネント 役割
MediaUpload メディアライブラリを開く仕組みを提供する。ボタンなどの見た目は render で自分で書く
MediaUploadCheck ログイン中のユーザーにファイルをアップロードする権限(upload_files)があるときだけ中身を表示する

古い記事では @wordpress/editor から読み込む例がありますが、現在は @wordpress/block-editor から読み込みます。

MediaUpload 自体は、何も表示しない「差し替え用」の部品です。投稿・固定ページの編集画面やサイトエディターでは、WordPressが editor.MediaUpload フィルターで、メディアライブラリ(wp.media)を使う実装に差し替えています。そのため、通常のブロック開発では何も設定せずに使えます。

主なプロパティ

プロパティ 必須 内容
onSelect 必須 メディアが選ばれて画面が閉じたときに呼ばれる関数。選ばれたメディアの情報を受け取る
render 必須 画面を開くボタンなどを返す関数。引数の open を呼ぶとメディアライブラリが開く
allowedTypes 選べる種類。'image'・'video'・'audio' のような種類か、'application/pdf' のようなMIMEタイプの配列。省略するとすべて
value 開いたときに選択済みにしておくメディアのID(multiple のときはIDの配列)
multiple true で複数選択。'add' にすると、ShiftキーやCtrlキーなしで複数選べる
gallery ギャラリー編集用の画面で開く
title メディアライブラリの画面の見出し
onClose 選んだかどうかにかかわらず、画面が閉じたときに呼ばれる

手順1: 雛形を作る

ローカルのWordPressの wp-content/plugins で、ブロックの雛形を作ります。Node.jsとnpmが必要です。

cd wp-content/plugins
npx @wordpress/create-block@latest image-picker --namespace=myplugin
cd image-picker

src/image-picker/ に block.json・edit.js・save.js などが作られます。以降はこの3つのファイルを書き換えます。雛形にある view.js(公開ページで動くJavaScript)はこの例では使わないので、削除して構いません。

手順2: block.jsonに属性を追加する

選んだ画像のID・URL・代替テキストを保存する属性(attributes)を追加します。src/image-picker/block.json を次の内容にします。

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "myplugin/image-picker",
	"version": "0.1.0",
	"title": "Image Picker",
	"category": "media",
	"icon": "format-image",
	"description": "メディアライブラリから画像を1枚選んで表示するブロック",
	"attributes": {
		"mediaId": {
			"type": "number"
		},
		"mediaUrl": {
			"type": "string",
			"default": ""
		},
		"mediaAlt": {
			"type": "string",
			"default": ""
		}
	},
	"supports": {
		"html": false,
		"align": [ "wide", "full" ]
	},
	"textdomain": "image-picker",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css"
}

view.js を削除した場合は、雛形にあった "viewScript": "file:./view.js" の行も消します。

手順3: edit.jsでMediaUploadを使う

src/image-picker/edit.js を次の内容にします。

import { __ } from '@wordpress/i18n';
import {
	useBlockProps,
	MediaUpload,
	MediaUploadCheck,
} from '@wordpress/block-editor';
import { Button } from '@wordpress/components';
import './editor.scss';

const ALLOWED_MEDIA_TYPES = [ 'image' ];

export default function Edit( { attributes, setAttributes } ) {
	const { mediaId, mediaUrl, mediaAlt } = attributes;

	// メディアライブラリで画像が選ばれたときに呼ばれる
	const onSelectImage = ( media ) => {
		// 「大」サイズがあれば使い、なければ元の画像を使う
		const url = media.sizes?.large?.url ?? media.url;
		setAttributes( {
			mediaId: media.id,
			mediaUrl: url,
			mediaAlt: media.alt,
		} );
	};

	const onRemoveImage = () => {
		setAttributes( { mediaId: undefined, mediaUrl: '', mediaAlt: '' } );
	};

	return (
		<div { ...useBlockProps() }>
			{ mediaUrl && <img src={ mediaUrl } alt={ mediaAlt } /> }

			<MediaUploadCheck
				fallback={
					<p>{ __( '画像を選ぶ権限がありません。', 'image-picker' ) }</p>
				}
			>
				<MediaUpload
					onSelect={ onSelectImage }
					allowedTypes={ ALLOWED_MEDIA_TYPES }
					value={ mediaId }
					title={ __( '画像を選択', 'image-picker' ) }
					render={ ( { open } ) => (
						<Button variant="secondary" onClick={ open }>
							{ mediaUrl
								? __( '画像を変更', 'image-picker' )
								: __( '画像を選択', 'image-picker' ) }
						</Button>
					) }
				/>
				{ mediaUrl && (
					<Button variant="link" isDestructive onClick={ onRemoveImage }>
						{ __( '画像を外す', 'image-picker' ) }
					</Button>
				) }
			</MediaUploadCheck>
		</div>
	);
}

要点は次のとおりです。

  • render に渡した関数の引数 open をボタンの onClick に渡すと、ボタンを押したときにメディアライブラリが開きます。メディアライブラリの画面からは、新しいファイルのアップロードもできます。
  • onSelect が受け取る media には、id・url・alt・sizes などが入っています。sizes には画像サイズごとのURLがあり、full(元の画像)は常にあります。large などは、元の画像がそのサイズより大きいときだけ作られるので、例のように無い場合に備えます。
  • value に保存済みのIDを渡すと、メディアライブラリを開いたときにその画像が選択された状態になります。
  • MediaUploadCheck の fallback は、アップロード権限が無いユーザー(標準の権限グループでは「寄稿者」)に代わりに表示する内容です。

手順4: save.jsで画像を出力する

src/image-picker/save.js を次の内容にします。

import { useBlockProps } from '@wordpress/block-editor';

export default function save( { attributes } ) {
	const { mediaId, mediaUrl, mediaAlt } = attributes;

	if ( ! mediaUrl ) {
		return null;
	}

	return (
		<figure { ...useBlockProps.save() }>
			<img
				src={ mediaUrl }
				alt={ mediaAlt }
				className={ mediaId ? `wp-image-${ mediaId }` : undefined }
			/>
		</figure>
	);
}

<img> に wp-image-画像ID のクラスを付けておくと、WordPressが公開ページの表示時に、その画像の srcset・sizes 属性(画面幅に合わせた画像の候補)を付け加えます。

手順5: ビルドして確かめる

npm run build
wp plugin activate image-picker

WP-CLIを使わない場合は、管理画面の「プラグイン」で有効化します。投稿の編集画面で「Image Picker」ブロックを追加し、「画像を選択」からメディアライブラリが開くこと、選んだ画像が表示され、保存後の公開ページにも出ることを確かめます。開発中は npm start にすると、保存するたびにビルドされます。

複数の画像を選ぶ場合

multiple を付けると、onSelect には選ばれたメディアの配列が渡されます。保存する属性も配列にします。

"attributes": {
	"images": {
		"type": "array",
		"default": []
	}
}
<MediaUpload
	multiple
	allowedTypes={ [ 'image' ] }
	value={ images.map( ( image ) => image.id ) }
	onSelect={ ( media ) =>
		setAttributes( {
			images: media.map( ( item ) => ( {
				id: item.id,
				url: item.url,
				alt: item.alt,
			} ) ),
		} )
	}
	render={ ( { open } ) => (
		<Button variant="secondary" onClick={ open }>
			{ __( '画像を選択', 'image-picker' ) }
		</Button>
	) }
/>

画像以外を選ばせたい場合は allowedTypes を変えます。PDFだけなら [ 'application/pdf' ]、動画なら [ 'video' ] です。

知っておきたい注意点

  • 保存されるのは選んだ時点の値: この例では、URLと代替テキストをブロックの属性にコピーして保存します。あとでメディアライブラリ側で代替テキストを直しても、ブロックの表示は変わりません。もう一度画像を選び直すと反映されます。
  • アップロードできるファイル: メディアライブラリからアップロードできる種類と大きさは、WordPressとサーバーの設定で決まります。allowedTypes は選べる種類を絞るだけで、許可されていない種類のアップロードを可能にするものではありません。
  • 独自の管理画面で使う場合: 自作の管理画面に独自のブロックエディターを組み込む場合は、投稿の編集画面のような準備がされていないため、メディアライブラリのスクリプトの読み込み(wp_enqueue_media())と editor.MediaUpload フィルターの設定が必要です。通常のブロック開発では不要です。
  • 画像選択の部品はほかにもある: 画像が無いときの「アップロード/メディアライブラリ」の枠をまとめて出す MediaPlaceholder、ツールバーに「置換」メニューを出す MediaReplaceFlow も @wordpress/block-editor にあります。WordPress標準の画像ブロックのような見た目にしたい場合は、こちらも検討します。

うまく動かないとき

症状 確かめること
ボタンが表示されない ログイン中のユーザーにアップロード権限があるか(MediaUploadCheck が隠している)。render が要素を返しているか
ボタンを押してもメディアライブラリが開かない render の open をボタンの onClick に渡しているか。独自の管理画面で使っていないか
選んだ画像が保存されない block.json の attributes に、setAttributes で使った名前の属性があるか。npm run build をやり直したか
保存済みのブロックが、無効なコンテンツを含むというエラー表示になる 保存したあとで save.js の出力を変えると、保存済みのHTMLと合わなくなる(ブロックの検証)。開発中は、そのブロックを削除して追加し直す

まとめ

  • MediaUpload と MediaUploadCheck は @wordpress/block-editor から読み込みます。
  • ボタンの見た目は render で書き、引数の open でメディアライブラリを開きます。選んだ結果は onSelect で受け取り、setAttributes で属性に保存します。
  • 画像サイズのURLは media.sizes から取り、full 以外は無い場合に備えます。
  • 複数選択は multiple、選べる種類は allowedTypes で指定します。

お気軽にご相談ください

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