SaasサービスのUploathingとは?
Uploadthingの詳細は、下記の記事に記載していますので、今回は割愛します。
完成イメージ
ディレクトリ構成
frontendフォルダにNuxt3プロジェクトを、backendフォルダにDjangoプロジェクトをそれぞれ格納します。
.
└── NuxtDjangoProject/
├── backend/
│ ├── adminuser
│ ├── api/
│ │ ├── migrations/
│ │ │ └── 0001_initial.py
│ │ ├── serializer.py
│ │ ├── urls.py
│ │ └── views.py
│ └── todoproject/
│ ├── settings.py
│ └── urls.py
└── frontend/
├── components/
│ ├── footer/
│ │ └── footer.vue
│ └── navbar/
│ └── navbar.vue
├── pages/
│ ├── adminUsers/
│ │ ├── login/
│ │ │ └── login.vue
│ │ ├── registration/
│ │ │ └── registration.vue
│ │ ├── updateProfile/
│ │ │ └── updateProfile.vue
│ │ └── uploadImageFile/
│ │ └── uploadImageFile.vue
│ ├── login/
│ │ └── login.vue
│ ├── registration/
│ │ └── registration.vue
│ └── index.vue
├── .env
├── server/
│ └── uploadthing.ts
├── app.vue
├── nuxtconfig.ts/
│ └── package.json
└── tsxconfig.json
Nuxt3とUploadthingの連携方法
uploadthingの下記の公式ドキュメントを参照しながら進めていきます。
パッケージをインストールする
uploadthingをNuxt3でも使えるようにパッケージをインストールしましょう。
frontendフォルダ直下に移動して、下記のコマンドをコマンドパレットに入力します。
npm install uploadthing @uploadthing/nuxt
.envファイルにトークンを追加する
.envファイルにUploadthingにトークンを追加します。
UPLOADTHING_TOKEN='your access token'
Uploadthingモジュールを初期化する
@uploadthing/nuxtモジュールをnuxtconfig.tsに追加します。
nuxtconfig.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-11-01',
devtools: { enabled: true },
modules: ['vuetify-nuxt-module', '@pinia/nuxt','@uploadthing/nuxt'],
pinia:{
authImports:[
'defineStore'
],
},
})
ファイルアップロード機能をサーバ側(Typescript)に追加する
画像をサーバ経由でuploadthingへアップ路度するための機能を実装します。
frontend/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: {
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.ufsUrl);
}),
} satisfies FileRouter;
export type UploadRouter = typeof uploadRouter;
画面を作成する
サーバまでの機能を実装をしたので、最後に画面を作っていきます。
frontend/pages/adminUsers/uploadImageFile/uploadImageFile.vue
<script setup lang="ts">
import { useRouter } from 'vue-router';
const router = useRouter();
const alert = (msg: string) => {
window.alert(msg);
};
</script>
<template>
<div>
<UploadButton
:config="{
endpoint: 'imageUploader',
onClientUploadComplete: (file) => {
console.log('uploaded', file);
console.log('uploaded', file[0].url);
alert('Upload complete');
router.push(`/adminUsers/updateProfile/updateProfile?image=${file[0].url}`);
},
onUploadError: (error) => {
console.error(error, error.cause);
alert('Upload failed');
},
}"
/>
<UploadDropzone
:config="{
endpoint: 'imageUploader',
onClientUploadComplete: (file) => {
console.log('uploaded', file);
//console.log('uploaded', file[0].url);
alert('Upload complete');
},
onUploadError: (error) => {
console.error(error, error.cause);
alert('Upload failed');
},
}"
/>
</div>
</template>
以上です。
