React Tailwind Login Page Template

Most React Tailwind login templates suffer from duplicated code, poor state management, or missing TypeScript support. In this guide, you’ll get:

✅ A TypeScript-first implementation for type safety

✅ Reusable Input and Button components to slash redundancy

✅ Production-ready features like loaders, error handling, and simulated API calls

Preview of the React Tailwind Sign in Page

React tailwind sign in page

Main Login Page Component

To make the component scalable and modular, this login page relies on three components:

  1. Input Component
  2. Button Component
  3. Dummy Logo

You can find the code for all these components below.

Login to Flexy UI

New here? Sign up

Key Features of React Tailwind Login Page

1. Reusable Components

3. Loader Spinner & Error Handling

Mimic API calls with setTimeout and display user-friendly errors.

3. TypeScript Safety

Strongly typed props for inputs and buttons prevent runtime errors.

File Structure

src/
├─ components/

│ ├─ Input.tsx # Reusable input component
│ └─ Button.tsx # Button with loader

└─ LoginPage.tsx # Main form UI

1. Reusable Input Component

1import { ChangeEvent, FC } from 'react' 2 3interface InputProps { 4 type: 'text' | 'number' | 'email' | 'password' 5 label?: string 6 value: string | number 7 name: string 8 placeholder: string 9 error?: string 10 disabled?: boolean 11 onChange: (e: ChangeEvent<HTMLInputElement>) => void 12 icon?: React.ReactNode 13} 14 15const Input: React.FC<InputProps> = ({ 16 type, 17 name, 18 disabled, 19 placeholder, 20 label, 21 value, 22 onChange, 23 error, 24 icon, 25 ...props 26}) => { 27 return ( 28 <div className="mb-6"> 29 {label && ( 30 <label htmlFor={label} className="mb-1.5 block text-sm font-medium text-[#344054]"> 31 {label} 32 </label> 33 )} 34 <div className="relative flex items-center"> 35 {icon && <span className="absolute left-3 text-[#667085]">{icon}</span>} 36 <input 37 type={type} 38 name={name} 39 id={label} 40 placeholder={placeholder} 41 value={value} 42 onChange={onChange} 43 disabled={disabled} 44 className={`w-full rounded-lg border border-[#D0D5DD] px-4 py-2.5 pl-10 text-gray-700 placeholder:text-[#667085] focus:border-blue-200 focus:outline-none focus:ring-2 focus:ring-blue-200 ${ 45 error && 'ring-2 ring-red-200' 46 }`} 47 {...props} 48 /> 49 </div> 50 {error && <p className="ml-3 mt-1 block text-sm text-red-600">{error}</p>} 51 </div> 52 ) 53} 54 55export default Input

What It Does:

2. Loading Spinner Button Component

1import { LoaderCircle } from 'lucide-react' 2import React from 'react' 3 4type ButtonProps = { 5 text: string 6 loading?: boolean 7 disabled?: boolean 8} 9 10const Button: React.FC<ButtonProps> = ({ text, loading = false, disabled }) => { 11 return ( 12 <button 13 className="w-full cursor-pointer rounded-lg border border-neutral-800 bg-neutral-800 px-4 py-2 text-white hover:border-gray-700 hover:bg-gray-900 disabled:cursor-not-allowed disabled:bg-gray-300 disabled:text-gray-500" 14 type="submit" 15 disabled={disabled} 16 > 17 {!loading ? ( 18 text 19 ) : ( 20 <LoaderCircle className="inline-block animate-spin text-center" color="#fff" /> 21 )} 22 </button> 23 ) 24} 25 26export default Button

What It Does:

3. Dummy Logo

1const DummyLogo = () => ( 2 <div className="mb-4 flex justify-center"> 3 <span className="text-3xl font-bold text-yellow-500"></span> 4 </div> 5)

What It Does:

Feel free to use this code in your project.


Flexy UI Newsletter

Build better and faster UIs.Get the latest Tailwind UI components directly in your inbox. No spam!