snow-uiProhome

Template guides

A template is a set of pages, the provider they share and an adapter to your backend. You mount the pages on your own routes.

The templates

  • Auth & onboarding: npx shadcn@latest add @snow-ui-pro/auth, and its mock backend @snow-ui-pro/mock-auth.
  • SaaS settings & billing: npx shadcn@latest add @snow-ui-pro/settings, and its mock backend @snow-ui-pro/mock-settings.
  • Commerce admin: npx shadcn@latest add @snow-ui-pro/commerce, and its mock backend @snow-ui-pro/mock-commerce.
  • CRM: npx shadcn@latest add @snow-ui-pro/crm, and its mock backend @snow-ui-pro/mock-crm.
  • Analytics: npx shadcn@latest add @snow-ui-pro/analytics, and its mock backend @snow-ui-pro/mock-analytics.

How every template is mounted

  1. Add the template, and its mock backend to try the pages before yours is ready. The template brings its pages, blocks and the snow-ui components they use.
  2. Put the template’s provider (AuthTemplateProvider, SettingsTemplateProvider…) in the layout that wraps its routes. It is a client component and takes the adapter, your router’s navigate and link component, and your routes (each has a default).
  3. Add one route per page that renders the page component with its data: the guide of each template lists the pages, their props and suggested routes.
  4. Replace the mock adapter with your own: its interface is in components/snow-ui-pro/lib/<template>-types.ts, and each guide describes it.

Templates never call the network themselves and don’t depend on a framework: the guides show the Next.js App Router, and the same components work with any router.

React Router (Vite)

A Vite app needs Tailwind CSS v4 (the @tailwindcss/vite plugin) and the @ import alias in vite.config.ts and tsconfig.json before shadcn init, as in the shadcn/ui guide for Vite. Then follow the installation. Pass React Router’s link to the templates:

tsx
// src/router-link.tsx
import { Link } from 'react-router'
import type { LinkComponent } from '@/components/snow-ui-pro/lib/navigation'

/** The templates render their links with your router's link. */
export const RouterLink: LinkComponent = ({ href, ...props }) => (
  <Link to={href} {...props} />
)

The provider goes in a layout route, around an <Outlet />; navigate is React Router’s:

tsx
// src/auth.tsx — a layout route with the provider, one route per page
import { useMemo } from 'react'
import { Outlet, useNavigate } from 'react-router'
import { SnowUIProvider } from '@/components/snow-ui/components/SnowUIProvider/SnowUIProvider'
import { createMockAuthAdapter } from '@/components/snow-ui-pro/mock/auth' // or your AuthAdapter
import { AuthTemplateProvider } from '@/components/snow-ui-pro/templates/auth/AuthTemplate'
import { RouterLink } from './router-link'

export function AuthLayout() {
  const navigate = useNavigate()
  const adapter = useMemo(() => createMockAuthAdapter(), [])
  return (
    <SnowUIProvider>
      <AuthTemplateProvider
        adapter={adapter}
        navigate={navigate}
        linkAs={RouterLink}
        routes={{ app: '/' }}
      >
        <Outlet />
      </AuthTemplateProvider>
    </SnowUIProvider>
  )
}

Pages that take URL values read them with useParams and useSearchParams where Next.js passes params and searchParams:

tsx
// src/App.tsx (main.tsx wraps <App /> in <BrowserRouter>)
import { Route, Routes, useParams, useSearchParams } from 'react-router'
import { OnboardingPage } from '@/components/snow-ui-pro/templates/auth/OnboardingPage'
import { PasswordResetPage } from '@/components/snow-ui-pro/templates/auth/PasswordResetPage'
import { SignInPage } from '@/components/snow-ui-pro/templates/auth/SignInPage'
import { SignUpPage } from '@/components/snow-ui-pro/templates/auth/SignUpPage'
import { AuthLayout } from './auth'

function ResetPassword() {
  const [params] = useSearchParams()
  return <PasswordResetPage token={params.get('token') ?? undefined} />
}

function Onboarding() {
  const { step = 'about-you' } = useParams()
  return <OnboardingPage step={step} />
}

export default function App() {
  return (
    <Routes>
      <Route element={<AuthLayout />}>
        <Route path="sign-in" element={<SignInPage />} />
        <Route path="sign-up" element={<SignUpPage />} />
        <Route path="reset-password" element={<ResetPassword />} />
        <Route path="onboarding/:step" element={<Onboarding />} />
        {/* …verify, two-factor, two-factor/setup: the guide lists them */}
      </Route>
    </Routes>
  )
}

Without server rendering, what the Next.js layouts read on the server is read in the browser: the sidebar state with readSidebarState(document.cookie) (from components/snow-ui/components/Sidebar/sidebar-cookie), and now from new Date().