Getting Started using Nuxt
The UploadThing Nuxt module makes it super easy to get started with uploading in
Nuxt apps. It is a wrapper around @uploadthing/vue
and the H3 backend adapter.
Check out a full example here β
Using standalone Vue without Nuxt? Checkout the standalone example here β
Package Setup
Install the packages
npm install uploadthing @uploadthing/nuxt
Add env variables
NUXT_UPLOADTHING_TOKEN=... # A token for interacting with the SDK
# π NUXT_ prefix is **important**
If you don't already have a uploadthing secret key, sign up β and create one from the dashboard! β
Initialize the Uploadthing module
Add the @uploadthing/nuxt
module to your nuxt.config.ts
file:
nuxt.config.ts
export default {
modules: ["@uploadthing/nuxt"],
uploadthing: {
/**
* Path to your router definition file
* @default `~/server/uploadthing.ts`
*/
routerPath: "",
},
};
You can set some module options in the uploadthing
property of your
nuxt.config.ts
file:
/**
* See https://docs.uploadthing.com/api-reference/server#createroutehandler
* for more information about the `RouteHandlerConfig` options.
*/
export type ModuleOptions = RouteHandlerConfig & {
/**
* Path to your router definition file
* @default `~/server/uploadthing.ts`
*/
routerPath?: string;
};
Set Up A FileRouter
All files uploaded to uploadthing are associated with a FileRoute. The following is a very minimalistic example, with a single FileRoute "imageUploader". Think of a FileRoute similar to an endpoint, it has:
- Permitted types ["image", "video", etc]
- Max file size
- How many files are allowed to be uploaded
- (Optional)
input
validation to validate client-side data sent to the route - (Optional)
middleware
to authenticate and tag requests onUploadComplete
callback for when uploads are completed
To get full insight into what you can do with the FileRoutes, please refer to the File Router API.
It is import you export the router as uploadRouter
and the inferred type as
UploadRouter
for the module to pick up your router and it's types.
src/lib/server/uploadthing.ts
import type { H3Event } from "h3";
import { createUploadthing } from "uploadthing/h3";
import type { FileRouter } from "uploadthing/h3";
const f = createUploadthing();
const auth = (ev: H3Event) => ({ id: "fakeId" }); // Fake auth function
// FileRouter for your app, can contain multiple FileRoutes
export const uploadRouter = {
// Define as many FileRoutes as you like, each with a unique routeSlug
imageUploader: f({
image: {
/**
* For full list of options and defaults, see the File Route API reference
* @see https://docs.uploadthing.com/file-routes#route-config
*/
maxFileSize: "4MB",
maxFileCount: 1,
},
})
// Set permissions and file types for this FileRoute
.middleware(async ({ event }) => {
// This code runs on your server before upload
const user = await auth(event);
// If you throw, the user will not be able to upload
if (!user) throw new Error("Unauthorized");
// Whatever is returned here is accessible in onUploadComplete as `metadata`
return { userId: user.id };
})
.onUploadComplete(async ({ metadata, file }) => {
// This code RUNS ON YOUR SERVER after upload
console.log("Upload complete for userId:", metadata.userId);
console.log("file url", file.url);
}),
} satisfies FileRouter;
export type UploadRouter = typeof uploadRouter;
Upload some files!
Just mount one of our components in your app and start uploading files!
pages/index.vue
<script setup lang="ts">
const alert = (msg: string) => {
window.alert(msg);
};
</script>
<template>
<div>
<UploadButton
:config="{
endpoint: 'imageUploader',
onClientUploadComplete: (file) => {
console.log('uploaded', file);
alert('Upload complete');
},
onUploadError: (error) => {
console.error(error, error.cause);
alert('Upload failed');
},
}"
/>
<UploadDropzone
:config="{
endpoint: 'imageUploader',
onClientUploadComplete: (file) => {
console.log('uploaded', file);
alert('Upload complete');
},
onUploadError: (error) => {
console.error(error, error.cause);
alert('Upload failed');
},
}"
/>
</div>
</template>
For component API reference, refer to the React API reference. Framework specific docs will be added soon.
Custom flows with the useUploadThing
composable
If the premade components don't fit your needs, you can use the useUploadThing
to create your own custom components.
pages/index.vue
<script setup lang="ts">
const alert = (msg: string) => {
window.alert(msg);
};
const { startUpload } = useUploadThing("videoAndImage", {
onClientUploadComplete(res) {
console.log(`onClientUploadComplete`, res);
alert("Upload Completed");
},
});
</script>
<template>
<label>
<input
type="file"
@change="
async (e) => {
console.log(`e`, e);
const file = (e.target as HTMLInputElement).files?.[0];
if (!file) return;
// Do something with files
// Then start the upload
await startUpload([file]);
}
"
/>
</label>
</template>