Skip to main content

wp media import

Overview

Add files directly to the WordPress media library from the server filesystem or remote URLs — without going through the browser upload form. Essential for bulk imports, migrations, and programmatic media management.

What It Does

wp media import calls WordPress's attachment creation functions (wp_handle_sideload, wp_insert_attachment, wp_generate_attachment_metadata) to register a file as a media attachment — copying it to wp-content/uploads/ and creating all derivative image sizes in one step.

Syntax

wp media import <file-or-url>... [OPTIONS]

Options

FlagDescription
FILE_OR_URL...File path(s) or URL(s) to import
--post_id=IDAttach imported file to a specific post
--title=TITLEOverride the attachment title
--caption=CAPTIONSet caption text
--alt=ALTSet alt text
--desc=DESCSet description
--featured_imageSet first imported file as the post's featured image
--skip-copyRegister the file in-place (don't copy to uploads folder)
--preserve-filetimeKeep original file modification timestamp
--porcelainOutput only the new attachment ID

Basic Usage

Import a local file

wp media import /var/www/images/banner.jpg

Output:

Imported file '/var/www/images/banner.jpg' as attachment ID 234.
Success: Imported 1 of 1 items.

Import from a remote URL

wp media import https://example.com/assets/logo.png

Output:

Imported file 'logo.png' as attachment ID 235.
Success: Imported 1 of 1 items.

Import with alt text and title

wp media import /var/www/images/hero.jpg \
--title="Homepage Hero" \
--alt="A beautiful mountain landscape"

Output:

Imported file '/var/www/images/hero.jpg' as attachment ID 236.
Success: Imported 1 of 1 items.

Attach to a post and set as featured image

wp media import /var/www/images/post-cover.jpg \
--post_id=42 \
--featured_image

Output:

Imported file '/var/www/images/post-cover.jpg' as attachment ID 237.
Set as the featured image for post 42.
Success: Imported 1 of 1 items.

Get only the new attachment ID (for scripting)

ATTACHMENT_ID=$(wp media import /var/www/images/product.jpg --porcelain)
echo "New attachment ID: $ATTACHMENT_ID"

Output:

New attachment ID: 238

Real-World Scenarios

Scenario 1: Bulk import all images from a directory

for file in /var/www/migration-images/*.jpg; do
wp media import "$file"
done

Scenario 2: Import from a URL list file

#!/bin/bash
# urls.txt contains one image URL per line
while IFS= read -r url; do
wp media import "$url"
done < urls.txt
#!/bin/bash
# Read post IDs and their corresponding image files
while IFS=',' read -r post_id image_path; do
wp media import "$image_path" --post_id="$post_id" --featured_image
echo "Set featured image for post $post_id"
done < post-images.csv

post-images.csv:

42,/var/www/images/post-42.jpg
43,/var/www/images/post-43.jpg
44,/var/www/images/post-44.jpg

Scenario 4: Site migration — import images from old server

# On old server: generate a list of image URLs
wp post list --post_type=attachment --format=csv --fields=ID,guid > attachments.csv

# On new server: import each
while IFS=',' read -r id url; do
[ "$id" = "ID" ] && continue # skip header
wp media import "$url"
done < attachments.csv

Scenario 5: Import WooCommerce product images

#!/bin/bash
# Import product images and set as featured images
for product_id in $(wp post list --post_type=product --format=ids); do
IMAGE_PATH="/var/www/product-images/${product_id}.jpg"
if [ -f "$IMAGE_PATH" ]; then
wp media import "$IMAGE_PATH" --post_id="$product_id" --featured_image
fi
done

Best Practices

  1. Use --porcelain when you need the attachment ID for further processing in scripts.
  2. Use --skip-copy only when you want to serve files from a non-standard location (e.g., an S3-mounted filesystem).
  3. Set --alt during import — don't leave it for later; accessibility metadata is easier to set during the import.
  4. Import in batches for very large sets to avoid PHP memory issues.

Troubleshooting

ProblemCauseFix
Error: File doesn't existWrong pathVerify with ls /path/to/file
Error: Could not download remote fileURL blocked or unreachabletest with curl -I URL
Warning: Attachment already existsFile already importedCheck with wp media list
Image sizes not generatedPHP memory too lowIncrease memory_limit

Quick Reference

wp media import /path/to/file.jpg                 # Local file
wp media import https://example.com/img.png # Remote URL
wp media import file.jpg --post_id=42 --featured_image
wp media import file.jpg --porcelain # Return ID only

Next Steps