2.0 beta — new releases can include breaking changes. Stable 1.x docs
dimah-s3v2.0.0-beta.0

React Setup

Install @dimah-s3/react, create the client, mount S3Provider, and call your first hook.

Install

npm i @dimah-s3/react@beta @dimah-s3/core@beta @fuma-translate/react

@dimah-s3/react needs React 19.2. @dimah-s3/core holds APIError and the protocol helpers, and @fuma-translate/react powers the translated strings.

Create the client

createS3Client returns the API object plus a bound Provider and a typed useApi.

lib/s3-client.ts
"use client";

import { createS3Client } from "@dimah-s3/react";

export const s3Client = createS3Client();
export const S3Provider = s3Client.Provider;

To change the base path, send cookies, or add headers:

export const s3Client = createS3Client({
  basePath: "/api/s3", 
  credentials: "include", 
  headers: async () => ({
    Authorization: `Bearer ${await getAuthToken()}`, 
  }), 
});

Mount S3Provider

Mount the provider near your app root:

app/layout.tsx
import { S3Provider } from "@/lib/s3-client"; 

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <S3Provider>{children}</S3Provider>
      </body>
    </html>
  );
}

The provider also takes translations and locale. See Internationalization.

Call your first hook

Use useUpload with a route name from your server config:

app/file-uploader.tsx
"use client";

import { useUpload } from "@dimah-s3/react";

export function FileUploader() {
  const upload = useUpload({ route: "avatar" });

  return (
    <div
      {...upload.getRootProps({
        className: "cursor-pointer rounded border p-4 text-center",
      })}
    >
      <input {...upload.getInputProps()} />
      {upload.isPending
        ? `Uploading: ${upload.progress.percent}%`
        : "Click or drop a file here"}
    </div>
  );
}

Every hook takes an optional api to use instead of the provider's.


Shared and server modules

The root entry is a client module. Plain functions that do not need React, such as defineApi, memoryObjectSource, and createLocalStorageStore, ship from @dimah-s3/react/engine, which has no "use client" directive:

lib/s3-api.ts
import { defineApi } from "@dimah-s3/react/engine";

See Engine for the full list.


TypeScript route inference

Type route names across hooks and components:

lib/s3-routes.ts
import type { InferS3Routes } from "@dimah-s3/core";
import type { s3 } from "@/lib/s3";

declare module "@dimah-s3/core" {
  interface DimahS3Routes extends Record<InferS3Routes<typeof s3>, true> {} 
}

Type reference

import type { CreateS3ClientOptions } from "@dimah-s3/core";

CreateS3ClientOptions

Prop

Type

Frequently asked questions

On this page