Closed jonybekov closed 1 year ago
Looks like your action function is reposting to the same route. What are you trying to do?
@jonybekov
I made remix and netlify forms work (with some drawbacks)
[your-name].html
file with <form netlify>
element and inputs you are using to public
folder to let netlify bots register your form<Form>
element to your page and create corresponding actionFunction
{ "Content-Type": "application/x-www-form-urlencoded" }
fetch(
${process.env.URL!}/form)
where form
is arbitrary name
netlify.toml
add
[[redirects]]
from = "/form"
to = "/"
status = 200
The idea is to use remix action handler which is run inside netlify function to send form submission.
process.env.URL
is environment variable which has your production site's url (i could not find env variable with actual current deploy url e.g. when having preview build) which i consider a drawback of this solution. Stil default remix setup for netlify has
from = "/*"
to = "/.netlify/functions/server"
status = 200
which will catch your form submission (even when done from action) but adding ABOVE this rule
[[redirects]]
from = "/form"
to = "/"
status = 200
will forward requests to your_url/form
to your_url
and bypass remix serverless function
You can't do a fetch to a URL without host and protocol server-side so fetch("/")
will not work. You need to know the full URL.
Looks like your action function is reposting to the same route. What are you trying to do?
I am trying to send a form data to netlify forms. In the docs it's said that ajax requests should be sent to root page.
I have the same problem but in vercel.
I have the same issue on Fly.io
Same issue on AWS Architect. Here is my code:
import { Form, useActionData, useSubmit } from "@remix-run/react";
import type { ActionArgs } from "@remix-run/node";
import { json } from "@remix-run/node";
import { search } from "~/deepgram.server";
import invariant from "tiny-invariant";
export async function action({ request }: ActionArgs) {
const formData = await request.formData();
const name = formData.get("name");
const privacyCode = formData.get("privacyCode");
const recording = formData.get("recording");
const errors = {
name: name ? null : "Name is required",
privacyCode: privacyCode ? null : "Privacy Code is required",
recording: recording ? null : "Recording is required",
};
invariant(typeof name === "string", "name must be a string");
invariant(typeof privacyCode === "string", "privacyCode must be a string");
const hasErrors = Object.values(errors).some((errorMessage) => errorMessage);
if (hasErrors) {
return json({ errors });
} else {
const buffer = Buffer.from(await recording.arrayBuffer(), "base64");
const confidence = await search(buffer, name, privacyCode);
return json({
confidence,
});
}
}
export default function Index() {
const actionData = useActionData<typeof action>();
const submit = useSubmit();
const handleSubmit = (event: any) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
submit(formData, {
method: "post",
encType: "multipart/form-data",
});
};
return (
<main className="relative min-h-screen bg-white sm:flex sm:items-center sm:justify-center">
<Form method="post" encType="multipart/form-data" onSubmit={handleSubmit}>
<label className="block">
Name
<input name="name" id="name" />
{actionData?.errors?.name ? (
<em className="text-red-600">{actionData?.errors?.name}</em>
) : null}
{actionData?.confidence?.name ? (
<span>{actionData?.confidence?.name}</span>
) : null}
</label>
<label className="block">
Privacy Code
<input name="privacyCode" id="privacyCode" />
{actionData?.errors?.privacyCode ? (
<em className="text-red-600">{actionData?.errors?.privacyCode}</em>
) : null}
{actionData?.confidence?.privacyCode ? (
<span>{actionData?.confidence?.privacyCode}</span>
) : null}
</label>
<label className="block">
Recording
<input
type="file"
accept="audio/*"
capture
name="recording"
id="recording"
/>
</label>
<button type="submit">Submit</button>
</Form>
</main>
);
}
Update: I discovered that there was actually an error being thrown on the server. (Due to a missing environment variable, but presumably any error would have caused the same result). Perhaps there is a better way of letting these error messages get through when they happen? Or at least some better error message that gives an idea of what went wrong.
Server logs should have the real error, we remove the stack in production so nothing sensitive is revealed to clients.
What version of Remix are you using?
1.1.3
Steps to Reproduce
name="contact-form" action="/" method="post" className="w-full" data-netlify="true"
.Add action handler to index page.
Expected Behavior
Form should be submitted successfully.
Actual Behavior