Skip to content

docs: Add getting started for tanstack/start #973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions docs/src/app/(docs)/getting-started/tanstack-start/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
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

```bash npm2yarn
npm install uploadthing @uploadthing/react
```

### Add env variables

```bash
UPLOADTHING_TOKEN=... # A token for interacting with the SDK
```

<Warning>
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)
</Warning>

## 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
- (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](/file-routes).

```ts {{ title: "app/server/uploadthing.ts" }}
import { createUploadthing } 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 ourFileRouter = {
// Define as many FileRoutes as you like, each with a unique routeSlug
imageUploader: f({ image: { maxFileSize: "4MB" } })
// 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 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.url);
}),
} satisfies FileRouter;

export type OurFileRouter = typeof ourFileRouter;
```

### Create an API route using the FileRouter

<Note>
File path here doesn't matter, you can serve this from any route. We recommend
serving it from `/api/uploadthing`.
</Note>

<Warning>
Make sure to configure API entry handler in `app/api.ts`. For more
information, please refer to the [@tanstack/start
docs](https://tanstack.com/router/latest/docs/framework/react/start/api-routes#setting-up-the-entry-handler).
</Warning>

```ts {{ title: "app/routes/api/uploadthing.ts" }}
import { createAPIFileRoute } from "@tanstack/start/api";

import { createRouteHandler } from "uploadthing/server";

import { ourFileRouter } from "~/api/uploadthing";

const handlers = createRouteHandler({ router: ourFileRouter });

export const Route = createAPIFileRoute("/api/uploadthing")({
GET: handlers,
POST: handlers,
});
```

> See configuration options in
> [server API reference](/api-reference/server#create-route-handler)

## Creating the UploadThing Helpers

Generating the `createUploadThing` helper function lets you create your own
components, with full type safety:

```ts {{ title: "app/utils/uploadthing.ts" }}
import {
generateUploadButton,
generateUploadDropzone,
} from "@uploadthing/react";

import type { OurFileRouter } from "~/api/uploadthing";

const UploadButton = generateUploadButton<OurFileRouter>();
const UploadDropzone = generateUploadDropzone<OurFileRouter>();

export default UploadButton;
```

### Add UploadThing's Styles

<Tabs tabs={["Tailwind", "Not Tailwind"]}>
<Tab>
Wrap your Tailwind config with the `withUt` helper. You can learn more about our
Tailwind helper in the ["Theming" page](/concepts/theming#theming-with-tailwind-css)

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

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

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

```tsx
import "@uploadthing/react/styles.css";
```

</Tab>
</Tabs>

## Mount A Button And Upload!

```tsx {{ title: "app/routes/index.tsx" }}
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](/concepts/theming)

Want to make your own components? Check out our
[useUploadThing hook](/api-reference/react#use-upload-thing)
1 change: 1 addition & 0 deletions docs/src/site-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const navigation: Array<NavGroup> = [
{ title: "Remix", href: "/getting-started/remix" },
{ title: "SolidStart", href: "/getting-started/solid" },
{ title: "SvelteKit", href: "/getting-started/svelte" },
{ title: "Tanstack/Start", href: "/getting-started/tanstack-start" },
{ title: "Vue with Nuxt", href: "/getting-started/nuxt" },
],
},
Expand Down
Loading