How to Integrate LoginForm, RegisterForm, and ForgotPasswordForm in refine-shadcn

To integrate the authentication forms in refine-shadcn, install the @ferdiunal/refine-shadcn-auth package, initialize the auth provider using createRefineAuthProvider, and import the pre-built form components into your route pages.

The refine-shadcn repository provides a complete authentication UI layer built on top of shadcn-ui, react-hook-form, and Zod. This guide walks you through wiring the LoginForm, RegisterForm, and ForgotPasswordForm components into a Refine application using the actual source implementation from packages/auth/src/components/.

Install the Authentication Package

First, add the auth package to your project. This installs the form components and the underlying better-auth integration.

npm install @ferdiunal/refine-shadcn-auth

Initialize the Refine Auth Provider

Before using the forms, you must create a Refine-compatible auth provider. The createRefineAuthProvider factory in packages/auth/src/providers/refine-auth-provider.tsx implements all required methods (login, logout, check, register, forgotPassword) using better-auth under the hood.

Create your auth provider file:

// src/authProvider.ts
import { createRefineAuthProvider } from "@ferdiunal/refine-shadcn-auth";
import { AuthProvider } from "@refinedev/core";

export const authProvider: AuthProvider = createRefineAuthProvider();

Then wrap your application with the AuthProvider context and pass the provider to <Refine>:

// src/main.tsx
import { Refine } from "@refinedev/core";
import { AuthProvider as AuthContextProvider } from "@ferdiunal/refine-shadcn-auth";
import { authProvider } from "./authProvider";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <AuthContextProvider>
    <Refine authProvider={authProvider} /* other props */ />
  </AuthContextProvider>
);

Implement the Authentication Forms

With the provider initialized, you can now import the form components from packages/auth/src/components/. Each form uses react-hook-form for state management and Zod for validation, exposing a consistent prop interface.

All three forms accept these props:

  • onSubmit: Callback receiving validated form data
  • loading: Boolean to disable inputs and show loading states
  • className: Optional CSS classes
  • defaultValues: Optional default form values

LoginForm

The LoginForm component in packages/auth/src/components/login-form.tsx renders email and password fields with validation against the loginSchema.

import { LoginForm } from "@ferdiunal/refine-shadcn-auth";
import { useAuth } from "@ferdiunal/refine-shadcn-auth";

export const LoginPage = () => {
  const { login } = useAuth();

  const handleLogin = async (data: { email: string; password: string }) => {
    await login(data);
  };

  return (
    <LoginForm 
      onSubmit={handleLogin} 
      loading={false} 
    />
  );
};

RegisterForm

The RegisterForm in packages/auth/src/components/register-form.tsx handles name, email, password, and confirm password fields. It supports an optional terms acceptance checkbox via the termsRequired prop.

import { RegisterForm } from "@ferdiunal/refine-shadcn-auth";
import { useAuth } from "@ferdiunal/refine-shadcn-auth";

export const RegisterPage = () => {
  const { register } = useAuth();

  const handleRegister = async (data: {
    name: string;
    email: string;
    password: string;
    confirmPassword: string;
    acceptTerms?: boolean;
  }) => {
    await register(data);
  };

  return (
    <RegisterForm
      onSubmit={handleRegister}
      loading={false}
      termsRequired
    />
  );
};

ForgotPasswordForm

The ForgotPasswordForm in packages/auth/src/components/forgot-password-form.tsx provides a single email field for password reset requests. It includes optional navigation back to the login page.

import { ForgotPasswordForm } from "@ferdiunal/refine-shadcn-auth";
import { useAuth } from "@ferdiunal/refine-shadcn-auth";
import { useNavigate } from "react-router-dom";

export const ForgotPasswordPage = () => {
  const { forgotPassword } = useAuth();
  const navigate = useNavigate();

  const handleForgot = async (data: { email: string }) => {
    await forgotPassword(data);
    navigate("/login");
  };

  return (
    <ForgotPasswordForm
      onSubmit={handleForgot}
      loading={false}
      backToLoginEnabled
      onBackToLogin={() => navigate("/login")}
    />
  );
};

Add the AuthLayout Wrapper (Optional)

For a complete authentication page experience, wrap your forms with the AuthLayout component from packages/auth/src/components/auth-layout.tsx. This provides a responsive two-column layout with a logo, title, subtitle, and background image support.

import { AuthLayout, LoginForm } from "@ferdiunal/refine-shadcn-auth";
import { useAuth } from "@ferdiunal/refine-shadcn-auth";

export const LoginPage = () => {
  const { login } = useAuth();

  return (
    <AuthLayout
      title="My Application"
      subtitle="Sign in to access your dashboard"
      backgroundImage="/images/auth-bg.jpg"
    >
      <LoginForm onSubmit={login} loading={false} />
    </AuthLayout>
  );
};

Complete Routing Example

Here is a minimal router configuration using React Router that ties all three forms together:

// src/AppRoutes.tsx
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { LoginPage } from "./pages/login";
import { RegisterPage } from "./pages/register";
import { ForgotPasswordPage } from "./pages/forgot-password";

export const AppRoutes = () => (
  <BrowserRouter>
    <Routes>
      <Route path="/login" element={<LoginPage />} />
      <Route path="/register" element={<RegisterPage />} />
      <Route path="/forgot-password" element={<ForgotPasswordPage />} />
    </Routes>
  </BrowserRouter>
);

Summary

  • Install the @ferdiunal/refine-shadcn-auth package to get pre-built authentication UI components.
  • Initialize the auth layer by creating a provider with createRefineAuthProvider and wrapping your app with <AuthContextProvider>.
  • Import LoginForm, RegisterForm, and ForgotPasswordForm from the package and connect them to useAuth hooks (login, register, forgotPassword).
  • Optionally wrap forms in AuthLayout for a complete full-screen authentication experience with branding support.

Frequently Asked Questions

How do I customize the validation schemas for the authentication forms?

The forms use Zod schemas defined in the source files (loginSchema, registerSchema, forgotPasswordSchema). To customize validation, you can fork the component source from packages/auth/src/components/ or wrap the forms and add additional validation logic in your onSubmit handler before calling the auth methods.

Can I use these forms without the Refine framework?

While the forms are designed for Refine, they are React components that accept onSubmit callbacks. However, the useAuth hook and AuthProvider context are specific to the @ferdiunal/refine-shadcn-auth package, which expects a Refine-compatible auth provider structure. For non-Refine apps, you would need to reimplement the context providers.

Where are the form styles defined?

The forms rely on shadcn-ui components (Button, Card, Input) imported from the theme package. The styling uses Tailwind CSS classes defined in packages/theme/src/ui/. You can override styles by passing className props to the forms or by customizing the shadcn-ui component registry in your project.

How do I handle authentication errors in the forms?

The useAuth hook methods (login, register, forgotPassword) return promises that reject on failure. Wrap your onSubmit handlers in try/catch blocks to capture errors and display them using your preferred UI (toast notifications, inline alerts, etc.). The forms themselves do not internally display API error messages, leaving error handling flexible for your implementation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →