MediaLit logoMediaLit Docs

Other frameworks

Upload from the browser with Vue, Svelte or plain JavaScript.

@medialit/uploader uploads a file from the browser to MediaLit and has no framework dependency. @medialit/react is built on it.

npm install @medialit/uploader

Your server needs a route that returns { signature, endpoint }. Use createSignatureHandler with any server that uses the Fetch API, or see Express.

Upload a file

import { uploadFile } from "@medialit/uploader";

const media = await uploadFile(file, {
    signatureEndpoint: "/api/medialit/signature",
    access: "public",
    onProgress: ({ percentage }) => console.log(`${Math.round(percentage)}%`),
});

console.log(media.mediaId, media.file);

uploadFile resolves to the uploaded media and rejects with an error whose message you can show to the user. Errors from MediaLit or your signature route are MediaLitUploadErrors with the HTTP status. Send media.mediaId to your server and seal it there when the user saves.

Cancel an upload

Pass an AbortSignal. Cancelling rejects with an UploadAbortedError.

import { isUploadAbortedError, uploadFile } from "@medialit/uploader";

const controller = new AbortController();
cancelButton.onclick = () => controller.abort();

try {
    await uploadFile(file, {
        signatureEndpoint: "/api/medialit/signature",
        signal: controller.signal,
    });
} catch (err) {
    if (!isUploadAbortedError(err)) showError(err.message);
}

Examples

With a bundler such as Vite:

<input type="file" id="file" />
<progress id="progress" max="100" value="0"></progress>

<script type="module">
    import { uploadFile } from "@medialit/uploader";

    document.getElementById("file").addEventListener("change", async (e) => {
        const media = await uploadFile(e.target.files[0], {
            signatureEndpoint: "/api/medialit/signature",
            onProgress: ({ percentage }) => {
                document.getElementById("progress").value = percentage;
            },
        });
        console.log(media.mediaId);
    });
</script>
<script setup lang="ts">
import { ref } from "vue";
import { uploadFile } from "@medialit/uploader";

const progress = ref(0);
const error = ref("");

async function onChange(e: Event) {
    const file = (e.target as HTMLInputElement).files?.[0];
    if (!file) return;
    try {
        const media = await uploadFile(file, {
            signatureEndpoint: "/api/medialit/signature",
            onProgress: (p) => (progress.value = p.percentage),
        });
        console.log(media.mediaId);
    } catch (err) {
        error.value = (err as Error).message;
    }
}
</script>

<template>
    <input type="file" @change="onChange" />
    <progress max="100" :value="progress" />
    <p v-if="error">{{ error }}</p>
</template>
<script lang="ts">
    import { uploadFile } from "@medialit/uploader";

    let progress = $state(0);
    let error = $state("");

    async function onchange(e: Event) {
        const file = (e.target as HTMLInputElement).files?.[0];
        if (!file) return;
        try {
            const media = await uploadFile(file, {
                signatureEndpoint: "/api/medialit/signature",
                onProgress: (p) => (progress = p.percentage),
            });
            console.log(media.mediaId);
        } catch (err) {
            error = (err as Error).message;
        }
    }
</script>

<input type="file" {onchange} />
<progress max="100" value={progress}></progress>
{#if error}<p>{error}</p>{/if}

Options

Prop

Type

On this page