🪼

Remixで画像ファイルをクラウドストレージにアップロード

2024/07/26に公開

フルスタックWebアプリケーションフレームワークの Remix に関する内容です。
今回は、画像ファイルをクラウドサービスへアップロードする処理の実装を行います。

画像を管理するクラウドサービスとして ImageKit を採用しています。
ImageKit は画像管理のための豊富な API が用意されており使いやすいサービスです。
無料プランもあるので気軽に試すことができます。(2024年7月時点)

API を使用する際には、API keys が必要です。
これらを .env ファイルで管理し、バックエンドから取得してリクエストを行います。

事前準備

事前に ImageKit のサインアップが完了しており、マイページから API keys を参照できる状態にしておきます。
API keys はマイページの下部「Developer options」の「API keys」から確認できます。
以下の3つが必要になるのでコピーしておきます。

  • URL-endpoint: https:///ik.imagekit.io/a1b2c3****
  • Public Key: public_ABC123**********
  • Private Key: private_ZXC987**********

プロジェクト作成してフォームを実装

今回はコンパイラとして Vite を使います。
以下のコマンドでRemix プロジェクトを作成。

npm create vite@latest
ログ
Need to install the following packages:
create-remix@2.10.3
Ok to proceed? (y)


 remix   v2.10.3 💿 Let's build a better website...

   dir   Where should we create your new project?
         remix-upload-sample

      ◼  Template: Using remix-run/remix/templates/express...
      ✔  Template copied

   git   Initialize a new git repository?
         Yes

  deps   Install dependencies with npm?
         Yes

      ✔  Dependencies installed

      ✔  Git initialized

  done   That's it!

         Enter your project directory using cd ./remix-upload-sample
         Check out README.md for development and deploy instructions.

         Join the community at https://rmx.as/discord

app/routes/_index.tsx を開いて、ファイル選択とアップロード用のボタンを設置します。
フォームには Remix の Form コンポーネントを使いました。※Formについて
ファイルアップロードの際は、エンコードタイプで multipart/form-data を指定する必要がある点に注意です。

https://github.com/t-aono/remix-upload-sample/blob/884687fd69110bbc7108ee4863e024ebd0d1b7a4/app/routes/_index.tsx#L29-L34

アップロード処理を実装

認証を行うための API keys を .env ファイルを作成してコピペしておきます。

PUBLIC_KEY="public_ABC123**********"
PRIVATE_KEY="private_ZXC987**********"
URL_ENDPOINT="https:///ik.imagekit.io/a1b2c3****"

SDK を使うとより簡単に実装ができるので Node.js 用の SDK をインストールしておきます。

npm install imagekit --save

app/routes/_index.tsx を開いて action 関数を追加します。
この時、フォームは multipart form で送られてくるので unstable_parseMultipartFormData という関数を使って処理します。
unstable_parseMultipartFormData について

https://github.com/t-aono/remix-upload-sample/blob/884687fd69110bbc7108ee4863e024ebd0d1b7a4/app/routes/_index.tsx#L16-L24

uploadHandler を実装します。今回は app/utilities/image.server.ts を作成して定義しています。
unstable_composeUploadHandlers を使うことでフォームの name, data, filename 等を取得できます。
name は input タグの name プロパティの値です。filename は選択したファイルのファイル名です。

https://github.com/t-aono/remix-upload-sample/blob/884687fd69110bbc7108ee4863e024ebd0d1b7a4/app/utilities/image.server.ts#L35-L46

data については Buffer 型に変換しないとうまく動作しないので、変換用の関数を用意しています。

https://github.com/t-aono/remix-upload-sample/blob/884687fd69110bbc7108ee4863e024ebd0d1b7a4/app/utilities/image.server.ts#L27-L33

uploadImage では ImageKit の SDK を使ってアップロードを行います。

https://github.com/t-aono/remix-upload-sample/blob/884687fd69110bbc7108ee4863e024ebd0d1b7a4/app/utilities/image.server.ts#L9-L25

これでフォームから画像アップロードができるようになりました。
アップロードが成功すると、画像にアクセスするためのURLが出力されるはずです。

参考

ImageKit について
https://imagekit.io/

Remix の Vite に関する説明
https://remix.run/docs/en/main/guides/vite

ImageKit の Node.js 用 SDK
https://github.com/imagekit-developer/imagekit-nodejs

Discussion