Home

Download and Upload Images to DigitalOcean Spaces with Next.js

17 views

To download images from URLs and save them in DigitalOcean Spaces using Next.js, you can create an API route to handle the image downloading and uploading. The following guide will cover how to do this.

Prerequisites

  1. Node.js and Next.js: Make sure you have a Next.js application set up. If you don't have one, you can create it quickly using:

    npx create-next-app@latest my-next-app
    cd my-next-app
    
  2. Install Required Packages: You'll need the following packages:

    • aws-sdk for interacting with DigitalOcean Spaces (S3-compatible).
    • axios for making HTTP requests (you can use node-fetch or the built-in https module, but axios is convenient).

    Install these using:

    npm install aws-sdk axios
    
  3. DigitalOcean Spaces Credentials: Make sure you have your Space name, Access Key, Secret Key, and the endpoint URL ready.

Step-by-Step Implementation

  1. Create an API Route: In your Next.js app, create a new API route to handle the image downloading and uploading. Create a file at pages/api/upload-image.js.

    // pages/api/upload-image.js
    import AWS from 'aws-sdk';
    import axios from 'axios';
    
    // Configure AWS S3
    const spacesEndpoint = new AWS.Endpoint('nyc3.digitaloceanspaces.com');
    const s3 = new AWS.S3({
        endpoint: spacesEndpoint,
        accessKeyId: process.env.SPACES_ACCESS_KEY, // Store your key in environment variables
        secretAccessKey: process.env.SPACES_SECRET_KEY,
    });
    
    export default async function handler(req, res) {
        if (req.method !== 'POST') {
            return res.status(405).json({ message: 'Method not allowed' });
        }
    
        const { imageUrl } = req.body;
    
        if (!imageUrl) {
            return res.status(400).json({ message: 'Image URL is required' });
        }
    
        try {
            // Download the image
            const response = await axios.get(imageUrl, { responseType: 'arraybuffer' });
    
            // Get the filename from the image URL
            const imageName = imageUrl.split('/').pop();
    
            // Upload the image to DigitalOcean Spaces
            const uploadParams = {
                Bucket: process.env.SPACES_BUCKET_NAME, // Your Space name
                Key: imageName,
                Body: response.data,
                ContentType: response.headers['content-type'],
            };
    
            await s3.putObject(uploadParams).promise();
    
            return res.status(200).json({ message: 'Image uploaded successfully', imageName });
        } catch (error) {
            console.error(error);
            return res.status(500).json({ message: 'Error uploading image', error: error.message });
        }
    }
    
  2. Environment Variables: You should store your sensitive information in environment variables. Create a .env.local file in the root of your Next.js project and add your credentials:

    SPACES_ACCESS_KEY=your_access_key
    SPACES_SECRET_KEY=your_secret_key
    SPACES_BUCKET_NAME=your_space_name
    
  3. Calling the API Route: You can call this API route from any part of your application. Here’s an example of how to call the API when a button is clicked. You might do it in a component:

    // components/UploadImageButton.js
    import { useState } from 'react';
    
    const UploadImageButton = () => {
        const [imageUrl, setImageUrl] = useState("");
    
        const handleSubmit = async () => {
            const res = await fetch('/api/upload-image', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ imageUrl }),
            });
    
            const data = await res.json();
            console.log(data);
            if (res.ok) {
                alert('Image uploaded successfully');
            } else {
                alert(`Error: ${data.message}`);
            }
        };
    
        return (
            <div>
                <input
                    type="text"
                    value={imageUrl}
                    onChange={(e) => setImageUrl(e.target.value)}
                    placeholder="Enter image URL"
                />
                <button onClick={handleSubmit}>Upload Image</button>
            </div>
        );
    };
    
    export default UploadImageButton;
    
  4. Integrating the Component: You can integrate this component in your main page or wherever you need it.

    // pages/index.js
    import UploadImageButton from '../components/UploadImageButton';
    
    export default function Home() {
        return (
            <div>
                <h1>Upload Image to DigitalOcean Spaces</h1>
                <UploadImageButton />
            </div>
        );
    }
    

Testing the Functionality:

  • Start your Next.js application:
    npm run dev
    
  • Navigate to http://localhost:3000.
  • Enter an image URL in the input field and click the upload button.

Notes:

  • Ensure CORS is properly configured for your DigitalOcean Space if you're working in a cross-origin environment.
  • Adjust error handling and validation as necessary for a production-ready application.
  • The example uses a simple text input to gather the image URL, but further validation could improve user experience.

This setup should allow you to download images from a URL and save them to DigitalOcean Spaces effectively using Next.js!