Offload Media Documentation
Complete guide to installing, configuring, and using Offload Media for WordPress.
Table of Contents
Installation
Requirements
- WordPress 6.0 or higher
- PHP 8.0 or higher
- Hetzner Object Storage bucket with access credentials
- Active internet connection for offloading files
Install via WordPress Admin
- Download the plugin ZIP file from your dashboard or the pricing page
- Go to Plugins → Add New → Upload Plugin in WordPress
- Upload the ZIP file and click Install Now
- Click Activate Plugin after installation completes
- Navigate to Media → Hetzner Offload to configure
Install via FTP
- Extract the plugin ZIP file to your computer
- Upload the
hetzner-media-offloadfolder to/wp-content/plugins/on your server - Go to Plugins in WordPress admin and activate Hetzner Media Offload
- Navigate to Media → Hetzner Offload to configure
Getting Started
Step 1: Get Your Hetzner Credentials
Before configuring the plugin, you'll need to create a Hetzner Object Storage bucket and generate access credentials.
- Log into your Hetzner Cloud Console
- Navigate to Storage → Object Storage
- Click Create Bucket and choose a unique name (e.g.,
my-wordpress-media) - Select your preferred region (choose the one closest to your server for best performance)
- Go to Access Keys and click Generate Access Key
- Save your Access Key and Secret Key securely (you won't be able to see the secret key again)
Important: Keep your Secret Key secure. If you lose it, you'll need to generate a new access key pair.
Step 2: Configure the Plugin
- In WordPress, go to Media → Hetzner Offload
- Enter your Access Key in the first field
- Enter your Secret Key in the second field
- Enter your Bucket Name (the name you chose when creating the bucket)
- Select your Region from the dropdown (must match the region where you created the bucket)
- Click Test Connection to verify your credentials work
- If the test succeeds, toggle Enable Offload to start offloading new uploads
Step 3: Optional Settings
- CDN Domain: If you're using a CDN (like Cloudflare), enter your CDN domain here. All offloaded media URLs will use your CDN instead of the direct Hetzner URL.
- Object Prefix: Customize the folder structure in your bucket. By default, files are stored with their WordPress upload path structure.
Configuration
Settings Overview
Connection Settings
- Access Key
- Your Hetzner Object Storage access key (public identifier)
- Secret Key
- Your Hetzner Object Storage secret key (private, like a password)
- Bucket Name
- The name of your Hetzner Object Storage bucket
- Region
- The Hetzner region where your bucket is located (e.g., nbg1, fsn1, hel1)
Advanced Settings
- CDN Domain
- Optional. If you use a CDN, enter your CDN domain (e.g.,
cdn.example.com). Leave empty to use direct Hetzner URLs. - Enable Offload
- Toggle to enable/disable automatic offloading of new media uploads. When disabled, files are saved locally only.
Pro Settings
Pro users have access to additional configuration options:
- Selective Offload: Choose which file types to offload (images only, exclude PDFs, etc.)
- Delete Local Files: Automatically remove files from your server after successful offload
- Signed URLs: Generate time-limited signed URLs for private content
- Migration Settings: Configure bulk migration of existing media
Lite vs Pro Features
Lite (Free)
- Automatic offloading for new media uploads
- URL rewriting for offloaded files
- CDN domain support
- Connection testing
- Media library status column
Pro
Premium- Everything in Lite
- Bulk migrate existing media library
- Selective offload by file type
- Signed URLs for private content
- URL replacement in post content
- Migration progress tracking
- Action logs and audit trail
- Priority support
Troubleshooting
Connection Issues
"Connection test failed"
- Verify your Access Key and Secret Key are correct (no extra spaces)
- Ensure your bucket name matches exactly (case-sensitive)
- Check that the region matches your bucket's region
- Verify your Hetzner account has Object Storage enabled
- Check your server's firewall allows outbound HTTPS connections
"Files not uploading to Hetzner"
- Ensure "Enable Offload" is toggled on in settings
- Check that your bucket has sufficient storage space
- Verify file permissions on your WordPress uploads directory
- Check WordPress debug logs for error messages
- Ensure your PHP installation has cURL enabled
URL Issues
"Images showing broken links"
- Clear your WordPress cache (if using a caching plugin)
- Clear your browser cache
- Verify the files actually exist in your Hetzner bucket
- Check that your CDN domain (if used) is correctly configured
- Ensure your bucket has public read access enabled
Performance Issues
"Uploads are slow"
- This is normal - files are being uploaded to both your server and Hetzner
- Large files may take longer to offload
- Check your server's upload speed and Hetzner connection
- Consider using Pro version's "Delete local files" option to reduce server load
Developer Guide
Hooks & Filters
The plugin provides several WordPress hooks for developers to customize behavior.
Filters
hetzner_offload_object_prefix
Customize the object key prefix in your bucket.
add_filter('hetzner_offload_object_prefix', function($prefix) {
return 'custom-prefix/';
});
hetzner_offload_use_async
Disable async processing to upload files synchronously.
add_filter('hetzner_offload_use_async', '__return_false');
hetzner_offload_skip_file
Skip offloading specific files. Return true to skip.
add_filter('hetzner_offload_skip_file', function($skip, $attachment_id) {
// Skip files larger than 10MB
$file_path = get_attached_file($attachment_id);
if (filesize($file_path) > 10 * 1024 * 1024) {
return true;
}
return $skip;
}, 10, 2);
Actions
hetzner_offload_file_offloaded
Triggered after a file is successfully offloaded.
add_action('hetzner_offload_file_offloaded', function($attachment_id, $offload_data) {
// $offload_data contains:
// - 'url': The Hetzner URL
// - 'key': The object key in the bucket
// - 'bucket': The bucket name
error_log('File offloaded: ' . $offload_data['url']);
}, 10, 2);
hetzner_offload_file_failed
Triggered when offloading fails.
add_action('hetzner_offload_file_failed', function($attachment_id, $error) {
error_log('Offload failed for attachment ' . $attachment_id . ': ' . $error);
}, 10, 2);
File Structure
hetzner-media-offload/
├── hetzner-media-offload.php # Main plugin file
├── uninstall.php # Cleanup on uninstall
├── includes/
│ ├── Plugin.php # Main plugin class
│ ├── Admin/
│ │ └── AdminController.php # Admin UI controller
│ ├── Media/
│ │ ├── MediaHandler.php # Upload handling
│ │ └── UrlRewriter.php # URL rewriting
│ ├── Storage/
│ │ └── HetznerClient.php # S3 API client
│ ├── Background/
│ │ └── BackgroundProcessor.php # Async processing
│ ├── Helpers/
│ │ ├── Settings.php # Settings manager
│ │ ├── Database.php # DB operations
│ │ └── Logger.php # Logging (Pro)
│ └── Licensing/
│ └── LicenseManager.php # License validation
└── pro/
├── pro-loader.php # Pro features loader
└── MigrationHandler.php # Bulk migration
Frequently Asked Questions
Will this break my existing media?
No. The plugin only affects new uploads by default. Your existing media remains on your local server. Pro users can migrate existing media at any time with the bulk migration feature.
What happens if Hetzner is down?
If Hetzner is unavailable during upload, your files are saved locally as normal. The plugin includes fallback protection, so your uploads won't fail. You can retry offloading later when Hetzner is available.
Can I use a CDN?
Yes! Enter your CDN domain in the settings and all offloaded media URLs will use your CDN. This works with any CDN that supports origin pull from Hetzner Object Storage.
Does this work with multisite?
Pro version includes full multisite support. Each site can use the same or different buckets, and migration works across all sites in your network.
How do I migrate back to local storage?
If you decide to stop using the plugin, your original local files can be preserved (if you haven't deleted them). Deactivating the plugin will restore local URLs. Pro users can use the migration tool to download files back from Hetzner.
What file types are supported?
The plugin supports all file types that WordPress allows in the media library, including images, PDFs, videos, audio files, and documents. Pro users can selectively choose which file types to offload.
How much does Hetzner Object Storage cost?
Storage costs €0.02 per GB per month. For a typical site with 20GB of media, that's €0.40 per month. There are no data transfer fees within the same region, and no minimum charges. You only pay for what you use.
Ready to get started?
Download the free Lite version or upgrade to Pro for advanced features.