Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/beige-camels-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@uploadthing/nuxt": major
---

Migrate module to Nuxt 4 and add Tailwind v4 support
2 changes: 1 addition & 1 deletion packages/nuxt/.nuxtrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
imports.autoImport=false
typescript.includeWorkspace=true
experimental.typescriptBundlerResolution=true
future.typescriptBundlerResolution=true
211 changes: 96 additions & 115 deletions packages/nuxt/README.md
Original file line number Diff line number Diff line change
@@ -1,155 +1,136 @@
# Nuxt UploadThing Module

[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![License][license-src]][license-href] [![Nuxt][nuxt-src]][nuxt-href]
[![npm version](https://img.shields.io/npm/v/@uploadthing/nuxt/latest.svg?style=flat&colorA=020420&colorB=00DC82)](https://npmjs.com/package/@uploadthing/nuxt)
[![npm downloads](https://img.shields.io/npm/dm/@uploadthing/nuxt.svg?style=flat&colorA=020420&colorB=00DC82)](https://npm.chart.dev/@uploadthing/nuxt)
[![License](https://img.shields.io/npm/l/@uploadthing/nuxt.svg?style=flat&colorA=020420&colorB=00DC82)](https://npmjs.com/package/@uploadthing/nuxt)
[![Nuxt](https://img.shields.io/badge/Nuxt-020420?logo=nuxt)](https://nuxt.com)

Nuxt module for getting started with UploadThing in your Nuxt app.

- [✨  Release Notes](/CHANGELOG.md)
Nuxt module for UploadThing with type-safe router integration, generated components, and auto-registered helpers.

## Quick Setup
---

1. Add `@uploadthing/nuxt` and `uploadthing` dependencies to your project
## Features

```bash
# Using pnpm
pnpm add -D @uploadthing/nuxt
pnpm add uploadthing

# Using yarn
yarn add --dev @uploadthing/nuxt
yarn add uploadthing
- Type-safe UploadThing router integration
- Auto-generated upload components
- Auto-imported UploadThing Vue helpers
- Optional Tailwind styles integration

# Using npm
npm install --save-dev @uploadthing/nuxt
npm install uploadthing

# Using bun
bun add -D @uploadthing/nuxt
bun add uploadthing
```
---

2. Add `@uploadthing/nuxt` to the `modules` section of `nuxt.config.ts`
## Installation

```js
export default defineNuxtConfig({
modules: ["@uploadthing/nuxt"],
});
```bash
pnpm add @uploadthing/nuxt uploadthing
```

That's it! You can now use @uploadthing/nuxt in your Nuxt app ✨
---

## Quick Start

## Usage
1) Add the module in `nuxt.config.ts`

> For full documentation, see the
> [UploadThing docs](https://docs.uploadthing.com/getting-started/nuxt)
```ts
export default defineNuxtConfig({
modules: ['@uploadthing/nuxt'],

uploadthing: {
fileRouterPath: '@@/server/uploadthing',
fileRouterExport: 'fileRouter',
componentPrefix: 'Uploadthing',
useTailwindStyles: false,
},
})
```

1. Create an upload router in your app:
2) Create your UploadThing router in `server/uploadthing.ts`

```js
// server/uploadthing.ts
import { createUploadthing, UTFiles } from "uploadthing/h3";
import type { FileRouter } from "uploadthing/h3";
```ts
import { createUploadthing, type FileRouter } from 'uploadthing/h3'

const f = createUploadthing();
const f = createUploadthing()

/**
* This is your Uploadthing file router. For more information:
* @see https://docs.uploadthing.com/api-reference/server#file-routes
*/
export const uploadRouter = {
videoAndImage: f({
image: {
maxFileSize: "4MB",
maxFileCount: 4,
acl: "public-read",
},
video: {
maxFileSize: "16MB",
},
export const fileRouter = {
imageUploader: f({
image: { maxFileSize: '4MB', maxFileCount: 1 },
})
.middleware(({ event, files }) => {
// ^? H3Event

// Return some metadata to be stored with the file
return { foo: "bar" as const };
.middleware(async () => {
return { userId: 'demo-user' }
})
.onUploadComplete(({ file, metadata }) => {
// ^? { foo: "bar" }
console.log("upload completed", file);
.onUploadComplete(async ({ metadata, file }) => {
return {
uploadedBy: metadata.userId,
url: file.ufsUrl,
}
}),
} satisfies FileRouter;

export type UploadRouter = typeof uploadRouter;
} satisfies FileRouter
```

2. Mount a component in your app and start uploading files:
3) Use generated components anywhere in your app

Comment on lines 70 to 72
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Wrong package name in install instructions

The README tells users to install nuxt-uploadthing, but package.json still declares "name": "@uploadthing/nuxt" and the changeset also references @uploadthing/nuxt. The badges at the top also link to the nuxt-uploadthing npm slug, which would 404 unless this package is being renamed (but the package.json has not changed its name field).

Suggested change
2. Mount a component in your app and start uploading files:
3) Use generated components anywhere in your app
pnpm add @uploadthing/nuxt uploadthing
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/nuxt/README.md
Line: 69-71

Comment:
**Wrong package name in install instructions**

The README tells users to install `nuxt-uploadthing`, but `package.json` still declares `"name": "@uploadthing/nuxt"` and the changeset also references `@uploadthing/nuxt`. The badges at the top also link to the `nuxt-uploadthing` npm slug, which would 404 unless this package is being renamed (but the package.json has not changed its `name` field).

```suggestion
pnpm add @uploadthing/nuxt uploadthing
```

How can I resolve this? If you propose a fix, please make it concise.

```vue
<script setup lang="ts">
const alert = (msg: string) => {
window.alert(msg);
};
</script>

<template>
<div>Playground</div>
<UploadButton
:config="{
endpoint: 'videoAndImage',
onClientUploadComplete: (res) => {
console.log(`onClientUploadComplete`, res);
alert('Upload Completed');
},
onUploadBegin: () => {
console.log(`onUploadBegin`);
},
}"
/>

<UploadDropzone
<UploadThingUploadButton
:config="{
endpoint: 'videoAndImage',
onClientUploadComplete: (res) => {
console.log(`onClientUploadComplete`, res);
alert('Upload Completed');
},
onUploadBegin: () => {
console.log(`onUploadBegin`);
},
endpoint: 'imageUploader',
onClientUploadComplete: (res) => console.log(res),
onUploadError: (error) => console.error(error),
}"
/>
</template>
```

Wow, that was easy!

## Development

From workspace root:
## Tailwind Styles

```bash
# Install dependencies
pnpm install
To use UploadThing Tailwind styles, enable:

```ts
uploadthing: {
useTailwindStyles: true,
}
```

Requirements:

1. `tailwindcss` must be installed in your project.
2. Import both Tailwind and `@uploadthing/nuxt` styles in your main CSS file (for example `assets/css/main.css`):

```css
@import "tailwindcss";
@import '@uploadthing/nuxt'
```

If `tailwindcss` is missing, the module falls back to UploadThing default CSS.

# Develop with the playground
pnpm dev
---

# Run ESLint
pnpm lint
## Module Options

```ts
uploadthing: {
fileRouterPath: '@@/server/uploadthing',
fileRouterExport: 'fileRouter',
componentPrefix: 'Uploadthing',
useTailwindStyles: false,
}
```

<!-- Badges -->

[npm-version-src]:
https://img.shields.io/npm/v/@uploadthing/nuxt/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
[npm-version-href]: https://npmjs.com/package/@uploadthing/nuxt
[npm-downloads-src]:
https://img.shields.io/npm/dm/@uploadthing/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D
[npm-downloads-href]: https://npmjs.com/package/@uploadthing/nuxt
[license-src]:
https://img.shields.io/npm/l/@uploadthing/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D
[license-href]: https://npmjs.com/package/@uploadthing/nuxt
[nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
[nuxt-href]: https://nuxt.com
- `fileRouterPath`: Path to your UploadThing router file.
- `fileRouterExport`: Export name of the router in that file.
- `componentPrefix`: Prefix for generated components (`<prefix>UploadButton`, `<prefix>UploadDropzone`).
- `useTailwindStyles`: Enable UploadThing Tailwind styles integration.

---

## Auto-Imports

The module auto-imports these helpers:

- `useUploadThing`
- `createUpload`
- `routeRegistry`
- `uploadFiles`
10 changes: 10 additions & 0 deletions packages/nuxt/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,15 @@ export default [
ignores: ["dist/**", "playground/**"],
},
...baseConfig,
{
files: ["src/**/*.ts", "src/**/*.vue", "src/**/*.mts"],
languageOptions: {
parserOptions: {
project: ["./tsconfig.json"],
tsconfigRootDir: import.meta.dirname,
projectService: false,
},
},
},
noSelfImport("@uploadthing/nuxt"),
];
33 changes: 20 additions & 13 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,53 @@
},
"exports": {
".": {
"types": "./dist/types.d.ts",
"types": "./dist/types.d.mts",
"import": "./dist/module.mjs",
"require": "./dist/module.cjs"
"style": "./dist/runtime/uploadthing-tw.css"
}
},
"main": "./dist/module.mjs",
"typesVersions": {
"*": {
".": ["./dist/types.d.mts"]
}
},
"main": "./dist/module.cjs",
"types": "./dist/types.d.ts",
"files": [
"dist"
],
"scripts": {
"lint": "eslint src --max-warnings 0",
"build": "nuxt-module-build build && tsc && bun run postbuild.ts",
"build": "nuxt-module-build build && tsc",
"clean": "git clean -xdf .nuxt dist node_modules",
"dev": "nuxi dev playground --port 3010",
"dev:build": "nuxi build playground",
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
"prepack": "bun ../../.github/replace-workspace-protocol.ts",
"dev:prepack": "nuxt-module-build build",
"FIXME__test": "vitest run",
"test:watch": "vitest watch"
},
"dependencies": {
"@nuxt/kit": "^3.15.0",
"@nuxt/kit": "^4.4.2",
"@uploadthing/vue": "workspace:*",
"defu": "^6.1.4"
"defu": "^6.1.7",
"pathe": "^2.0.3"
},
"devDependencies": {
"@nuxt/devtools": "1.7.0",
"@nuxt/module-builder": "^0.8.4",
"@nuxt/schema": "^3.15.0",
"@nuxtjs/tailwindcss": "^6.12.2",
"@nuxt/devtools": "^3.2.4",
"@nuxt/module-builder": "^1.0.2",
"@nuxt/schema": "^4.4.2",
"@nuxt/test-utils": "^4.0.2",
"@uploadthing/eslint-config": "workspace:*",
"eslint": "9.25.1",
"h3": "^1.13.0",
"nuxt": "^3.15.0",
"nuxt": "^4.4.2",
"uploadthing": "workspace:*",
"vite": "^6.3.4",
"vitest": "3.2.4"
},
"peerDependencies": {
"uploadthing": "^7.2.0"
"uploadthing": "^7.2.0",
"nuxt": "^4.0.0"
}
}
37 changes: 0 additions & 37 deletions packages/nuxt/postbuild.ts

This file was deleted.

Loading
Loading