# Continue as guest

Let people try your app with one tap on Continue as guest, then keep everything when they add an email address in your app.

**Continue as guest** puts one more button on your sign-in page. One tap makes a real account with no email address, signs the person in, and takes them into your app. It suits an app people should try before they commit, such as a notes or analytics app with a demo workspace. When the person decides to stay, they add an email address inside your app, and the same account, with everything they made as a guest, becomes an ordinary one.

> **Note:**

- A BuildBase plan that includes guest users. Without one, **Guest** shows locked in the console and adding it is refused.
- **Allow public sign-up** on, and **Who may sign up** set to **Anyone**. A guest has no address, so no allowlist or waitlist could name one.
- An email sender, for the code a guest gets when they add their address.



## Step by step

1. In the BuildBase console, press **Users** in the left-hand bar (the **User management** area), then **Authentication** under **Access**, and the **Methods** tab.
2. Press **Add auth method** and choose **Guest**. The **Title** is your own name for the method, shown in the console only. Keep `Continue as guest`. The button your users see always reads "Continue as guest", in the language the page is showing.
3. Press **Create**.

![The Add new method dialog in the console with Guest chosen: what it is for, what else it needs, a Title box reading Continue as guest, a warning that bot protection is off, and the Create button](/images/sign-in-setup/guests/console-add-guest.webp)

The yellow warning shows while [bot protection](/authentication/bot-protection) is off: nothing then checks a new guest, so a script could fill your end-user limit with guests, up to 10 an hour from each network address. Turn bot protection on in the **Security** tab before you go live.

4. Open the **Sign-up** tab and check that **Allow public sign-up** is on.

![The Sign-up tab in the console: the Sign-up card with Allow public sign-up switched on, which Continue as guest needs](/images/sign-in-setup/guests/console-signup-open.webp)

5. Further down the same tab, in **Who may sign up**, choose **Anyone** and press **Save**. In **Allowlist only** or **Waitlist** mode the guest button is hidden.

![The Who may sign up card on the Sign-up tab with the mode set to Anyone, the only mode where the guest button shows](/images/sign-in-setup/guests/console-who-may-sign-up.webp)

6. Open the **Security** tab and find the **Account deletion** card. **Remove idle guests after (days)** is how long a guest can go unused before the account is deleted, from 1 to 365 days. It is 30 unless you change it. Press **Save** if you changed it.

![The Account deletion card on the Security tab: Grace period (days) and Remove idle guests after (days) set to 30, with what each one does](/images/sign-in-setup/guests/console-idle-guests.webp)

"Unused" means the guest's session was not used: the last-seen time moves at most once an hour while it is. A guest who adds an email address is never removed for being idle. A guest who made a workspace that other people joined is kept, as an account deletion would be.

## Attach it to your app

A method shows on the sign-in page only once it is ticked on an app.

1. Open the **Settings** tab and press **Edit** on your app, here **Acme Analytics**.
2. Under **Methods**, tick **Continue as guest**, and press **Update**.

![The Methods list in the Edit auth setting sheet for Acme Analytics, with Email and password and Continue as guest both ticked](/images/sign-in-setup/guests/console-client-methods.webp)

## Check the preview

Open the **Sign-in page** tab. The **Preview** beside the settings shows your look on a sample card. It draws the same sample buttons for every app, so it does not list your methods. To see the real page with the new button, press **Open the live page for Acme Analytics** above the preview.

![The Preview beside the sign-in page settings: an Open the live page for Acme Analytics button above a sample sign-in card with the Acme logo](/images/sign-in-setup/guests/console-preview.webp)

The live page opens in a new tab. **Continue as guest** sits at the bottom of the card, under every way in that keeps an account.

![The live sign-in page for Acme opened from the preview: email and password, then Continue as guest at the bottom of the card](/images/sign-in-setup/guests/live-page-guest-button.webp)

## What people see

On the hosted sign-in page the person presses **Continue as guest** and lands in your app straight away, with no form, no email and no code. The question mark beside the button explains what a guest account is. The page speaks 8 languages, and the button and the note follow the page's language.

![The question mark beside Continue as guest, open: you can use the app without an email address or a password, adding an address later in the app keeps everything, and signing out first loses the guest account](/images/sign-in-setup/guests/hosted-guest-note.webp)

On a phone the button stays under the form:

![The Acme sign-in page on a phone: email and password, Sign in, then Continue as guest with a question mark beside it, and Create account below](/images/sign-in-setup/guests/hosted-phone.webp)

A guest is a real account with a few differences:

- **Named `Guest`, with no address.** Inside the account there is a placeholder address that is never shown and never mailed. No welcome, verification or notification email goes to a guest.
- **Counted as an end user** on your plan. When the plan's end-user limit is reached, Continue as guest is refused.
- **No two-step sign-in, no passkey** and no wallet: those start once the guest adds an address. The sign-in page does not offer a guest a passkey, and the API refuses all three with `409 guest_account`.
- **Signing out loses the account.** A guest has nothing to sign back in with, so tell people to add their address before they leave.

In the console, guests are marked in the **Users** list: the **Email** column reads "None, a guest" and the **Type** column shows a **Guest** badge. The list's filters can show only guests.

![The Users list in the console: Sam Rivera, the former guest, now a Person with an address, a row named Guest with None, a guest in the Email column and a Guest badge as its Type, and the owner](/images/sign-in-setup/guests/console-users-guest.webp)

## In your app (SDK)

