> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formbase.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SPA Handling

> Handle Formbase submissions in single-page apps without full-page redirects.

Single-page apps often want to stay on the current route and show an inline success message. Formbase returns a `303` redirect for browser submissions, so you should prevent the browser from following it and handle the result manually.

There are two recommended patterns:

1. Client-side fetch with `redirect: 'manual'`
2. Server-side submit (API route or server action)

<Steps>
  <Step title="Client-side fetch">
    <Tabs>
      <Tab title="React">
        ```tsx theme={null}
        const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
          method: 'POST',
          body: new FormData(event.currentTarget),
          redirect: 'manual',
        });

        if (response.status === 303 || response.ok) {
          setStatus('Submitted!');
        }
        ```
      </Tab>

      <Tab title="Vue">
        ```js theme={null}
        const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
          method: 'POST',
          body: new FormData(event.currentTarget),
          redirect: 'manual',
        });

        status.value = response.status === 303 || response.ok
          ? 'Submitted!'
          : 'Failed.';
        ```
      </Tab>

      <Tab title="Svelte">
        ```js theme={null}
        const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
          method: 'POST',
          body: new FormData(event.currentTarget),
          redirect: 'manual',
        });

        status = response.status === 303 || response.ok
          ? 'Submitted!'
          : 'Failed.';
        ```
      </Tab>
    </Tabs>

    `redirect: 'manual'` prevents the browser from following the redirect and failing CORS checks.
  </Step>

  <Step title="Server-side submit">
    Post to Formbase from your backend (API route, server action, or serverless function). This returns JSON and avoids browser redirects entirely.
  </Step>
</Steps>

<Callout type="note">
  If you use a server action (Next.js, Remix), you get a JSON response from Formbase and can return a clean success state to the client.
</Callout>
