Skip to content

Commit

Permalink
docs: New blog about Progressive Forms (#1195)
Browse files Browse the repository at this point in the history
progressive forms post

TODO

- [x] Update the date before merging

---------

Co-authored-by: Tyler <[email protected]>
  • Loading branch information
tylersayshi and tylersayshi authored Feb 20, 2025
1 parent 1055735 commit 29af481
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
66 changes: 66 additions & 0 deletions packages/website/private/contents/post-007.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
slug: progressive-forms
title: Progressive forms
description: Forms work without JavaScript!
author: tyler
date: 2025/02/20
---

Remember the last time you submitted a form that did nothing?

We can fix that!

## What does this look like?

Before React 19 and server actions, a basic form might look like this:

```jsx
'use client';

const ClientForm = () => {
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
await fetch('/api/submit', {
method: 'POST',
body: JSON.stringify(Object.fromEntries(formData)),
});
};

return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" required />
<input name="password" type="password" required />
<button type="submit">Submit</button>
</form>
);
};
```

This is just fine, but if we want our form to run in an environment without JavaScript or we just want to optimize the form to not need to render on the client, there is a new pattern available.

## Introducing progressive forms with server actions

The form below works without JavaScript, which is helpful for making your forms immediately interactive. In slow network conditions, for example, a user can now submit the form even before the JavaScript loads.

```jsx
async function submitForm(formData) {
'use server';
await fetch('https://api.example.com/submit', {
method: 'POST',
body: JSON.stringify(Object.fromEntries(formData)),
});
}

const ServerForm = () => {
return (
<form action={submitForm}>
<input name="email" type="email" required />
<input name="password" type="password" required />
<button type="submit">Submit</button>
</form>
);
};
```

We can sprinkle in some JavaScript where it can be helpful like for client-side validation or for showing errors from the server. The key point though is that the form will always submit and pair with your server action regardless of whether JavaScript had loaded or not.
17 changes: 16 additions & 1 deletion packages/website/src/lib/get-author.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
export const getAuthor = (author: string) => {
type Author = {
name: string;
biography: string;
avatar: string;
url: string;
};

export const getAuthor = (author: string): Author => {
switch (author) {
case 'daishi':
return {
Expand All @@ -14,11 +21,19 @@ export const getAuthor = (author: string) => {
avatar: `https://cdn.candycode.com/waku/sophia.png`,
url: `https://x.com/razorbelle`,
};
case 'tyler':
return {
name: 'Tyler Lawson',
biography: 'senior engineer at second spectrum',
avatar: 'https://avatars.githubusercontent.com/u/26290074',
url: 'https://tylur.dev',
};
default:
return {
name: ``,
biography: ``,
avatar: ``,
url: '',
};
}
};

0 comments on commit 29af481

Please sign in to comment.