Table of Contents
React Authentication with Supabase
- Intro & Demo
- Setting Up React Project
- Creating SignUp Form
- SignUp User
- Route Between Pages
- Log the user in
- Navigate To Homepage
- Logout
React CRUD Operations with Supabase
- Intro
- Setup React and Supabase
- Fetch Users (READ)
- Create User (CREATE)
- Delete User (DELETE)
- Update User (UPDATE)
1 Setup React Project
Git Workflow Example: Initial Commit and Push
Initial Status Check
PS C:\Users\capta\proj\React-Auth-Supa> git status On branch main No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) nothing added to commit but untracked files present (use "git add" to track)
Adding Files and Committing
PS C:\Users\capta\proj\React-Auth-Supa> git add . PS C:\Users\capta\proj\React-Auth-Supa> git commit -m "docs: readme.md file" [main (root-commit) 04e1abe] docs: readme.md file 1 file changed, 1 insertion(+) create mode 100644 README.md
Pushing to Remote
PS C:\Users\capta\proj\React-Auth-Supa> git push -u origin main Enumerating objects: 3, done. Writing objects: 100% (3/3), 261 bytes | 261.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 * [new branch] main -> main branch 'main' set up to track 'origin/main'.
Updating the README
PS C:\Users\capta\proj\React-Auth-Supa> git add . PS C:\Users\capta\proj\React-Auth-Supa> git commit -m "docs: added description" [main 3bf09c5] docs: added description 1 file changed, 1 insertion(+) PS C:\Users\capta\proj\React-Auth-Supa> git push Enumerating objects: 5, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/krashautomation/React-Auth-Supa.git 04e1abe..3bf09c5 main -> main
Key Takeaways
- Initial Setup: Shows the complete workflow from first commit to push
- Conventional Commits: Using
docs:prefix for documentation changes - Branch Tracking: Setting upstream with
-u origin main
2. Creating your Vite Project
Adding Vite to an Existing Project? Don't Miss This Critical Detail
That innocent-looking dot at the end of your Vite command changes everything. Let's break it down:
🆕 Without the Dot
npm create vite@latest
→ Creates a new folder called vite-project
→ Perfect for fresh projects
└── vite-project/ ← Brand new folder
├── src/
└── package.json
🔄 With the Dot
npm create vite@latest .
→ Injects Vite directly into your current folder
→ What you want for existing projects
├── src/ (new)
├── package.json (merged)
└── existing-files (kept)
⚠️ Pro Tip
When using the dot version:
- Vite may ask to overwrite files
- Never blindly accept - manually merge:
- Keep your existing
package.jsonscripts - Preserve custom configs
- Only add Vite-specific changes
- Keep your existing
🎚 Side-by-Side Comparison
vite@latest |
vite@latest . |
|
|---|---|---|
| New folder | ✓ | ✗ |
| Modifies current dir | ✗ | ✓ |
| Conflict risk | None | High |
🏁 The Right Choice
For existing projects:
Then carefully merge files. Your future self will thank you.
(Tip: Use monospace font for code blocks and bright accent colors for commands on dark backgrounds.)
Git Workflow: Multiple File Changes
Option 1: Atomic Commits (Recommended)
Separate commits for logically distinct changes:
# Stage and commit each change separately
git add file1.js
git commit -m "feat: add user authentication"
git add file2.css
git commit -m "style: update button colors"
git add file3.md
git commit -m "docs: correct API examples"
✓ Pros: Clean history, easier debugging
✗ Cons: More steps
Option 2: Single Combined Commit
When changes are related:
# Stage all changes together
git add .
git commit -m "feat: implement login system with styled buttons"
✓ Pros: Faster workflow
✗ Cons: Less granular history
Option 3: Interactive Staging
For mixed changes (some atomic, some combined):
git add -p # Review changes interactively # For each change: (y) stage (n) don't stage (s) split larger changes
✓ Pros: Maximum control
✗ Cons: Steeper learning curve
Best Practice
"Commit like you're sending a message to your future self debugging at 3AM."
Separate commits when changes serve different purposes, combine when they're part of the same logical change.
3. Creating the Signup Form
React Form Component
This code creates a basic form component in React with three controlled inputs:
function handleChange(event) { // Handles input changes (currently empty) } return ( <div> <form> {/* Full Name Input */} <input placeholder='fullname' name='fullName' onChange={handleChange} /> {/* Email Input */} <input placeholder='Email' name='email' onChange={handleChange} /> {/* Password Input */} <input placeholder='Password' name='password' onChange={handleChange} /> </form> </div> )
Key Features:
- Controlled inputs - All form fields use React's
onChangehandler - Empty handler - Currently just a placeholder function (needs state management)
- Proper naming - Inputs use semantic
nameattributes - Basic structure - Ready for state integration (useState/useReducer)
Next Steps: Add state management to handleChange to store input values and implement form submission.
4. Add Submit Button and Create States for Inputs
React State Object for Form Data
const [formData, setFormData] = useState({ fullName: '', email: '', password: '' })
State Structure Explained:
- Single source of truth - All form fields managed in one state object
- Initial empty values - Strings initialized as empty for controlled inputs
- Destructured assignment -
formDatacontains values,setFormDataupdates them - Consistent naming - Matches the
nameattributes from your form inputs
Complete Example: Here's how to connect this to your form handler:
function handleChange(event) { setFormData({ ...formData, [event.target.name]: event.target.value }) }
Key Benefit: This pattern keeps all form data organized together and makes it easy to submit the entire object to an API endpoint later.
5. Setup State Management for Form and View in Console
React Form State Management
State Initialization
const [formData, setFormData] = useState({
fullName: '',
email: '',
password: ''
});
This creates a state object to store all form fields with empty initial values.
Debugging with Console
console.log(formData);
Outputs the current state to browser console. Chrome may recommend:
⚠️ For better React debugging, install:
Recommended Next Steps
- Implement
handleChangeto update state - Add form submission handler
- Install React DevTools for component inspection
With React DevTools, you can inspect component state and props directly in Chrome's Developer Tools panel.
6. Signup User on Supabase: Authentication Flow
Installing Supabase in a React Project
1. Install Supabase JS Library
Run this command in your project directory:
npm install @supabase/supabase-js
Or if using yarn:
yarn add @supabase/supabase-js
2. Create Supabase Client
Create a new file src/lib/supabaseClient.js:
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.REACT_APP_SUPABASE_URL
const supabaseKey = process.env.REACT_APP_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseKey)
3. Configure Environment Variables
Create a .env file in your project root:
REACT_APP_SUPABASE_URL=your-project-url
REACT_APP_SUPABASE_ANON_KEY=your-anon-key
Find these values in your Supabase project settings → API.
4. Using Supabase in Components
Import and use the client in any component:
import { supabase } from './lib/supabaseClient'
function App() {
const fetchData = async () => {
const { data, error } = await supabase
.from('your_table')
.select('*')
}
// ...
}
Remember to restart your development server after adding environment variables!
Step 7: Cateh Errors & Test Signup / Check Auth in Supabase
Step 8: Route Between Pages: Login & Signup
Implementing Routing Between Pages in React
I recently implemented page routing in my React application using react-router-dom. Here's how I set it up:
Project Structure
src/ ├── Pages/ │ ├── index.js // Exports all page components │ ├── Login.jsx │ └── SignUp.jsx ├── main.jsx // Wrapped with BrowserRouter └── App.jsx // Main application component
Key Implementation Steps
- Created three page files in a new
Pagesfolder - Installed router with
npm i react-router-dom(v7.8.1) - Wrapped the app with
BrowserRouterinmain.jsx - Exported components from
Pages/index.jsfor cleaner imports
Code Highlights
main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import { BrowserRouter } from 'react-router-dom'
createRoot(document.getElementById('root')).render(
<StrictMode>
<BrowserRouter><App /></BrowserRouter>
</StrictMode>
)
Pages/index.js
import Login from './Login'
import SignUp from './SignUp'
export {
Login,
SignUp
}
This setup provides a solid foundation for adding more pages and implementing navigation between them. Next steps would be to create the actual routing configuration in App.jsx and build out the page components.
Step 9: Adding Login Page Functionality
I enhanced the Login page by adding a proper form and improving the account creation flow. Here are the key improvements:
Login.jsx Updates
import React from 'react'
import { Link } from 'react-router-dom'
const Login = () => {
return (
<div className="login-container">
<h2>Login</h2>
<form>
<input type="email" placeholder="Email" />
<input type="password" placeholder="Password" />
<button type="submit">Sign In</button>
</form>
<p>
Don't have an account? <Link to="/signup">Create one</Link>
</p>
</div>
)
}
export default Login
Key Improvements
- ✓ Added complete login form with email and password fields
- ✓ Implemented proper form submission structure
- ✓ Enhanced "Don't have an account?" message with working Link component
- ✓ Added proper routing to SignUp page using react-router-dom
Next Steps
The next enhancements will include form validation, error handling, and connecting to Supabase authentication. I'll also style the form to match the application's design system.
Routing between pages in React — quick walkthrough
You implemented client-side routing and flow from Login → Homepage and set a session token to persist the user's state across refreshes.
- Created
Homepage.jsxusing the rfce / rfce-like snippet to scaffold the component. - Added a
<Route path="/homepage">entry inApp.jsx. - Exported
Homepagefrom your pages index withimport Homepage from './Homepage'and included it in your grouped export. - Imported the grouped exports in
App.jsxwithimport { SignUp, Login, Homepage } from './pages'. - In
Login.jsxaddedconst navigate = useNavigate()and callnavigate('/homepage')on successful login. - Stored the session token in
sessionStorageand used it to maintain the global session state on refresh.
Testing notes: after logging in, refreshing the browser should keep you on /homepage if the session token is present in session storage.
Comments
Post a Comment