next-fetch
next-fetch copied to clipboard
RFC: multipart/form-data
Summary
Currently the Form.encType
has no effect when using @next-fetch/swr/form
.
Enabling encTypes like multipart/form-data
would allow all kinds of common features like File Uploads.
Basic example
File: pages/file-upload.tsx
export default function MyImageUpload() {
const mutation = useImageUpload();
return (
<Form encType="multipart/form-data" mutation={mutation}>
<input type="file" name="someFile" accept="image/*" />
<button type="submit">Submit</button>
</Form>
);
}
File: pages/api/image.swr.ts
import { zfd } from "zod-form-data";
export const useImageUpload = mutation(
zfd.formData({ someFile: zfd.file() }),
async (formData) => {
const file: File = formData.get('someFile')
// ...
return { message: "Success" };
}
);
Motivation
Today next-fetch only supports application/x-www-form-urlencoded
forms. These forms are quite limited, since they only allow structured string data.
Adding multipart/form-data
support, would allow sending all kind of hybrid data (strings, blobs, etc) to the server while still being able to support native html forms (hookResponse
).
Challenges
-
FormData
inside Edge Runtime and Node.js still lacks in some features. -
FormData
blobs need to be lazy on the server. -
zod
currently doesn't support ES Maps afaik. Nevertheless zod-form-data can help here. - ...to be continued
Adoption strategy
The type definition of @next-fetch/swr/form
element should be updated for the time multipart/form-data
is not supported, otherwise a breaking change will be needed when the feature has been implemented.
export function Form<Data, Error>({
mutation,
mutationConfig,
...props
}: React.HTMLProps<HTMLFormElement> &
React.PropsWithChildren<{
mutation: HookWithFormSubmission<Data, Error>;
mutationConfig?: SWRMutationConfiguration<Data, Error>;
+ encType?: 'application/x-www-form-urlencoded'
}>) {
const { formProps } = useForm(mutation, mutationConfig);
return createElement("form", { ...formProps, ...props }, props.children);
}
Later this feature can be allowed by adding multipart/form-data
to the encType
union.
export function Form<Data, Error>({
mutation,
mutationConfig,
...props
}: React.HTMLProps<HTMLFormElement> &
React.PropsWithChildren<{
mutation: HookWithFormSubmission<Data, Error>;
mutationConfig?: SWRMutationConfiguration<Data, Error>;
- encType?: 'application/x-www-form-urlencoded'
+ encType?: 'application/x-www-form-urlencoded' | 'multipart/form-data'
}>) {
const { formProps } = useForm(mutation, mutationConfig);
return createElement("form", { ...formProps, ...props }, props.children);
}
Links
- https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData?retiredLocale=de
- https://www.npmjs.com/package/zod-form-data
- https://xhr.spec.whatwg.org/#dom-formdata