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

# Build a SaaS app

> Recipe for building a subscription SaaS in Rocket.new with authentication, team workspaces, Stripe billing, in-app notifications, and role permissions.

export const LlmsDirective = () => <blockquote className="llms-directive">
    For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
    For a lightweight markdown version of this page, append .md to the URL.
  </blockquote>;

<LlmsDirective />

<Info>
  A project management SaaS where teams can create workspaces, organize tasks on Kanban boards, invite collaborators, and upgrade to a paid plan. The finished product includes user authentication, a free tier with limits, a Pro subscription via Stripe checkout, transactional email notifications, and one-click deployment to Netlify.

  By the end of this recipe you will have a production-ready app that you can customize, rebrand, and launch as your own product.
</Info>

## Tech stack

<Note>You do not need to understand these technologies. Rocket handles them automatically. This table is for reference.</Note>

| Service                  | Role                                                   |
| ------------------------ | ------------------------------------------------------ |
| **Next.js + TypeScript** | Frontend framework and API routes                      |
| **Supabase**             | User authentication, PostgreSQL database, file storage |
| **Stripe**               | Subscription billing (free and Pro plans)              |
| **Resend**               | Transactional emails (welcome, invites, receipts)      |
| **Netlify**              | Production deployment and hosting                      |

## Architecture overview

Here is how the pieces connect:

1. A visitor signs up using **Supabase Auth** (email/password or social login).
2. After signup, they land on a dashboard where they can create a **workspace** and start adding **tasks** (stored in Supabase).
3. The workspace owner can **invite team members** by email. Resend delivers the invitation.
4. When the team is ready to unlock higher limits, the owner opens the **pricing page** and completes a **Stripe Checkout** session to subscribe to the Pro plan.
5. Stripe webhooks update the subscription status in Supabase, and Resend sends a receipt email.
6. The entire app is **deployed to Netlify** with environment variables configured for each service.

## How long does it take?

| Phase         | What you are building    | Estimated time    |
| ------------- | ------------------------ | ----------------- |
| Setup         | Project, Supabase, auth  | 5-10 minutes      |
| Core features | Workspaces, tasks, teams | 10-15 minutes     |
| Monetization  | Stripe, pricing, billing | 5-10 minutes      |
| Communication | Email notifications      | 5 minutes         |
| Launch        | Deploy, go live          | 5 minutes         |
| **Total**     | **Complete SaaS app**    | **30-45 minutes** |

## Step-by-step build

