The LoadingButton component runs one async action and reports on it in place: it swaps to a spinner while the request is open, confirms with a tick when it resolves, and returns to its resting label on its own.
For any button that fires a request, whether that is submitting a form, saving a draft or sending an invite. It owns the busy state itself, which closes the two bugs a hand-rolled version usually ships with: a second click landing while the first request is still open, and the spinner never clearing when the request fails. Reach for it only where the work is genuinely asynchronous; on an instant action the success tick appears and vanishes so fast it reads as a glitch. For a toggle that flips between two settled states rather than performing work, use Subscribe Button instead.
Add it with the CLI, open it in v0, or copy the source into your project.
Everything Loading Button accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
| children (required) | React.ReactNode | No default | Resting label, shown when the button is idle |
| onAction | () => void | Promise<void> | No default | The work to run on click. The button stays busy until it settles, and returns to idle if it rejects |
| loadingText | string | Saving | Label shown while the action is in flight |
| successText | string | Saved | Label shown briefly once the action resolves |
| successDuration | number | 1.6 | Seconds the success label stays up before the button returns to idle |
| className | string | '' | Additional CSS classes for styling |
| ...props | ButtonHTMLAttributes | No default | Any other native button props, including onClick, type and disabled |
Required.