Step-by-Step Guide to Creating a Note Taking App with Vite, React, and Supabase
This guide provides a step-by-step update for enhancing the Note-Taking App by integrating authentication, user session management, and CRUD operations with a Supabase database. The updated app will feature a Header with the app title and user email, a SignUp page, and a Dashboard where users can see, create, update, and delete notes.
Step 1: Install Node.js
Before you start, ensure you have Node.js installed. You can check your installation by running:
node-vnpm-v
If Node.js is not installed, download and install it from the official website.
Step 2: Create a New Vite Project
Vite is a fast build tool for modern web applications. To create a new Vite-powered React project, run the following command at Git-bash terminal or PowerShell terminal:
Create a new project and note down the Project URL and Anon Key.
b. Install Supabase Client
In your project directory, install the Supabase client:
c. Configure Supabase
Create a .env file in the root of your project and add:
Then, in src/supabaseClient.js, initialize Supabase:
Now your project is set up with Vite, React, and Supabase!
Step 7: Create a Database Table for NoteTaking App
Navigate to the Supabase Dashboard → Table Editor and create a new table called notes with the following columns:
id (UUID, Primary Key, Default: gen_random_uuid())
title (Text, Not Null)
content (Text, Not Null)
date (Timestamp, Default: now())
iscompleted (Boolean, Default: false)
user_id (UUID, Foreign Key referencing auth.users, Not Null)
Step 8: Create Authentication Components(final)
To enable user authentication, install:
Then, Create src/components/Auth.jsx to handle SignUp, SignIn, SignOut, Email Confirmation, and Reset Password.
a. Create Auth Component for SignUp and SignIn(final)
In src/components/Auth.jsx, add:
a. Create an Authentication Handler
Create a new file src/auth.js to handle user authentication:
b. Create Auth Component for SignUp and SignIn (optional)
In src/auth.js, update the code to use auth.js functions:
Now, the authentication logic is centralized in auth.js, making it reusable and maintainable. The application supports sign-up, sign-in, sign-out, password reset, and fetching the authenticated user. Let me know if you need any refinements!(optional)
b. Implement Password Reset (optional)
In src/components/ResetPassword.jsx, add:
Step 9: Update App Header
Modify src/components/Header.jsx to show the app title and logged-in user email.
Step 10: Create the Dashboard Page
In src/pages/Dashboard.jsx, add:
Now your NoteTaker app includes authentication, password reset, and a fully functional dashboard to create, view, update, and delete notes using Supabase!
Step 11: Update App Header(final)
Modify src/components/Header.jsx to show the app title and logged-in user email, with a Sign Out button.
Step 12: Create a Dashboard Component with Card Display for Notes
Modify src/pages/Dashboard.jsx to manage notes and display them in card format.
Step 13: Create a Parent Component App.jsx (final)
Create src/App.jsx to integrate the Header, Dashboard, User Authentication, and Routes.
Step 14: Create a Dashboard Component with Card Display for Notes(final)
Modify src/pages/Dashboard.jsx to manage notes and display them in card format.
Step 15: Create a Note Taking Feature(final)
In src/components/FormNote.jsx, add:
The updated app now includes:
A FormNote component to handle both note creation and updating.
Dashboard functionality to create, update, and delete notes.
A new Update button that allows users to edit existing notes.
Step 16: Run the Application
Start the development server:
Conclusion
The updated app now includes a parent App.jsx component that manages routing and integrates authentication, dashboard, and header components for a complete user experience.
Challenge: Step A: Create a Note Taking Feature
In src/components/FormNote.jsx, add:
Step B: SQL Command Operation on Supabase DB table for Policies Setting
Step C: Fetch and Display Notes
In src/components/NoteList.js:
Now your NoteTaker app is fully functional with authentication, database integration, and note management!
Create a new table named notes with the following columns:
id (UUID, Primary Key, Default: gen_random_uuid(), Not Null)
title (Text, Not Null)
content (Text, Not Null)
date (Timestamp, Default: now(), Not Null)
isCompleted (Boolean, Default: false, Not Null)
user_id (UUID, Foreign Key referencing auth.users.id, Not Null)
c. Save and Deploy
Click Save to create the table.
Ensure the table permissions allow Authenticated users to perform CRUD operations.
d. Configure Row-Level Security (RLS)
Navigate to the Authentication → Policies section.
Click New Policy and select the notes table.
Add a rule that allows users to access only their own notes:
Add policies for insert, update, and delete accordingly.
Now, your Supabase database table is set up and secured!
As an alternative better way, use the SQL command to create the notes table in Supabase with Row Level Security (RLS) enabled:
UUID Setting in RLS Policies
We have to set the column in the database table with a default of auth.uid().
Type: uuid
Default Value: auth.uid()
SQL Command Explanation
The id column is a UUID primary key generated using gen_random_uuid().
The user_id column references the auth.users.id field, ensuring that each note belongs to a specific authenticated user.
RLS is enabled to ensure users can only access their own data.
Four security policies are created to allow authenticated users to insert, select, update, and delete only their own notes.
You can execute this SQL command in the SQL Editor of your Supabase project to create and secure the notes table. 🚀
Step E: Integrate Components into App.jsx
a. See step F to create App.jsx
Modify src/App.jsx to integrate authentication and note-taking functionality:
b. Update Dashboard.jsx
Ensure Dashboard.jsx manages note creation, retrieval, update, and deletion:
Final Steps
Run npm run dev to start the development server.
Test authentication and note management features.
Deploy the project using Vercel or Netlify for hosting.
Now your Vite React Note Taker App is fully functional with authentication and CRUD operations using Supabase! 🚀
Repeat Step 13 to accomodate sign out functionality.
Note on 403 Forbidden Error
Supabase Policies
The 403 Forbidden error typically indicates that your Supabase client does not have the necessary permissions to insert data into the notes table. Here are steps to troubleshoot and resolve this issue:
Step 1: Check Supabase Policies
Go to your Supabase Dashboard.
Navigate to Database > Tables > notes.
Click on Row Level Security (RLS).
If RLS is enabled, ensure you have a policy that allows authenticated users to insert data. If there's no policy, add the following policy:
Create a policy for INSERT
Name: Allow Insert for Authenticated Users
Target: INSERT
Expression: auth.uid() IS NOT NULL <--- default = auth.uid()
This policy ensures only signed-in users can insert new notes.
Step 2: Verify Supabase API Key Usage
Open your .env file and confirm that you are using the correct Anon Key:
If your Supabase project requires Service Role Key for inserting data, switch to using the Service Role Key in a backend function instead of using it directly in frontend code (which is unsafe).
Step F: Integrate Components into App.jsx
a. Create App.jsx
Modify src/App.jsx to integrate authentication and note-taking functionality:
b. Update Dashboard.jsx
Ensure Dashboard.jsx includes a sign-out button and correctly saves notes:
c. Update Header.jsx
Step G: Modify FormNote.jsx to Include Date Input and Completion Checkbox
In src/components/FormNote.jsx, update the form to include an input for the creation date and a checkbox for task completion:
Step H: Modify NoteList.jsx to Display Date, Completion Checkbox, and Delete Button
In src/components/NoteList.jsx, update the list to show the note creation date, allow marking completion, and add a delete button:
Step I ::
Step J: Run and Test Your Application
Start your development server with npm run dev.
Add new notes using the form, ensuring they store date and isCompleted.
Ensure the delete button removes notes successfully.
Verify that notes are stored and retrieved correctly from Supabase.
Now your Vite React Note Taker App includes a date input for note creation, a checkbox for marking completion, and a delete button using Bootstrap icons! 🚀
// Some code
-- Enable extensions required for UUID generation
create extension if not exists "pgcrypto";
-- Create the 'notes' table
create table public.notes (
id uuid primary key default gen_random_uuid(),
title text not null,
content text not null,
date timestamp default now() not null,
isCompleted boolean default false not null,
user_id uuid references auth.users(id) on delete cascade not null
);
-- Enable Row Level Security (RLS) on the 'notes' table
alter table public.notes enable row level security;
-- Create policies to allow users to interact only with their own notes
-- Allow users to insert their own notes
create policy "Allow users to insert their own notes"
on public.notes
for insert
with check (auth.uid() = user_id);
-- Allow users to read only their own notes
create policy "Allow users to read their own notes"
on public.notes
for select
using (auth.uid() = user_id);
-- Allow users to update only their own notes
create policy "Allow users to update their own notes"
on public.notes
for update
using (auth.uid() = user_id);
-- Allow users to delete only their own notes
create policy "Allow users to delete their own notes"
on public.notes
for delete
using (auth.uid() = user_id);
CREATE POLICY "Enable read access for authenticated users"
ON "public"."notes"
FOR SELECT USING (auth.uid() = user_id);
sql
-- Enable extensions required for UUID generation
create extension if not exists "pgcrypto";
-- Create the 'notes' table
create table public.notes (
id uuid primary key default gen_random_uuid(),
title text not null,
content text not null,
date timestamp default now() not null,
isCompleted boolean default false not null,
user_id uuid references auth.users(id) on delete cascade not null
);
-- Enable Row Level Security (RLS) on the 'notes' table
alter table public.notes enable row level security;
-- Create policies to allow users to interact only with their own notes
-- Allow users to insert their own notes
create policy "Allow users to insert their own notes"
on public.notes
for insert
with check (auth.uid() = user_id);
-- Allow users to read only their own notes
create policy "Allow users to read their own notes"
on public.notes
for select
using (auth.uid() = user_id);
-- Allow users to update only their own notes
create policy "Allow users to update their own notes"
on public.notes
for update
using (auth.uid() = user_id);
-- Allow users to delete only their own notes
create policy "Allow users to delete their own notes"
on public.notes
for delete
using (auth.uid() = user_id);