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
FormDatainside Edge Runtime and Node.js still lacks in some features.FormDatablobs need to be lazy on the server.zodcurrently 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