Great question! Have you ever found an answer to this? Or has anyone ever?
Sadly the documentation is still as crappy as it was four years ago and googling for this topic still brings up your question as the only relevant result.
Interestingly, your idea of
uploader: {
type: 'application/pdf'
}
seems to be recognized by the API since you can see that the wp.media
instance outputs it as a prop when logged to the console. However, it has absolutely zero effect and the user can still select whatever file he wants in the uploader.
It might not be the cleanest solution, but, for anyone that stumbles across this age-old topic, here's how I know handle invalid file types: Within my_custom_uploader.on('select', () => { ... })
I check if the selected media file is of the same file type thats set under
library: {
type: 'myfiletype'
}
and render an error message if thats not the case and prevent the file id from being set as the value of the corresponding input.
The final code implementation could look somewhat like this:
// Handle media selection in media uploader
my_custom_uploader.on( 'select', () => {
// Get selected mediafile
const sel_media = my_custom_uploader.state().get( 'selection' ).first().toJSON();
// Check if selected mediafile is of wrong file type
if( sel_media.mime !== 'application/pdf' ) {
// Set error message
const err_msg = 'Filetype ' + sel_media.mime + ' is not supported for menu item icons. Please select an SVG file.';
// Create inline error element, set HTML classes and append error messsage
const err_el = document.createElement('p');
err_el.classList.add( 'my-inline-error', 'wrong-filetype' );
err_el.innerHTML = err_msg;
// Get upload button
const upload_btn = document.getElementById( 'my_custom_upload_btn' );
// Check if error message does not exist yet
if( document.querySelector( '.my-inline-error.wrong-filetype' ) ) {
// Insert error element after upload button
upload_btn.after( err_el );
}
// Return to prevent further script execution
return;
}
// Get mediafile ID input
const mediafile_id_input = document.getElementById( 'my-mediafile-id-input' );
// Set value of mediafile ID input to ID of selected mediafile
mediafile_id_input = sel_media.id;
} );
As far as I can tell from my research, WordPress core handles things similarly in it's implementations of the media API. I still don't think it's pretty though.