A guest turns into a full account from your app, not from the sign-in page. The SDK's settings dialog does it for you: on the **Account** screen a guest sees **Create your account** in place of their email address. The **Security** screen shows the same form in place of the password, phone, two-step and passkey sections. Both come with `@buildbase/sdk` 0.0.90.

1. The guest types an email address, and optionally a name and a password, then presses **Send code**.

![The Account screen of the settings dialog in the app, for a guest: Create your account, with Email, Name (optional) and Password (optional) boxes and a Send code button, in place of the email address](/images/sign-in-setup/guests/sdk-profile-guest.webp)

2. A 6-digit code goes to that address. **Resend** unlocks after 30 seconds.

![Create your account after Send code: We sent a code to sam.rivera@acme.example, a Code from the email box, Create account, and Resend counting down](/images/sign-in-setup/guests/sdk-code-sent.webp)

![The email the guest gets, subject "Your sign-in code for Acme": Hi Sam Rivera, a 6-digit sign-in code that works once and expires in 10 minutes, and when and from where it was asked for](/images/sign-in-setup/guests/email-code.webp)

3. The guest types the code and presses **Create account**. They stay signed in, and the account keeps its user ID and everything they made.

![The Account screen after the code: Your account is ready. You can sign in with sam.rivera@acme.example from now on, and the profile now shows the address](/images/sign-in-setup/guests/sdk-upgraded.webp)

Without a password, the account gets one nobody knows, and **Forgot password?** on the sign-in page sets a real one. Connecting Google or another provider from the Security screen also turns a guest into an account, with the provider's verified address.

To put the same form anywhere in your app, render `GuestUpgrade` for guests:

```tsx
// components/save-your-work.tsx
import { GuestUpgrade, useSaaSAuth } from '@buildbase/sdk/react';

export function SaveYourWork() {
  const { user } = useSaaSAuth();
  if (!user?.isAnonymous) return null;

  return (
    <GuestUpgrade onUpgraded={({ email }) => console.log('Saved', email)} />
  );
}
```

For a form of your own, `useGuestUpgrade()` holds the same steps: `start({ email, name?, password? })`, then `confirm(code)`, with `step`, `pending`, `error` and `waitSeconds` for your buttons. See [Guest users](/authentication/guests#upgrading-in-place).

## Check it works

- [ ] The live page for your app shows **Continue as guest** under the other ways in.
- [ ] Pressing it lands in your app signed in, and the console's **Users** list shows a new row with a **Guest** badge.
- [ ] In your app, the guest's **Account** screen shows **Create your account**.
- [ ] After the code, the same row in **Users** shows the address, and the person can sign in with it.

## Things to watch out for

- **Signing out loses a guest account for good.** A guest has nothing to sign back in with. Show `GuestUpgrade` before people leave, so they add an address first.
- **Guests count toward your end-user limit.** While bot protection is off, a script can make up to 10 guests an hour from each network address. Turn bot protection on before launch.
- **Idle guests are deleted.** A guest unused for 30 days, or the number of days you set, is deleted, unless they made a workspace other people joined.
- **The button needs sign-up open to anyone.** Invite-only, an allowlist or a waitlist hides **Continue as guest**.
- **No email reaches a guest.** No notifications, no two-step sign-in and no wallet until they add an address.

## If something goes wrong

On the sign-in page the refusal shows under "Could not continue as a guest". In your app, `GuestUpgrade` shows the server's sentence.

| What people see                                                                                                                  | Why                                                                            | What to do                                                              |
| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| No Continue as guest button                                                                                                      | The method is not ticked on the app, sign-up is off, or the mode is not Anyone | Tick it on the app, turn on **Allow public sign-up**, choose **Anyone** |
| "Continuing as a guest is not available here."                                                                                   | The app that started the sign-in has no guest method                           | Tick **Continue as guest** on that app                                  |
| "Sign-up is not enabled for this app."                                                                                           | Public sign-up is off, or the mode is not Anyone                               | Change it on the **Sign-up** tab                                        |
| "This app is not taking new sign-ups right now."                                                                                 | Your plan's end-user limit is reached                                          | Raise the plan, or wait for idle guests to be removed                   |
| "Too many guest accounts from this network. Try again later."                                                                    | 10 guests came from one network address in the last hour                       | Wait an hour. Bot protection keeps scripts out before this limit        |
| "The security check expired or did not pass. Please try it again."                                                               | Bot protection did not pass                                                    | Try again                                                               |
| "That email address cannot be used. Try a different one, or if it already has an account here, sign in to that account instead." | The address already has an account in your app, or cannot be used              | Use another address, or sign in to the existing account                 |
| "Sign-up isn't available for this address."                                                                                      | The address is on your blocklist                                               | Use another address, or change the blocklist                            |
| "Please wait 30 seconds before asking for another code." (the number counts down)                                                | A code went out moments ago                                                    | Wait for the countdown                                                  |
| "That code did not match. Check the newest email and try again."                                                                 | A wrong code                                                                   | Use the code in the newest email                                        |
| "This code has expired. Ask for a new one."                                                                                      | 10 minutes passed, or 5 wrong tries                                            | Press **Resend code**                                                   |
| "This account already has an email address."                                                                                     | The person is not a guest any more                                             | Nothing: the account is already full                                    |

## Next steps

- [Guest users](/authentication/guests) - the API behind each step and every refusal.
- [Bot protection](/authentication/bot-protection) - check each new guest.
- [Deleting accounts](/authentication/account-deletion) - the clean-up idle guests go through.
- [Set up sign-in, step by step](/sign-in-setup/overview) - every sign-in guide, and the order to set them up in.
