DEV Community

Cover image for Ship SaaS Faster with Next.js Components
Gaurav Guha
Gaurav Guha

Posted on • Originally published at thefrontkit.com

Ship SaaS Faster with Next.js Components

Every SaaS product needs the same foundation: authentication flows, dashboard layouts, settings pages, forms, tables, and navigation. Building these from scratch costs weeks of development timeβ€”time you could spend on features that differentiate your product.

The SaaS Starter Kit provides production-ready Next.js components for auth, dashboards, settings, and moreβ€”all built with accessibility, responsive design, and token-driven theming.

🎯 What Every SaaS Needs (But Nobody Wants to Build)

Before writing a single line of code, you'll need:

  1. Authentication: Login, signup, password reset, OTP verification
  2. App shell: Sidebar navigation, topbar, user menu
  3. Dashboard: Layouts, cards, charts, data tables
  4. Settings: Account, billing, team management, integrations
  5. Forms: Validation, error handling, loading states
  6. Accessibility: WCAG AA compliance, keyboard navigation

Building these takes 4-6 weeks for an experienced team. The SaaS Starter Kit gives you all of this in days.

πŸ” Building Accessible Authentication Flows

Authentication is the first thing users see, and it needs to be bulletproof. Here's how the SaaS Starter Kit implements login:

import { LoginForm } from '@/components/ui/recipes/authentication/login-form'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import * as z from 'zod'

const loginSchema = z.object({
  email: z.string().email('Please enter a valid email address'),
  password: z.string().min(6, 'Password must be at least 6 characters'),
})