<Steps>
  <Step title="Start a new project">
    Open [rocket.new](https://rocket.new) and create a new project. Give Rocket a detailed description of the app so it scaffolds the right pages, layout, and navigation from the start.

    ```plaintext wrap theme={null}
    Build a project management SaaS called "Taskflow" using Next.js and TypeScript. Include these pages: landing page with hero and feature sections, pricing page with Free and Pro tiers, login page, signup page, dashboard with a sidebar, workspace settings page, and a Kanban task board. Use a clean, modern design with a blue and white color scheme. Add a responsive navbar with logo, navigation links, and login/signup buttons.
    ```

    <Tip>
      Be specific about the pages and layout you want in your first prompt. The more detail you give, the less back-and-forth you will need later.
    </Tip>
  </Step>

  <Step title="Connect Supabase">
    Go to **Integrations** in your Rocket project and connect your Supabase account via OAuth. Create a new Supabase project (or select an existing one), then ask Rocket to set up the database schema.

    ```plaintext wrap theme={null}
    Connect Supabase and create the following database tables:
    1. "profiles" - id (uuid, references auth.users), display_name (text), avatar_url (text), created_at (timestamp)
    2. "workspaces" - id (uuid), name (text), owner_id (uuid, references profiles), plan (text, default 'free'), created_at (timestamp)
    3. "workspace_members" - id (uuid), workspace_id (uuid, references workspaces), user_id (uuid, references profiles), role (text, either 'owner', 'admin', or 'member'), invited_at (timestamp), joined_at (timestamp)
    4. "tasks" - id (uuid), workspace_id (uuid, references workspaces), title (text), description (text), status (text, either 'todo', 'in_progress', or 'done'), assignee_id (uuid, references profiles), created_by (uuid, references profiles), position (integer), created_at (timestamp), updated_at (timestamp)
    Add row-level security policies so users can only access data in workspaces they belong to. Create a trigger that automatically inserts a profile row when a new user signs up.
    ```

    <Info>
      Rocket handles the Supabase connection through OAuth, so you never need to copy API keys manually. Your credentials are encrypted and stored securely.
    </Info>
  </Step>

  <Step title="Build the signup and login flow">
    Now wire up authentication so users can create accounts and sign in. This prompt connects Supabase Auth to the signup and login pages that Rocket already scaffolded.

    ```plaintext wrap theme={null}
    Implement user authentication using Supabase Auth:
    - On the signup page, add email/password registration. After successful signup, redirect to the dashboard and show a welcome message.
    - On the login page, add email/password login with a "Remember me" checkbox. Redirect to the dashboard after login.
    - Add a "Forgot password" link on the login page that sends a password reset email via Supabase.
    - Add Google sign-in as a social login option on both pages.
    - Protect the dashboard, workspace, and settings pages so only logged-in users can access them. Redirect unauthenticated visitors to the login page.
    - Add a user menu in the top-right corner of the dashboard with the user's name, avatar, and a sign-out button.
    ```

    <Tip>
      After Rocket builds the auth flow, preview the app and create a test account. Check the Supabase dashboard to confirm the user appeared in the `auth.users` table and that the `profiles` trigger fired.
    </Tip>
  </Step>

  <Step title="Create workspaces and task boards">
    This is the core of the product. Users create a workspace, then manage tasks on a drag-and-drop Kanban board.

    ```plaintext wrap theme={null}
    Build the workspace and task board features:
    - After login, show a "My Workspaces" list on the dashboard. Include a "Create Workspace" button that opens a modal with a name field.
    - When a user creates a workspace, automatically add them as the owner in the workspace_members table.
    - Inside each workspace, show a Kanban board with three columns: To Do, In Progress, and Done.
    - Users can create new tasks with a title and optional description. New tasks start in the "To Do" column.
    - Support drag-and-drop to move tasks between columns. Save the new status and position to Supabase on drop.
    - Each task card should show the title, assignee avatar, and a colored status badge.
    - Clicking a task card opens a detail panel where users can edit the title, description, status, and assignee.
    ```
  </Step>

  <Step title="Add team member invitations">
    Let workspace owners invite collaborators by email. This step introduces the team collaboration flow.

    ```plaintext wrap theme={null}
    Add team invitation functionality:
    - In the workspace settings page, add a "Members" section that lists current members with their role (owner, admin, member).
    - Add an "Invite Member" button that opens a modal with an email field and a role selector (admin or member).
    - When the owner sends an invite, create a pending record in workspace_members with the invited email and role.
    - If the invited person already has an account, show the workspace in their dashboard immediately. If not, they will see it after they sign up with that email address.
    - The workspace owner can remove members or change their role from the members list.
    - Limit the Free plan to 3 members per workspace. Show an upgrade prompt when the owner tries to invite a 4th member.
    ```

    <Info>
      The email notification for invitations will be connected in Step 8 when we add Resend. For now, the invitation logic works through the database.
    </Info>
  </Step>

  <Step title="Connect Stripe for billing">
    Go to **Integrations** and connect Stripe using your **test mode** API keys. Then ask Rocket to build the subscription backend.

    ```plaintext wrap theme={null}
    Connect Stripe and set up subscription billing:
    - Create two Stripe products: "Taskflow Free" (free, no Stripe subscription needed) and "Taskflow Pro" at $19/month.
    - Add a webhook handler that listens for checkout.session.completed, customer.subscription.updated, and customer.subscription.deleted events.
    - When a user completes checkout, update their workspace's plan column in Supabase from 'free' to 'pro'.
    - When a subscription is canceled or expires, revert the plan to 'free'.
    - Store the Stripe customer ID and subscription ID in a new "subscriptions" table linked to the workspace.
    - Add a billing page inside workspace settings that shows the current plan, next billing date, and a "Manage Subscription" button that opens the Stripe Customer Portal.
    ```

    <Tip>
      Use Stripe test mode keys during development. The test card number `4242 4242 4242 4242` with any future expiration and any CVC will simulate a successful payment.
    </Tip>
  </Step>

  <Step title="Create the pricing page">
    Build a public-facing pricing page that drives conversions and handles the checkout redirect.

    ```plaintext wrap theme={null}
    Build the pricing page:
    - Show two plan cards side by side: Free and Pro ($19/month).
    - Free plan features: up to 3 members, 1 workspace, 50 tasks, basic Kanban board.
    - Pro plan features: unlimited members, unlimited workspaces, unlimited tasks, priority support, advanced analytics (coming soon).
    - Highlight the Pro plan as "Most Popular" with a colored border.
    - Add a monthly/yearly toggle. Yearly pricing is $15/month billed annually ($180/year), showing a "Save 21%" badge.
    - The "Get Started" button on the Free plan links to the signup page.
    - The "Upgrade to Pro" button initiates a Stripe Checkout session. If the user is logged in, prefill their email. If not, redirect to signup first.
    - After successful checkout, redirect to the dashboard with a success toast notification.
    ```
  </Step>

  <Step title="Add email notifications with Resend">
    Go to **Integrations** and connect Resend by pasting your API key. Then set up transactional emails for key user actions.

    ```plaintext wrap theme={null}
    Connect Resend and add email notifications:
    - Send a welcome email when a new user signs up. Include the app name, a greeting with their name, and a "Go to Dashboard" button linking to the app.
    - Send an invitation email when a workspace owner invites a new member. Include the workspace name, the inviter's name, their assigned role, and a "Join Workspace" button.
    - Send a payment receipt email after a successful Stripe subscription. Include the plan name, amount, billing period, and a link to the billing page.
    - Send a subscription cancellation confirmation email when a user cancels their Pro plan.
    - Use a clean, minimal email template with the Taskflow logo, a white background, and blue accent buttons.
    ```

    <Info>
      Resend provides a free tier of 100 emails per day, which is plenty for development and early launch. You can upgrade later as your user base grows.
    </Info>
  </Step>

  <Step title="Deploy to Netlify">
    Go to **Integrations** and connect Netlify, then deploy your app to the web.

    Use the **Launch** button in your Rocket project to deploy to the web. Rocket handles the Netlify build configuration automatically. Make sure all required environment variables are set in your project's integration settings before launching.

    <Tip>
      After deploying, update your Supabase redirect URLs to include your app's live URL. Go to your Supabase dashboard, navigate to **Authentication > URL Configuration**, and add `https://your-app.builtwithrocket.new` to the allowed redirect URLs.
    </Tip>
  </Step>

  <Step title="Go live">
    Before sharing your app with real users, swap out all test credentials for production keys.

    * Replace your Stripe **test** API keys with **live** keys in the project environment variables
    * Recreate your Stripe products and prices in live mode (they do not carry over from test mode)
    * Update the Stripe webhook endpoint in the Stripe Dashboard to point to your production URL
    * Customize Supabase email templates with your app's branding and enable email confirmations to prevent spam signups
    * Test the full flow on the production URL: sign up, create a workspace, add a task, invite a member, and complete a real Stripe checkout with a small amount

    <Warning>
      Double-check that your Stripe live webhook secret matches the one in your Netlify environment variables. Mismatched secrets are the most common cause of payment processing failures after launch.
    </Warning>
  </Step>
</Steps>

## Customization ideas

Once the base product is running, here are ways to extend it.

<AccordionGroup>
  <Accordion title="Add analytics with Mixpanel" icon="chart-mixed">
    Track user behavior to understand how people use your app. Instrument events like workspace created, task moved, member invited, and plan upgraded.

    Use Mixpanel funnels to measure your signup-to-paid conversion rate.

    ```plaintext wrap theme={null}
    Connect Mixpanel and add event tracking for: user_signed_up, workspace_created, task_created, task_moved, member_invited, plan_upgraded, and plan_canceled. Add a Mixpanel identify call after login so events are linked to the user profile.
    ```
  </Accordion>

  <Accordion title="Add AI features with OpenAI" icon="robot">
    Let users generate task descriptions, summarize project progress, or get smart suggestions for task assignments using OpenAI.

    ```plaintext wrap theme={null}
    Connect OpenAI and add an "AI Assistant" button on the task board. When clicked, open a panel where users can: generate a task description from a short title, summarize all tasks in a workspace as a progress report, and get suggestions for which team member to assign a task to based on their current workload.
    ```
  </Accordion>

  <Accordion title="Add a public API" icon="code">
    Expose a REST API so power users can automate task creation, query workspace data, or integrate with external tools like Zapier.

    ```plaintext wrap theme={null}
    Create a public REST API with these endpoints:
    - GET /api/v1/workspaces - list user's workspaces
    - GET /api/v1/workspaces/:id/tasks - list tasks in a workspace
    - POST /api/v1/workspaces/:id/tasks - create a new task
    - PATCH /api/v1/tasks/:id - update a task
    - DELETE /api/v1/tasks/:id - delete a task
    Authenticate using Bearer tokens generated from the user settings page. Return JSON responses with proper error codes and pagination.
    ```
  </Accordion>

  <Accordion title="Add an admin dashboard" icon="gauge">
    Build an internal dashboard for yourself to monitor signups, revenue, and usage metrics without leaving the app.

    ```plaintext wrap theme={null}
    Create an admin dashboard at /admin that is only accessible to users with an "admin" role in the profiles table. Show: total users (with a signup chart over the last 30 days), total workspaces, active subscriptions and MRR, and a table of recent signups with email, signup date, and plan status.
    ```
  </Accordion>

  <Accordion title="Add mobile app support" icon="mobile">
    Make the app work well on phones and tablets, or generate a standalone mobile app from your Rocket project.

    ```plaintext wrap theme={null}
    Optimize the entire app for mobile devices. Make the sidebar collapsible with a hamburger menu, ensure the Kanban board scrolls horizontally on small screens, and make all modals full-screen on mobile. Add touch-friendly drag-and-drop for task cards.
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Payments complete but the plan does not update">
    This usually means the Stripe webhook is not reaching your app. Make sure Stripe is connected in your project's **Integrations** panel, then ask Rocket to investigate:

    ```plaintext wrap theme={null}
    Stripe payments are going through but the workspace plan is not updating to "pro" in Supabase. Debug the Stripe webhook handler and make sure it correctly listens for checkout.session.completed events and updates the workspace plan column.
    ```

    Also confirm you are using the correct mode (test vs. live) in both Stripe and your project's environment variables.
  </Accordion>

  <Accordion title="Login redirects to the wrong URL after deployment">
    After deploying, Supabase may still be configured to redirect to your development URL. Ask Rocket to update the auth settings:

    ```plaintext wrap theme={null}
    After deploying, login redirects to localhost instead of my production URL. Update the Supabase auth configuration so the site URL and allowed redirect URLs point to my production Netlify domain.
    ```

    You can also update this directly in your Supabase dashboard under **Authentication > URL Configuration**.
  </Accordion>

  <Accordion title="Emails are not sending">
    First, verify that Resend is connected in your project's **Integrations** panel. If it is connected but emails still are not arriving, ask Rocket to debug:

    ```plaintext wrap theme={null}
    Emails are not being sent through Resend. Check the email sending logic and make sure the Resend API is being called correctly for welcome emails, invitations, and receipts. Add error handling so I can see if the API call is failing.
    ```

    <Tip>
      During development, Resend only delivers to the email address on your Resend account unless you have verified a custom sending domain.
    </Tip>
  </Accordion>

  <Accordion title="Task board or workspace list is empty">
    If the app loads but shows no data, Supabase row-level security policies may be blocking access. Ask Rocket to fix it:

    ```plaintext wrap theme={null}
    The task board and workspace list are empty even though I have created data. Check the Supabase row-level security policies on the workspaces, workspace_members, and tasks tables. Make sure logged-in users can read data for workspaces they belong to.
    ```
  </Accordion>
</AccordionGroup>
