DEV Community

Cover image for Next.js Image File Upload and Preview with shadcn/ui
Aaronn
Aaronn

Posted on • Originally published at frontendshape.com

13 1 1 1 1

Next.js Image File Upload and Preview with shadcn/ui

In this tutorial, we'll create an image file upload with a preview using Next.js and Shadcn UI.

In this guide, we will create a file upload feature in Next.js using React hooks. We will include a file preview using the Next.js Image component and utilize Shadcn UI's Input and Label components for file selection.



"use client"

import { useState } from "react"
import Image from "next/image"

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export default function InputFile() {
  const [selectedFile, setSelectedFile] = useState(null)

  const handleFileChange = (e) => {
    const file = e.target.files[0]
    if (file) {
      const reader = new FileReader()
      reader.onloadend = () => {
        setSelectedFile(reader.result)
      }
      reader.readAsDataURL(file)
    }
  }

  return (
    <div className="grid w-full max-w-sm items-center gap-1.5">
      <Label htmlFor="picture">Picture</Label>
      <Input id="picture" type="file" onChange={handleFileChange} />
      {selectedFile && (
        <div className="mt-2">
          <Image
            src={selectedFile}
            alt="Preview"
            className="rounded-md"
            width={500}
            height={500}
          />
        </div>
      )}
    </div>
  )
}


Enter fullscreen mode Exit fullscreen mode

image file upload and preview
Building a Next.js Image File Upload and Preview Feature Using TypeScript and Shadcn UI.



"use client"

import React, { ChangeEvent, useState } from 'react';
import Image from 'next/image'
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

interface InputFileProps {
  // You can add any additional props needed
}

export default function InputFile(props: InputFileProps) {
  const [selectedFile, setSelectedFile] = useState<string | null>(null);

  const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];

    if (file) {
      const reader = new FileReader();
      reader.onloadend = () => {
        setSelectedFile(reader.result as string);
      };
      reader.readAsDataURL(file);
    }
  };

  return (
    <div className="grid w-full max-w-sm items-center gap-1.5">
      <Label htmlFor="picture">Picture</Label>
      <Input id="picture" type="file" onChange={handleFileChange} />
      {selectedFile && (
        <div className="mt-2">
          <Image
            src={selectedFile}
            alt="Preview"
            width={500}
            height={500}
          />
        </div>
      )}
    </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

Next.js with Shadcn UI Image File Upload Preview and remove button for the image preview.



"use client"

import React, { ChangeEvent, useState } from 'react';
import Image from 'next/image'
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

interface InputFileProps {
  // You can add any additional props needed
}

export default function InputFile(props: InputFileProps) {
  const [selectedFile, setSelectedFile] = useState<string | null>(null);

  const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];

    if (file) {
      const reader = new FileReader();
      reader.onloadend = () => {
        setSelectedFile(reader.result as string);
      };
      reader.readAsDataURL(file);
    }
  };

  const handleRemoveClick = () => {
    setSelectedFile(null);
  };

  return (
    <div className="grid w-full max-w-sm items-center gap-1.5">
      <Label htmlFor="picture">Picture</Label>
      <Input id="picture" type="file" onChange={handleFileChange} />
      {selectedFile && (
        <div className="mt-2 relative">
          <Image
            src={selectedFile}
            alt="Preview"
            width={500}
            height={500}
          />
          <button
            onClick={handleRemoveClick}
            className="absolute top-0 right-0 bg-red-500 text-white py-1 px-2"
            aria-label="Remove image"
          >
            X
          </button>
        </div>
      )}
    </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

File Upload Preview and remove button

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay