sveltekit-local-upload Svelte Themes

Sveltekit Local Upload

A simple application for uploading files locally using SvelteKit

SvelteKit Local Upload

A simple application for uploading files locally using SvelteKit with a minimal retro design.

Main Features

  • Local file upload with type and size validation
  • Minimal retro interface styled with Tailwind CSS
  • Loading animation during the upload process
  • Modal notifications for success/error status
  • File type validation (JPG, PNG, PDF)
  • File size limit (maximum 1MB)

Upload Form

The file upload form is designed with a minimal retro style using Tailwind CSS. Below are the main components of the upload form:

1. File Input

The file input has a unique styling with thick borders and amber colors consistent with the retro theme:

<input
    type="file"
    name="fileToUpload"
    id="file"
    class="block w-full text-sm file:mr-4 file:cursor-pointer file:border-2 file:border-slate-800 file:bg-amber-200 file:px-4 file:py-2 file:text-sm file:font-semibold file:text-slate-800 hover:file:bg-amber-300"
    accept={acceptTypeFile.join(',')}
/>

The file input only accepts the following file types:

  • JPEG (image/jpeg)
  • PNG (image/png)
  • PDF (application/pdf)

2. Upload Button with Loading State

The upload button includes a loading animation that appears during the upload process:

<button
    type="submit"
    class="w-full cursor-pointer border-2 border-slate-800 bg-amber-500 px-4 py-2 font-bold tracking-wide uppercase shadow-[4px_4px_0px_0px_rgba(30,41,59)] transition-all hover:translate-y-1 hover:shadow-[2px_2px_0px_0px_rgba(30,41,59)] disabled:cursor-not-allowed disabled:opacity-70"
    disabled={isLoading}
>
    {#if isLoading}
        <div class="flex items-center justify-center">
            <svg
                class="mr-2 -ml-1 h-4 w-4 animate-spin text-slate-800"
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 24 24"
            >
                <!-- SVG path for loading animation -->
            </svg>
            Loading...
        </div>
    {:else}
        Upload
    {/if}
</button>

3. Notification Modal

The notification modal appears after the upload process is complete, displaying either success or error status:

{#if showModal}
    <div
        class="fixed inset-0 z-50 flex items-center justify-center bg-slate-800/50"
        onclick={closeModal}
        aria-hidden="true"
    >
        <div
            class="w-full max-w-md border-2 border-slate-800 bg-white shadow-[8px_8px_0px_0px_rgba(30,41,59)]"
            transition:fly={{ y: 200, duration: 1000 }}
        >
            <!-- Modal header with different colors based on status -->
            <div
                class="border-b-2 border-slate-800 {modalType === 'success'
                    ? 'bg-green-200'
                    : 'bg-red-200'} flex items-center justify-between p-3"
            >
                <h2 class="text-xl font-bold tracking-wide uppercase">
                    {modalType === 'success' ? 'Success' : 'Error'}
                </h2>
                <!-- Close button -->
            </div>
            <!-- Modal content with icon and message -->
        </div>
    </div>
{/if}

Server-Side Validation

File validation is performed server-side with several criteria:

  1. File Presence:

    if (
        !(formData.fileToUpload as File).name ||
        (formData.fileToUpload as File).name === 'undefined'
    ) {
        return fail(400, {
            success: false,
            message: 'You must provide a file to upload'
        });
    }
    
  2. File Size (maximum 1MB):

    if (fileToUpload.size > 1024 * 1024 * 1) {
        return fail(400, {
            success: false,
            message: 'File size must be less than 10MB'
        });
    }
    
  3. File Type (jpg, png, pdf):

    if (!['jpg', 'png', 'pdf'].includes(fileToUpload.name.split('.').pop() as string)) {
        return fail(400, {
            success: false,
            message: 'File type must be jpg, png, or pdf'
        });
    }
    

File Storage

Uploaded files are stored in the static/upload/ directory with filenames generated randomly using UUID:

const ext = fileToUpload.name.split('.').pop();
const fileName = `${crypto.randomUUID()}.${ext}`;

writeFileSync(`static/upload/${fileName}`, Buffer.from(await fileToUpload.arrayBuffer()));

How to Use

  1. Select the file you want to upload (JPG, PNG, or PDF)
  2. Click the "Upload" button
  3. Wait until the upload process is complete (indicated by loading animation)
  4. A notification modal will appear showing the upload status (success/error)
  5. Click the "Close" button to close the modal

Technologies Used

  • SvelteKit
  • TypeScript
  • Tailwind CSS
  • Node.js File System API

Top categories

Loading Svelte Themes