File Upload Setup Guide
Enable users to upload images, documents, and files to your AI agents for processing.
File Upload Overview
What Can Users Upload?
Supported File Types:
- 📷 Images: .jpg, .jpeg, .png, .gif
- 📄 Documents: .pdf, .doc, .docx
- 📊 Spreadsheets: .xls, .xlsx
File Limits:
- Per File: 25MB maximum
- Total Upload: 100MB maximum per submission
- Multiple Files: Yes, upload several files at once
How It Works
1. User drags/selects files
↓
2. Preview shows thumbnails
↓
3. JavaScript validates (size, type)
↓
4. On submit: Files converted to base64
↓
5. Sent to webhook with metadata
↓
6. Webhook processes files
↓
7. Response sent back to user
Adding File Upload to Forms
Step 1: Create File Upload Field
- Edit your AI Agent
- Scroll to Form Builder
- Click "Add Field"
- Configure:
Label: "Upload Your Image"
Field Type: File
Accept: image/png,image/jpeg,image/jpg,image/gif
Required: No (or Yes if mandatory)
Help Text: "Upload an image for AI processing (Max 25MB)"
Step 2: Configure Accepted Types
Images Only:
Accept: image/*
Documents Only:
Accept: .pdf,.doc,.docx
Spreadsheets:
Accept: .xls,.xlsx
Multiple Types:
Accept: image/*,.pdf,.doc,.docx
Everything Allowed:
Accept: (leave empty)
Step 3: Save & Test
- Click "Save Form"
- View agent on frontend
- Test drag & drop
- Test file selection
File Upload Features
Drag & Drop Interface
Users can:
- 🖱️ Click to browse - Traditional file picker
- 🎯 Drag files - Drag files onto upload area
- 👁️ Preview - See thumbnails before uploading
- ❌ Remove files - Click X to remove unwanted files
- 📂 Multiple files - Upload several at once
Visual Feedback
Upload Area States:
1. Empty (Ready):
┌─────────────────────────────┐
│ 📁 │
│ Click or drag files here │
│ Max 25MB per file, 100MB │
│ total │
└─────────────────────────────┘
2. Drag Over (Active):
┌═════════════════════════════┐
║ 📁 ⬇️ ║
║ Drop your files here! ║
║ ║
║ ║
└═════════════════════════════┘
3. Files Selected (Preview):
┌─────────────────────────────┐
│ ┌───┐ photo1.jpg ❌ │
│ │img│ 1.2 MB │
│ └───┘ │
│ │
│ ┌───┐ photo2.jpg ❌ │
│ │img│ 850 KB │
│ └───┘ │
│ │
│ [+] Add more files │
└─────────────────────────────┘
Image Previews
- For images: Shows actual thumbnail
- For PDFs: Shows 📄 icon + filename
- For Word docs: Shows 📝 icon + filename
- For Excel: Shows 📊 icon + filename
File Information Display
Each file shows:
- ✅ Filename
- ✅ File size (formatted: KB, MB)
- ✅ Visual preview (for images)
- ✅ Remove button (X)
Processing Uploaded Files
File Data Structure
When a file is uploaded, WordPress sends this data to your webhook:
{
"form_data": {
"field_image_file_data": "iVBORw0KGgoAAAANSUhEUgAA...",
"field_image_file_name": "photo.jpg",
"field_image_file_type": "image/jpeg",
"field_image_file_size": 245678
}
}
Data Fields:
*_file_data- Base64 encoded file content*_file_name- Original filename*_file_type- MIME type*_file_size- Size in bytes
n8n: Decode and Use Files
Method 1: Convert to Binary (Images/PDFs)
// In n8n Code node
const fileData = $json.body.form_data.field_image_file_data;
const fileName = $json.body.form_data.field_image_file_name;
const fileType = $json.body.form_data.field_image_file_type;
// Decode base64 to buffer
const buffer = Buffer.from(fileData, 'base64');
return {
binary: {
data: buffer,
fileName: fileName,
mimeType: fileType
}
};
Method 2: Save to Temporary File
const fs = require('fs');
const path = require('path');
const fileData = $json.body.form_data.field_image_file_data;
const fileName = $json.body.form_data.field_image_file_name;
// Decode and save
const buffer = Buffer.from(fileData, 'base64');
const tempPath = path.join('/tmp', fileName);
fs.writeFileSync(tempPath, buffer);
return {
filePath: tempPath,
fileName: fileName,
saved: true
};
Method 3: Upload to Cloud Storage
Upload to AWS S3:
const AWS = require('aws-sdk');
const s3 = new AWS.S3({
accessKeyId: 'YOUR_ACCESS_KEY',
secretAccessKey: 'YOUR_SECRET_KEY'
});
const fileData = $json.body.form_data.field_image_file_data;
const fileName = $json.body.form_data.field_image_file_name;
const buffer = Buffer.from(fileData, 'base64');
const params = {
Bucket: 'your-bucket-name',
Key: `uploads/${Date.now()}-${fileName}`,
Body: buffer,
ContentType: $json.body.form_data.field_image_file_type
};
const result = await s3.upload(params).promise();
return {
url: result.Location,
bucket: result.Bucket,
key: result.Key
};
Use Cases & Examples
Use Case 1: AI Image Enhancement
Scenario: User uploads photo, AI enhances it
Form Fields:
- File upload (image)
- Enhancement type (select: Upscale, Denoise, Colorize)
- Email for results
n8n Workflow:
[Webhook]
↓
[Code: Decode image]
↓
[HTTP Request: Upload to Replicate]
↓
[Replicate: Enhance image]
↓
[Code: Get result URL]
↓
[Respond with enhanced image]
Response:
return {
output_html: `
<div class="enhancement-result">
<h3>✨ Enhanced Image Ready!</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
<div>
<h4>Original</h4>
<img src="${originalUrl}" style="max-width: 100%">
</div>
<div>
<h4>Enhanced</h4>
<img src="${enhancedUrl}" style="max-width: 100%">
</div>
</div>
<a href="${enhancedUrl}" download class="download-btn">Download Enhanced</a>
</div>
`
};
Use Case 2: Document Analysis (PDF)
Scenario: User uploads PDF, AI summarizes it
Form Fields:
- File upload (PDF)
- What to extract (select: Summary, Key Points, Action Items)
n8n Workflow:
[Webhook]
↓
[Code: Decode PDF]
↓
[HTTP Request: OCR/Text extraction]
↓
[OpenAI: Analyze text]
↓
[Format results]
↓
[Email results + Webhook response]
PDF Processing:
// Save PDF temporarily
const fs = require('fs');
const pdfData = $json.body.form_data.field_document_file_data;
const buffer = Buffer.from(pdfData, 'base64');
fs.writeFileSync('/tmp/document.pdf', buffer);
// Extract text (using pdf-parse library)
const pdf = require('pdf-parse');
const dataBuffer = fs.readFileSync('/tmp/document.pdf');
const pdfText = await pdf(dataBuffer);
return {
text: pdfText.text,
pages: pdfText.numpages
};
Use Case 3: Image-to-Text (OCR)
Scenario: User uploads image with text, AI extracts it
Form Fields:
- File upload (image)
- Language (select: English, Spanish, French, etc.)
Using Google Vision:
const vision = require('@google-cloud/vision');
const client = new vision.ImageAnnotatorClient();
const imageBuffer = Buffer.from(
$json.body.form_data.field_image_file_data,
'base64'
);
const [result] = await client.textDetection({
image: { content: imageBuffer }
});
const text = result.fullTextAnnotation.text;
return {
output_html: `
<div class="ocr-result">
<h3>📝 Extracted Text</h3>
<textarea rows="10" style="width:100%">${text}</textarea>
<button onclick="navigator.clipboard.writeText('${text.replace(/'/g, "\\'")}')">
Copy to Clipboard
</button>
</div>
`
};
Use Case 4: Background Removal
Scenario: User uploads photo, AI removes background
Form Fields:
- File upload (image)
- Output format (PNG with transparency / White background)
Using remove.bg API:
const FormData = require('form-data');
const axios = require('axios');
const imageBuffer = Buffer.from(
$json.body.form_data.field_photo_file_data,
'base64'
);
const formData = new FormData();
formData.append('image_file_b64', $json.body.form_data.field_photo_file_data);
formData.append('size', 'auto');
const response = await axios.post('https://api.remove.bg/v1.0/removebg', formData, {
headers: {
'X-Api-Key': 'YOUR_API_KEY',
...formData.getHeaders()
},
responseType: 'arraybuffer'
});
const resultBase64 = Buffer.from(response.data).toString('base64');
return {
output_html: `
<div class="bg-removal-result">
<h3>🎨 Background Removed!</h3>
<img src="data:image/png;base64,${resultBase64}" style="max-width: 100%">
<a href="data:image/png;base64,${resultBase64}" download="no-background.png">
Download Image
</a>
</div>
`
};
Use Case 5: Multiple File Processing
Scenario: User uploads multiple images for batch processing
Handling Multiple Files:
When multiple files are uploaded, they're sent as separate fields:
{
"field_images_0_file_data": "base64...",
"field_images_0_file_name": "photo1.jpg",
"field_images_1_file_data": "base64...",
"field_images_1_file_name": "photo2.jpg",
"field_images_2_file_data": "base64...",
"field_images_2_file_name": "photo3.jpg"
}
Process all files:
const formData = $json.body.form_data;
const files = [];
// Extract all uploaded files
Object.keys(formData).forEach(key => {
if (key.includes('_file_data')) {
const index = key.match(/_(\d+)_/)[1];
const fileData = formData[`field_images_${index}_file_data`];
const fileName = formData[`field_images_${index}_file_name`];
files.push({
data: fileData,
name: fileName
});
}
});
// Process each file
const results = await Promise.all(
files.map(file => processImage(file.data, file.name))
);
return { files: files.length, results };
Configuration & Limits
WordPress Limits
Default Settings:
- Maximum file size: 25MB per file
- Maximum total: 100MB per submission
- Allowed types: See supported file types above
Server Requirements
PHP Settings (check php.ini):
upload_max_filesize = 25M
post_max_size = 100M
max_execution_time = 300
memory_limit = 256M
Check current limits:
<?php
echo 'upload_max_filesize: ' . ini_get('upload_max_filesize') . '<br>';
echo 'post_max_size: ' . ini_get('post_max_size') . '<br>';
echo 'max_execution_time: ' . ini_get('max_execution_time') . '<br>';
echo 'memory_limit: ' . ini_get('memory_limit');
?>
Performance Considerations
Large files impact:
- ⏱️ Longer upload time
- 💾 More memory usage
- 🕐 Increased processing time
- 🔄 Higher timeout risk
Optimize:
- Compress images before upload (client-side)
- Use async processing for large files
- Stream uploads instead of loading entirely
- Set realistic limits based on your use case
Troubleshooting
File Upload Not Working
Symptoms:
- Upload button does nothing
- Drag & drop doesn't work
- No file preview
Solutions:
1. Check JavaScript Console:
F12 → Console tab → Look for errors
2. Verify file type:
// Accepted types must match
Accept: image/png,image/jpeg
3. Check file size:
File must be < 25MB
Total must be < 100MB
4. Browser compatibility:
- Chrome: ✅ Full support
- Firefox: ✅ Full support
- Safari: ✅ Full support (iOS 11+)
- Edge: ✅ Full support
File Too Large Error
Error Message:
"File 'photo.jpg' is too large. Maximum size is 25MB."
Solutions:
1. Compress the image:
- Use TinyPNG.com
- Use image editing software
- Reduce dimensions
2. Increase PHP limits:
; In php.ini
upload_max_filesize = 50M
post_max_size = 100M
3. Use multiple smaller files:
- Split large files
- Upload in batches
File Not Received by Webhook
Check webhook payload:
1. In n8n execution:
Click failed execution → View input data
2. Look for file fields:
{
"field_image_file_data": "Should be here",
"field_image_file_name": "photo.jpg"
}
3. Common issues:
- Field name mismatch
- Form not submitting correctly
- JavaScript error preventing submission
Base64 Decoding Errors
Error: Invalid base64 string
Solution:
// Ensure proper decoding
try {
const buffer = Buffer.from(fileData, 'base64');
return { success: true, buffer };
} catch (error) {
return {
error: true,
message: 'Invalid file data: ' + error.message
};
}
Preview Not Showing
For images:
// FileReader API creates preview
const reader = new FileReader();
reader.onload = (e) => {
preview.src = e.target.result; // Should show image
};
reader.readAsDataURL(file);
If still not working:
- Check image format (must be valid)
- Check file corruption
- Try different browser
- Check console for errors
Best Practices
User Experience
✅ DO:
- Show clear file requirements
- Display upload progress
- Provide instant validation feedback
- Show file previews
- Allow removing files before submit
- Give clear error messages
❌ DON'T:
- Hide file size limits
- Allow unlimited uploads
- Skip validation
- Ignore user feedback
Security
✅ DO:
- Validate file types server-side
- Check file sizes
- Scan for malware (if possible)
- Sanitize filenames
- Use secure temporary storage
❌ DON'T:
- Trust client-side validation only
- Execute uploaded files
- Store files permanently without scanning
- Allow dangerous file types (.exe, .php, etc.)
Performance
✅ Optimize:
- Compress images before processing
- Use CDN for storing results
- Implement file size limits
- Clean up temporary files
- Use async processing for large files
File Storage
Options:
1. Temporary Processing:
- Decode → Process → Delete
- No permanent storage needed
- Best for: AI processing, transformations
2. Cloud Storage:
- Upload to S3, Google Cloud, etc.
- Generate public URLs
- Best for: Results, user galleries
3. WordPress Media Library:
- Upload as attachment
- Managed by WordPress
- Best for: Permanent storage, galleries