Skip to content

SolidJS Form Submission

Submit forms in your SolidJS application using reactive signals and standard asynchronous fetch().

Here is a form component utilizing SolidJS’s createSignal to manage input states and submission status:

import { createSignal, Show } from 'solid-js';
interface Props {
apiUrl: string;
}
export default function SolidForm(props: Props) {
const [name, setName] = createSignal('');
const [email, setEmail] = createSignal('');
const [message, setMessage] = createSignal('');
const [status, setStatus] = createSignal<'idle' | 'sending' | 'success' | 'error'>('idle');
const [errorText, setErrorText] = createSignal('');
const handleSubmit = async (e: Event) => {
e.preventDefault();
setStatus('sending');
setErrorText('');
try {
const res = await fetch(props.apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify({ name: name(), email: email(), message: message() }),
});
const json = await res.json();
if (res.ok) {
setStatus('success');
setName('');
setEmail('');
setMessage('');
} else {
setStatus('error');
setErrorText(json.error || 'Something went wrong.');
}
} catch {
setStatus('error');
setErrorText('Network error. Please try again.');
}
};
return (
<form onSubmit={handleSubmit} class="space-y-4">
<div>
<label for="solid-name">Name</label>
<input
id="solid-name"
type="text"
value={name()}
onInput={(e) => setName(e.currentTarget.value)}
required
/>
</div>
<div>
<label for="solid-email">Email</label>
<input
id="solid-email"
type="email"
value={email()}
onInput={(e) => setEmail(e.currentTarget.value)}
required
/>
</div>
<div>
<label for="solid-message">Message</label>
<textarea
id="solid-message"
value={message()}
onInput={(e) => setMessage(e.currentTarget.value)}
required
/>
</div>
<button type="submit" disabled={status() === 'sending'}>
{status() === 'sending' ? 'Sending...' : 'Send Message'}
</button>
<Show when={status() === 'success'}>
<p class="text-green-600">Message sent successfully!</p>
</Show>
<Show when={status() === 'error'}>
<p class="text-red-600">{errorText()}</p>
</Show>
</form>
);
}