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で指定します。