export default function LoginPage() {
  const handleSubmit = async (data: LoginFormData) => {
    // Your auth logic here
    await signIn(data.email, data.password)
  }

  return (
    <div className="min-h-screen flex items-center justify-center">
      <LoginForm
        onSubmit={handleSubmit}
        showSocialLogin={true}
        showSignupLink={true}
        showForgotPasswordLink={true}
        onSocialLogin={(provider) => {
          // Handle OAuth
          signInWithProvider(provider)
        }}
      />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

What You Get Out of the Box

  • βœ… Form validation with Zod and react-hook-form
  • βœ… Error messages that are accessible to screen readers
  • βœ… Social login buttons (Google, Microsoft, Apple)
  • βœ… Loading states during submission
  • βœ… Keyboard navigation for all inputs
  • βœ… Password visibility toggle with proper ARIA labels

πŸ—οΈ Building the App Shell

The app shell is the foundation of your SaaS dashboard. Here's the main sidebar component:

import { MainSidebar } from '@/components/ui/composites/main-sidebar'

export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  const [activeNav, setActiveNav] = React.useState('chat')
  const [activeSection, setActiveSection] = React.useState('account')

  return (
    <div className="flex h-screen">
      <MainSidebar
        activeMainNav={activeNav}
        activeSection={activeSection}
        onMainNavChange={setActiveNav}
        onSectionChange={setActiveSection}
        user={{
          name: 'John Doe',
          email: 'john@example.com',
          avatar: '/avatars/john.jpg',
        }}
        onUpgrade={() => router.push('/pricing')}
      />

      <main className="flex-1 overflow-auto">
        {children}
      </main>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Sidebar Features

  • Main navigation: Chat, Notifications, Profile, Assistant, Settings
  • Settings sub-navigation: Account, Notifications, AI Integrations, Team & Permissions, Billing, Privacy & Security
  • User menu with avatar and upgrade CTA
  • Collapsible sections for mobile
  • Active state management with visual indicators
  • Tooltips for icon-only navigation items

πŸ“Š Building Dashboard Pages

Dashboards need flexible layouts that work across screen sizes. The kit provides composable components:

import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/primitives/card'
import { Button } from '@/components/ui/primitives/button'

export default function DashboardPage() {
  return (
    <div className="p-6 space-y-6">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold">Dashboard</h1>
        <Button action="primary">New Project</Button>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
        <Card>
          <CardHeader>
            <CardTitle>Total Users</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="text-3xl font-bold">1,234</div>
            <p className="text-sm text-muted-foreground">+12% from last month</p>
          </CardContent>
        </Card>

        {/* More cards... */}
      </div>

      <Card>
        <CardHeader>
          <CardTitle>Recent Activity</CardTitle>
        </CardHeader>
        <CardContent>
          {/* Data table or activity feed */}
        </CardContent>
      </Card>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

βš™οΈ Building Settings Pages

Settings pages are complexβ€”they need forms, validation, and clear organization. Here's how the kit structures them:

import { MainSidebar } from '@/components/ui/composites/main-sidebar'
import { AccountSettingsForm } from '@/components/ui/recipes/settings/account-settings-form'

export default function SettingsPage() {
  return (
    <div className="flex">
      <MainSidebar activeMainNav="settings" activeSection="account" />

      <main className="flex-1 p-6">
        <div className="max-w-2xl">
          <h1 className="text-2xl font-bold mb-6">Account Settings</h1>

          <AccountSettingsForm
            initialData={{
              name: 'John Doe',
              email: 'john@example.com',
              company: 'Acme Inc',
            }}
            onSubmit={async (data) => {
              await updateAccount(data)
            }}
          />
        </div>
      </main>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

The settings form includes:

  • Field validation with inline error messages
  • Loading states during save
  • Success/error toasts for user feedback
  • Accessible labels and help text
  • Keyboard shortcuts for common actions

πŸ“ Building Accessible Forms

Forms are everywhere in SaaS apps. The kit provides a consistent form system:

import { Form, FormField, FormLabel, FormMessage } from '@/components/ui/primitives/form'
import { Field, FieldContent, FieldError } from '@/components/ui/primitives/field'
import { Input } from '@/components/ui/primitives/input'

function TeamSettingsForm() {
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(teamSchema),
  })

  return (
    <Form onSubmit={handleSubmit(onSubmit)}>
      <FormField>
        <Field isInvalid={!!errors.teamName}>
          <FieldContent>
            <Input
              {...register('teamName')}
              placeholder="Team name"
              isError={!!errors.teamName}
            />
            {errors.teamName && (
              <FieldError>{errors.teamName.message}</FieldError>
            )}
          </FieldContent>
        </Field>
      </FormField>
    </Form>
  )
}
Enter fullscreen mode Exit fullscreen mode

Form Features

  • Consistent error styling across all inputs
  • Accessible error announcements for screen readers
  • Focus management moves to first error on submit
  • Loading states disable inputs during submission
  • Validation happens on blur and submit

🎨 Token-Driven Design System

The SaaS Starter Kit uses a production-ready design token system:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          50: 'var(--color-primary-50)',
          100: 'var(--color-primary-100)',
          600: 'var(--color-primary-600)',
          700: 'var(--color-primary-700)',
        },
        secondary: {
          100: 'var(--color-secondary-100)',
          200: 'var(--color-secondary-200)',
          // ... more tokens
        },
      },
      spacing: {
        'token-1': 'var(--spacing-token-1)',
        'token-2': 'var(--spacing-token-2)',
        // ... tokenized spacing scale
      },
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

This ensures:

  • Design-code parity: Token definitions translate directly to components
  • Theme consistency: Light/dark mode works automatically
  • Easy customization: Change tokens, update everywhere

πŸ“± Responsive by Default

All components are mobile-responsive out of the box:

// Sidebar collapses on mobile
<MainSidebar className="hidden md:flex" />

// Grid layouts adapt to screen size
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
  {/* Cards stack on mobile, grid on desktop */}
</div>

// Forms stack vertically on mobile
<Form className="space-y-4">
  {/* Fields stack naturally */}
</Form>
Enter fullscreen mode Exit fullscreen mode

βœ… Production Checklist

Before launching, ensure:

  • [ ] Authentication flows handle all edge cases (expired tokens, network errors)
  • [ ] Forms validate on both client and server
  • [ ] Navigation works with keyboard only
  • [ ] Loading states provide feedback for all async operations
  • [ ] Error boundaries catch and display errors gracefully
  • [ ] Mobile experience is polished and touch-friendly
  • [ ] Accessibility passes WCAG AA checks

πŸš€ Get Started Faster

Building these patterns from scratch takes 4-6 weeks. The SaaS Starter Kit gives you:

  • βœ… Pre-built auth flows (login, signup, password reset, OTP)
  • βœ… App shell with sidebar and topbar navigation
  • βœ… Dashboard layouts and components
  • βœ… Settings pages with forms and validation
  • βœ… WCAG AA accessibility built-in
  • βœ… Production-ready design token system
  • βœ… Next.js + Tailwind codebase ready to customize

Explore the SaaS Starter Kit: View components

❓ FAQ

Does it include backend/auth logic?

No. The kit focuses on frontend UI. You'll wire your own auth provider (Auth0, Clerk, Supabase, etc.) or build custom backend logic.

What about payment processing?

The kit includes billing UI components, but you'll integrate your own payment provider (Stripe, Paddle, etc.).

Can I use this for client work?

Yes, with an Agency license. Solo and Team licenses are for internal projects.

How do I customize the styling?

All components use Tailwind classes and design tokens. Modify tokens or add custom classes to match your brand.

Is it compatible with ShadCN/Radix?

Yes! The kit is built on Radix UI primitives for accessibility, similar to ShadCN.

Top comments (0)