batch-upload-sanity-plugin-cloudinary
v0.1.2
Published
A Sanity Studio input to batch upload and manage Cloudinary images with titles/captions and drag/drop ordering.
Maintainers
Readme
batch-upload-sanity-plugin-cloudinary
A Sanity Studio input component for batch uploading and managing Cloudinary images with titles/captions and drag-and-drop ordering.
In the pipe
- Use multiple text fields instead of just 2
- Deduplication enhance for cloudinary uploadfunctionality
- Adding more sanity types and not only text
Features
- 🚀 Batch Upload: Upload multiple images at once using Cloudinary's upload widget
- 🎯 Drag & Drop Reordering: Reorder images with intuitive drag-and-drop functionality
- 📝 Titles & Captions: Add titles and captions to each image
- 🗑️ Easy Removal: Remove individual images from the gallery
- ⚙️ Configurable: Customize upload settings via schema options
- 📱 Responsive: Works on desktop and mobile devices
Installation
npm install batch-upload-sanity-plugin-cloudinary
# or
pnpm add batch-upload-sanity-plugin-cloudinary
# or
yarn add batch-upload-sanity-plugin-cloudinaryPrerequisites
This plugin requires the official Sanity Cloudinary plugin to be installed and configured:
npm install sanity-plugin-cloudinarySetup
1. Configure Sanity with Cloudinary
// sanity.config.ts
import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {visionTool} from '@sanity/vision'
import {cloudinaryAssetSourcePlugin, cloudinarySchemaPlugin} from 'sanity-plugin-cloudinary'
export default defineConfig({
name: 'default',
title: 'My Studio',
projectId: 'your-project-id',
dataset: 'production',
plugins: [
structureTool(),
visionTool(),
cloudinaryAssetSourcePlugin(),
cloudinarySchemaPlugin()
],
schema: {
types: schemaTypes,
},
})2. Use the Component in Your Schema
// schemaTypes/album.ts
import {CloudinaryGalleryInput} from 'batch-upload-sanity-plugin-cloudinary'
import {defineField} from 'sanity'
import type {ComponentType} from 'react'
import type {ArrayOfObjectsInputProps} from 'sanity'
export default {
name: 'album',
title: 'Album',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
validation: (rule) => rule.required(),
}),
defineField({
name: 'imagesWithLegend',
title: 'Gallery',
type: 'array',
of: [
{
name: 'imageWithLegend',
type: 'object',
fields: [
defineField({
name: 'image',
title: 'Image',
type: 'cloudinary.asset',
validation: (rule) => rule.required(),
}),
defineField({
name: 'title',
title: 'Title',
type: 'string',
}),
defineField({
name: 'legend',
title: 'Legend',
type: 'string',
}),
],
preview: {
select: {
title: 'legend',
media: 'image',
},
},
},
],
components: {
input: CloudinaryGalleryInput as ComponentType<ArrayOfObjectsInputProps<any>>,
},
options: {
cloudinary: {
cloudName: 'your-cloudinary-cloud-name',
uploadPreset: 'your-upload-preset',
multiple: true,
sources: ['local', 'url', 'camera', 'dropbox'],
resourceType: 'image',
maxFiles: 20,
folder: 'your-folder-path',
}
} as any, // Type assertion for custom options
}),
],
}Configuration Options
The options.cloudinary object accepts the following properties:
| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| cloudName | string | ✅ | - | Your Cloudinary cloud name |
| uploadPreset | string | ✅ | - | Your Cloudinary upload preset |
| multiple | boolean | ❌ | true | Allow multiple file uploads |
| sources | string[] | ❌ | ['local', 'url', 'camera', 'dropbox'] | Available upload sources |
| resourceType | string | ❌ | 'image' | Type of resources to upload |
| maxFiles | number | ❌ | 20 | Maximum number of files |
| folder | string | ❌ | '' | Cloudinary folder path |
Cloudinary Setup
Create an Upload Preset:
- Go to your Cloudinary dashboard
- Navigate to Settings → Upload
- Create a new unsigned upload preset
- Configure allowed formats, transformations, etc.
Configure Security:
- Use unsigned upload presets for security
- Set appropriate folder restrictions
- Configure allowed file types and sizes
Data Structure
The component stores data in the following format:
interface ImageWithLegend {
_key: string
image: {
secure_url: string
public_id: string
original_filename: string
}
title?: string
legend?: string
}Usage Examples
Basic Gallery
defineField({
name: 'gallery',
title: 'Image Gallery',
type: 'array',
of: [{ type: 'object', fields: [
{ name: 'image', type: 'cloudinary.asset' },
{ name: 'caption', type: 'string' }
]}],
components: { input: CloudinaryGalleryInput },
options: {
cloudinary: {
cloudName: 'my-cloud',
uploadPreset: 'my-preset'
}
} as any
})Advanced Configuration
defineField({
name: 'portfolio',
title: 'Portfolio Images',
type: 'array',
of: [{ type: 'object', fields: [
{ name: 'image', type: 'cloudinary.asset' },
{ name: 'title', type: 'string' },
{ name: 'description', type: 'text' }
]}],
components: { input: CloudinaryGalleryInput },
options: {
cloudinary: {
cloudName: 'my-cloud',
uploadPreset: 'portfolio-uploads',
folder: 'portfolio/2024',
maxFiles: 50,
sources: ['local', 'url', 'camera'],
multiple: true
}
} as any
})Development
# Clone the repository
git clone https://github.com/victorbost/batch-upload-sanity-plugin-cloudinary.git
cd batch-upload-sanity-plugin-cloudinary
# Install dependencies
npm install
# Start development mode
npm run devBuilding
npm run buildDependencies
Peer Dependencies
react>= 18react-dom>= 18sanity>= 3@sanity/ui>= 1@dnd-kit/core>= 6@dnd-kit/sortable>= 7@dnd-kit/utilities>= 3uuid>= 9
Required Sanity Plugin
sanity-plugin-cloudinary- Official Cloudinary integration
Troubleshooting
Common Issues
"Cloudinary configuration required" message:
- Ensure you've added the
options.cloudinaryconfiguration - Verify your
cloudNameanduploadPresetare correct
- Ensure you've added the
TypeScript errors with custom options:
- Use
as anytype assertion for the options object - Or create custom type definitions
- Use
Upload widget not loading:
- Check your Cloudinary upload preset is unsigned
- Verify your cloud name is correct
- Ensure the Cloudinary script is loading properly
Drag and drop not working:
- Ensure all
@dnd-kitdependencies are installed - Check that the component is not in read-only mode
- Ensure all
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT © Victor Bostaetter
Support
If you encounter any issues or have questions, please open an issue on GitHub.
Changelog
0.1.0
- Initial release
- Batch image upload with Cloudinary
- Drag and drop reordering
- Title and caption support
- Configurable upload options
