Admin and roles
Give some users special powers
Most real apps have two kinds of users: the people who use the app, and the people who run it. In this lesson, you'll learn how roles work, how to build admin-only pages, and how to keep them safe.
What are roles?
Think of a shop. Customers stay at the front. Only staff can go in the back room to unpack boxes, change price tags, and check the order book. A role is the label that says who is staff and who is a customer.
- A role is a word stored with each user, like
useroradmin - An admin is a user who can manage the app's content
- An admin dashboard is the private set of pages where admins do that work
For example, a recipe app might let admins approve new recipes. A booking page might let admins see every booking. An online shop might let admins add products and view orders.
Where the role is stored
A common pattern is a profiles table with one row per user and a role column. New users get user by default.
profiles
id -- the same id as the logged-in user
name -- display name
role -- 'user' or 'admin' (default 'user')To make yourself an admin, open the table in your database dashboard (for example, Supabase's Table Editor) and change your own role to admin.
role column is excluded. Otherwise anyone can promote themselves to admin.Never trust the frontend
The frontend is the part of the app that runs in the user's browser. The user controls their browser, so they can change anything in it. Hiding the "Admin" link is like hiding the back-room key under the doormat.
Real protection needs three locks:
A server-side check means the code that runs on the server looks up the user's role before it does anything. The browser can't skip it.
/admin by typing the address, your dashboard is not protected. The server and the database must both check the role every time.Building admin-only pages
Here is a reusable prompt. Replace the parts in brackets with what your app manages:
Build an admin dashboard at /admin for my [type of app].
Access:
- Only users whose profiles.role is 'admin' can open any /admin page.
- Check the role on the server for every admin page and every admin API route.
- Add Row Level Security so only admins can insert, update, or delete [items].
- Non-admins get redirected to the home page.
- Show an "Admin" link in the header only for admins.
Pages:
- /admin/[items]: a table of all [items] with Edit and Delete buttons
and an "Add new" button.
- A form to add and edit an [item] with these fields: [fields].
- Ask "Are you sure?" before deleting.
- /admin/[other data, e.g. orders or bookings]: a read-only list, newest first.
Show me the plan first. Do not edit files yet.Let's break this down:
- The "Access" part comes first, because security is the most important rule
- "every admin API route" matters. The Save and Delete buttons call server routes, and those need the check too.
- The "Are you sure?" step stops one-click accidents
Managing content
Once admins can add, edit, and delete things, a few habits keep your data healthy:
- Hide instead of delete: mark old items as inactive, so old orders or bookings still make sense
- Validate input: prices can't be negative, required fields can't be empty
- Show who changed what: an "updated at" column helps when something looks wrong
File uploads
Admins often need to upload files, like product photos or recipe images. Apps store these in file storage, a bit like a shared photo folder for your app. In Supabase Storage, each folder is called a bucket.
Add image upload to the admin form.
- Use a storage bucket called [bucket-name].
- Anyone can view images, but only admins can upload, replace, or delete them.
- Accept only JPG, PNG, or WebP files under 5 MB.
- Save the image URL in the [image_url] column.
- Give me any SQL or storage policies I need to run, and explain them.Run any SQL it gives you in your database's SQL editor. Then upload a test image and check it shows up on the public page.
Testing your admin area
- As an admin, add an item, edit it, then delete (or hide) it
- Check that the public pages update each time
- Log in as a normal user and type
/adminin the address bar. You should be sent away. - As a normal user, try to upload a file. It should fail.
Common mistakes
Checking the role only in the browser
Wrong: "If the user is not an admin, hide the dashboard."
Right: "Check the admin role on the server for every admin page and API route, and in the database rules."- Using a secret database key (like Supabase's service_role key) in the browser so uploads "just work"
- Making a storage bucket writable by everyone
- Letting users edit their own
rolecolumn
Practice
Try these exercises to lock in what you just learned.
What's next?
You can now run your app without editing the database by hand. Next, you'll learn how to add AI features, like an assistant that answers questions using your app's own data.