0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

画像アップロード「Uploadthing」を使って、Nuxt3×Djnagoアプリから画像をアップロードする

Posted at

SaasサービスのUploathingとは?

Uploadthingの詳細は、下記の記事に記載していますので、今回は割愛します。

完成イメージ

image.png

ディレクトリ構成

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>

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?