Skip to content

Latest commit

 

History

History
239 lines (178 loc) · 6.84 KB

File metadata and controls

239 lines (178 loc) · 6.84 KB

import { docsMetadata } from "@/lib/utils";

export const metadata = docsMetadata({ title: "TanStack Start Setup", description: "Learn how to set up a TanStack Start project with UploadThing", category: "Getting Started", });

Getting Started with TanStack Start

Package Setup

Install the packages

npm install uploadthing @uploadthing/react

Add env variables

UPLOADTHING_TOKEN=... # A token for interacting with the SDK
If you don't already have a uploadthing token, [sign up](https://uploadthing.com/sign-in) and create one from the [dashboard!](https://uploadthing.com/dashboard) TanStack Start is currently in release candidate (RC). The APIs in this guide match the current v1 RC server-route conventions, but may still change before 1.0.

Set Up A FileRouter

Creating your first FileRoute

All files uploaded to uploadthing are associated with a FileRoute. The following is a very minimalistic example, with a single FileRoute "imageUploader". Think of a FileRoute similar to an endpoint, it has:

  • Permitted types ["image", "video", etc]
  • Max file size
  • How many files are allowed to be uploaded
  • (Optional) input validation to validate client-side data sent to the route
  • (Optional) middleware to authenticate and tag requests
  • onUploadComplete callback for when uploads are completed

To get full insight into what you can do with the FileRoutes, please refer to the File Router API.

import { createUploadthing, UploadThingError } from "uploadthing/server";
import type { FileRouter } from "uploadthing/server";

const f = createUploadthing();

const auth = (req: Request) => ({ 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: {
      /**
       * For full list of options and defaults, see the File Route API reference
       * @see https://docs.uploadthing.com/file-routes#route-config
       */
      maxFileSize: "4MB",
      maxFileCount: 1,
    },
  })
    // Set permissions and file types for this FileRoute
    .middleware(async ({ req }) => {
      // This code runs on your server before upload
      const user = await auth(req);

      // If you throw, the user will not be able to upload
      if (!user) throw new UploadThingError("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);

      // !!! Whatever is returned here is sent to the clientside `onClientUploadComplete` callback
      return { uploadedBy: metadata.userId };
    }),
} satisfies FileRouter;

export type UploadRouter = typeof uploadRouter;

Create an API route using the FileRouter

TanStack Start server routes can live anywhere under `src/routes`, but this guide uses `src/routes/api/uploadthing.ts` so the endpoint is served from `/api/uploadthing`. TanStack Start server routes now live directly in your `src/routes` tree, so `src/routes/api/uploadthing.ts` automatically serves `/api/uploadthing`. For more information, please refer to the [TanStack Start server-routes docs](https://tanstack.com/start/latest/docs/framework/react/guide/server-routes).
import { createFileRoute } from "@tanstack/react-router";

import { createRouteHandler } from "uploadthing/server";

import { uploadRouter } from "../../server/uploadthing";

const handler = createRouteHandler({ router: uploadRouter });

export const Route = createFileRoute("/api/uploadthing")({
  server: {
    handlers: {
      GET: async ({ request }) => {
        return handler(request);
      },
      POST: async ({ request }) => {
        return handler(request);
      },
    },
  },
});

See configuration options in server API reference

Create The UploadThing Components

We provide components to make uploading easier. We highly recommend re-exporting them with the types assigned, but you CAN import the components individually from @uploadthing/react instead.

import {
  generateReactHelpers,
  generateUploadButton,
  generateUploadDropzone,
} from "@uploadthing/react";

import type { UploadRouter } from "../server/uploadthing";

export const UploadButton = generateUploadButton<UploadRouter>();
export const UploadDropzone = generateUploadDropzone<UploadRouter>();
export const { useUploadThing } = generateReactHelpers<UploadRouter>();
To learn more about the components, check out the [react API reference](/api-reference/react).

Add UploadThing's Styles

<Tabs tabs={["Tailwind v3", "Tailwind v4", "Other"]}> Wrap your Tailwind config with the withUt helper. You can learn more about our Tailwind helper in the "Theming" page

  ```tsx
  import { withUt } from "uploadthing/tw";

  export default withUt({
    // Your existing Tailwind config
    content: ["./src/**/*.{ts,tsx,mdx}"],
    ...
  });
  ```

</Tab>

<Tab>
  If you're using Tailwind v4 with CSS configuration, you can use our plugin like this:

  ```css
  @import "tailwindcss";

  @import "uploadthing/tw/v4";
  @source "../node_modules/@uploadthing/react/dist"; /** <-- depends on your project structure */
  ```

  You can learn more about our Tailwind helper in the ["Theming" page](/concepts/theming#theming-with-tailwind-css)
</Tab>

<Tab>
  Include our CSS file in the root layout to make sure the components look right!

  ```tsx {{ title: "src/routes/__root.tsx" }}
  import uploadthingCss from "@uploadthing/react/styles.css?url";

  export const Route = createRootRoute({
    component: RootComponent,
    links: () => [{ rel: "stylesheet", href: uploadthingCss }],
  });
  ```

</Tab>

Mount A Button And Upload!

import { createFileRoute } from "@tanstack/react-router";

import { UploadButton } from "../utils/uploadthing";

export const Route = createFileRoute("/")({
  component: Home,
});

function Home() {
  return <UploadButton endpoint="imageUploader" />;
}

🎉 You're Done!

Want to customize the components? Check out the "Theming" page

Want to make your own components? Check out our useUploadThing hook