You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/how-to/file-uploads.md
+27-10Lines changed: 27 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,17 +1,33 @@
1
1
---
2
2
title: File Uploads
3
-
# need to validate this guide and get rid of remixisms like file system routes
4
-
hidden: true
5
3
---
6
4
7
5
# File Uploads
8
6
9
7
Handle file uploads in your React Router applications. This guide uses some packages from the [Remix The Web][remix-the-web] project to make file uploads easier.
10
8
11
-
_Thank you to David Adams for [his original guide](https://programmingarehard.com/2024/09/06/remix-file-uploads-updated.html/)on how to implement file uploads in Remix. You can refer to it for even more examples._
9
+
_Thank you to David Adams for [writing an original guide](https://programmingarehard.com/2024/09/06/remix-file-uploads-updated.html/)which this doc is based on. You can refer to it for even more examples._
12
10
13
11
## Basic File Upload
14
12
13
+
👉 **Setup some routes**
14
+
15
+
You can setup your routes however you like. This example uses the following structure:
16
+
17
+
```ts filename=routes.ts
18
+
import {
19
+
typeRouteConfig,
20
+
route,
21
+
} from"@react-router/dev/routes";
22
+
23
+
exportdefault [
24
+
// ... other routes
25
+
route("user/:id", "pages/user-profile.tsx", [
26
+
route("avatar", "api/upload-avatar.tsx"),
27
+
]),
28
+
] satisfiesRouteConfig;
29
+
```
30
+
15
31
👉 **Add the form data parser**
16
32
17
33
`form-data-parser` is a wrapper around `request.formData()` that provides streaming support for handling file uploads.
@@ -32,7 +48,7 @@ You must set the form's `enctype` to `multipart/form-data` for file uploads to w
32
48
33
49
</docs-warning>
34
50
35
-
```tsx filename=routes/user.$id.tsx
51
+
```tsx filename=pages/user-profile.tsx
36
52
import {
37
53
typeFileUpload,
38
54
parseFormData,
@@ -57,10 +73,10 @@ export async function action({
57
73
58
74
exportdefaultfunction Component() {
59
75
return (
60
-
<Formmethod="post"encType="multipart/form-data">
76
+
<formmethod="post"encType="multipart/form-data">
61
77
<inputtype="file"name="avatar" />
62
78
<button>Submit</button>
63
-
</Form>
79
+
</form>
64
80
);
65
81
}
66
82
```
@@ -97,7 +113,7 @@ export function getStorageKey(userId: string) {
97
113
98
114
Update the form's `action` to store files in the `fileStorage` instance.
99
115
100
-
```tsx filename=routes/user.$id.tsx
116
+
```tsx filename=pages/user-profile.tsx
101
117
import {
102
118
FileUpload,
103
119
parseFormData,
@@ -106,7 +122,7 @@ import {
106
122
fileStorage,
107
123
getStorageKey,
108
124
} from"~/avatar-storage.server";
109
-
importtype { Route } from"./+types/user";
125
+
importtype { Route } from"./+types/user-profile";
110
126
111
127
exportasyncfunction action({
112
128
request,
@@ -165,11 +181,12 @@ export default function UserPage({
165
181
166
182
Create a [resource route][resource-route] that streams the file as a response.
0 commit comments