Build a Full-Stack Portfolio with AI
Build and deploy a secure portfolio site with auth and a private admin panel.
Introduction
30 Second Summary
Every developer needs a portfolio to land their next role or freelance gig. But building one from scratch takes days of design decisions, backend wiring, and deployment headaches.
In this project, you will use AI-assisted code generation to build and deploy a secure, full-stack portfolio website with a public showcase and a private admin panel for managing your projects.
What You'll Build
A full-stack developer portfolio powered by Next.js and Tailwind CSS, with a Supabase backend for authentication, database storage, and image uploads, deployed live on Vercel.
By the end of this project, you'll have:
- A live portfolio website deployed at a free .vercel.app URL with an eye-catching, AI-generated UI.
- A secure admin panel where only you can log in and manage projects, protected by Supabase Auth and Row Level Security.
- A reusable prompt template for generating professional UI components with Google Antigravity.
- Secret Mission: Add interactive project filtering by tech stack and smooth scroll-triggered animations.
Are there any prerequisites?
No prior experience with Next.js or Supabase is needed. This guide walks you through setting up every tool from scratch, including Node.js, GitHub, and Google Antigravity.
Before We Start
Before you can build your portfolio, you need the right foundations in place. A full-stack app needs a runtime to build with, a database to store data, and a host to serve it to the world.
In this step, you will confirm your Node.js version, create a free Supabase project for your backend, set up Vercel for deployment, and prepare a GitHub repository to hold your code.
In this step, get ready to:
- Confirm Node.js v22+ is installed on your machine.
- Create a free Supabase project with a database and publishable key.
- Set up Vercel and GitHub for deploying your portfolio.
Verify Node.js and create a Supabase project
Your portfolio app uses Next.js, which requires Node.js to run. The Supabase JavaScript library (@supabase/supabase-js v2.110.0) needs Node.js v22 or later.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal and press Enter to open it.
- Check your Node.js version by running this command:
node --version
✔️ I see version 22 or higher
If you see v22.x.x or higher (for example v22.22.2 or v24.18.0), you are all set.
Move on to the Supabase setup below.
ⓧ I see an older version
If you see a version below v22 (for example v20.11.0 or v18.17.1), you need to upgrade.
- Go to the official Node.js v22 download page: https://nodejs.org/en/download/archive/v22.
- Download the installer for your operating system (.pkg for macOS, .msi for Windows).
- Run the installer and follow the prompts.
- Close and reopen your terminal, then run node --version again to confirm it shows v22 or higher.
Using nvm or a version manager?
If you use a version manager like nvm, you can install and switch to Node.js 22 directly. Check your version manager's documentation for the correct install command.
ⓧ Command not found
If you see an error like "command not found" or "not recognized", Node.js is not installed on your machine.
- Go to the official Node.js v22 download page: https://nodejs.org/en/download/archive/v22.
- Download the installer for your operating system (.pkg for macOS, .msi for Windows).
- Run the installer and follow the prompts to completion.
- Close and reopen your terminal, then run node --version to confirm it shows v22 or higher.
Still not working after installing?
Make sure you fully closed your terminal and opened a fresh one. The installer updates your system PATH, but existing terminal sessions do not pick up the change automatically.
help me troubleshoot Node.js installation on my machine
Now that Node.js is ready, create your Supabase project.
- Open https://database.new in your browser.
- Sign up for a free Supabase account if you do not already have one.
- Name your project my-portfolio.
- Set a database password and save it somewhere safe (you will need it later).
- Select the region closest to you and click Create new project.
- Wait about 30 seconds for the project to finish provisioning.
What is Supabase?
Supabase is an open-source backend platform that gives you a Postgres database, user authentication, file storage, and an auto-generated API in one dashboard. You will use it to store your portfolio projects, authenticate your admin login, and host uploaded images.
Once your project is provisioned, copy the Project URL and the publishable key.
- In the left sidebar of your Supabase project dashboard, click Settings.
- Click API Keys.
- Copy the Project URL and paste it into a notes file for later.
- Copy the publishable key (it starts with sb_publishable_) and paste it into the same notes file.
Why do I need these values?
The Project URL is the address your app uses to talk to your Supabase database. The publishable key identifies your app to Supabase and is safe to use in client-side code. You will add both as environment variables in a later step.
Can't find the API Keys section?
Make sure your project has finished provisioning (the dashboard shows your project name and a green status). If you still do not see the keys, try the Connect button at the top of your project dashboard, which also shows the Project URL and keys.
help me find my Supabase project URL and publishable key
Create a Vercel account and connect GitHub
Vercel will host your portfolio so anyone on the internet can see it. It gives you a free subdomain and automatic deployments every time you push code.
- Open https://vercel.com/signup in your browser.
- Click Continue with GitHub to sign up using your existing GitHub account.
- Authorize the Vercel app when prompted.
- Select the Hobby plan (free, $0/month) when asked.
What does the Hobby plan include?
The Vercel Hobby plan is free for personal, non-commercial use. It includes a yourname.vercel.app subdomain, HTTPS, and a global CDN. This is more than enough for a portfolio site.
Create a new GitHub repository
Your code needs a home on GitHub so Vercel can automatically deploy it.
- Go to https://github.com/new in your browser.
- Enter my-portfolio as the repository name.
- Set the visibility to Public (required for the free Vercel Hobby plan).
- Leave all other options unchecked (no README, no .gitignore, no license).
- Click Create repository.
Why keep the repo empty?
Google Antigravity will generate your full project from a prompt in the next step. Starting with an empty repo avoids merge conflicts when you push the generated code.
Your foundations are locked in. Next up, you will use Google Antigravity to generate a full portfolio app from a single prompt.
Generate the Portfolio UI with Antigravity
Your accounts are set up, your repository is ready, and your tools are in place. Now it's time to build something.
In this step, you'll use Google Antigravity to generate an entire Next.js portfolio website from a single prompt. Antigravity is an AI-powered code editor that can scaffold full-stack applications, complete with pages, components, and utility files.
In this step, get ready to:
- Clone your GitHub repository into Antigravity.
- Generate a full Next.js portfolio app using a detailed prompt.
- Review and refine the generated file structure.
Open Antigravity and clone your repository
Antigravity needs a workspace to generate code into. You'll clone your empty GitHub repository so Antigravity has a connected folder ready for your project files.
- Open Google Antigravity on your machine.
- Open the command palette by pressing Cmd+Shift+P (macOS) or Ctrl+Shift+P (Windows/Linux).
- Type Git Clone and select the option that appears.
- Paste your GitHub repository URL:
https://github.com/[[GITHUB_USERNAME="your-github-username"]]/my-portfolio.git
- Choose a location on your machine to clone into (your Desktop is a good option).
- When prompted, click Open to open the cloned repository as your workspace.
You should see an empty workspace with just a .git folder in the Explorer sidebar.
Why clone first?
Cloning your repository before generating code means everything Antigravity creates lands inside a Git-tracked folder. This makes it easy to push your code to GitHub later without any extra setup.
Don't see Git Clone in the command palette?
Make sure you typed Git Clone (with a space) in the command palette search. If it still doesn't appear, check that Git is installed on your machine by running git --version in a terminal.
help me set up Git Clone in Antigravity
Use the portfolio generation prompt
Antigravity generates entire applications from detailed natural-language prompts. The more specific your prompt, the closer the output matches what you want.
- Open Antigravity's chat panel (it should be visible on the right side or accessible from the sidebar).
- Paste the following prompt into the chat and press Enter to send it:
Create a Next.js 16 portfolio website with the App Router and Tailwind CSS. The site should have: 1) A stunning homepage with a hero section featuring my name and title with a gradient background and subtle animation, a projects grid section that displays project cards (each card shows a title, description, tech stack tags, and a thumbnail image), and a footer with social links. 2) A /login page with an email/password form that uses Supabase Auth. 3) A /admin page (protected, only accessible when logged in) with a form to add new projects (fields: title, description, tech_stack as comma-separated tags, and an image upload field). The admin page should also list existing projects with edit and delete buttons. Use @supabase/supabase-js for the backend. Store environment variables NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY. Make the design modern, dark-themed, with smooth hover animations on cards and a responsive layout. Use the App Router with a lib/supabase folder containing client.ts and server.ts utility files.
- Wait for Antigravity to finish generating all the files. This may take 30-60 seconds depending on your connection.
Why such a detailed prompt?
AI code generators produce better results when you specify exact page routes, field names, library choices, and design preferences upfront. Vague prompts lead to generic output that requires more rework.
This prompt names specific files (client.ts, server.ts), environment variable names (NEXT_PUBLIC_SUPABASE_URL), database fields, and even the visual style. That precision saves you from having to rewrite generated code later.
Save this prompt as a template
Keep a copy of this prompt somewhere you can find it again. You can reuse the same structure for future portfolio projects by swapping out the page descriptions and design preferences.
Review and refine the generated code
Antigravity's output may vary slightly each time, so you need to verify the key files are present. If anything is missing, you can ask Antigravity to fix it.
- Open the Explorer sidebar in Antigravity and check that the following files and folders exist:
- app/page.tsx (homepage with hero section and projects grid).
- app/login/page.tsx (email/password login form).
- app/admin/page.tsx (protected admin panel with add/edit/delete).
- lib/supabase/client.ts (browser client utility).
- lib/supabase/server.ts (server client utility).
- .env.local (template with NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY placeholders).
- If any of these files are missing, ask Antigravity to create them. For example, type in the chat: "Please create the missing lib/supabase/client.ts and server.ts files".
- If you want to adjust the visual design, ask Antigravity to refine it (e.g., "Make the hero section taller with a more dramatic gradient" or "Add card hover scale animation").
- Confirm the .env.local file contains placeholder values for both NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY.
What should each file do?
app/page.tsx is your public homepage. Visitors see your name, a project grid with cards, and social links in the footer.
app/login/page.tsx handles authentication using Supabase Auth. Only you will use this page to access the admin panel.
app/admin/page.tsx is your private dashboard for adding, editing, and deleting projects. It's protected so only logged-in users can access it.
lib/supabase/client.ts and lib/supabase/server.ts are utility files that create Supabase client instances for browser-side and server-side code respectively.
Antigravity generated a different file structure?
AI-generated output can vary. If Antigravity placed Supabase utilities in a different folder (like utils/ or src/lib/), ask it to move them: "Move the Supabase client files into a lib/supabase/ folder with client.ts and server.ts".
If pages ended up under a src/app/ folder instead of app/, that's fine. Both are valid Next.js project structures.
help me fix my Antigravity-generated file structure
Your full-stack portfolio app is generated and ready for a backend. Next up, you'll configure Supabase to store your project data, handle image uploads, and lock down access with Row Level Security.
Configure Supabase Backend
In the last step, you used Antigravity to generate a complete portfolio app with pages, components, and Supabase utility files. Now it is time to set up the backend that powers it all.
Your app needs somewhere to store project data (titles, descriptions, tech stacks) and project images. It also needs security rules so that only you can add or modify content. You will configure all of this inside the Supabase dashboard using SQL and the built-in Storage service.
In this step, get ready to:
- Create a database table to store your portfolio projects.
- Set up a storage bucket for project screenshot uploads.
- Lock down the database with Row Level Security policies and create an admin user.
Create the projects table
Your portfolio app needs a structured place to store each project's information. A database table defines the shape of that data, like a spreadsheet with fixed column headings.
- In your Supabase dashboard, click SQL Editor in the left sidebar.
- Create the projects table by pasting the following SQL and clicking Run:
CREATE TABLE projects (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
description TEXT NOT NULL,
tech_stack TEXT[] DEFAULT '{}',
image_url TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
What does this SQL do?
This creates a table called projects with six columns.
- id generates a unique identifier for each project automatically.
- title and description store the text content you enter through the admin panel.
- tech_stack is an array that holds multiple tags (like "React", "Python", "AWS").
- image_url stores the link to a project's screenshot in your storage bucket.
- created_at timestamps when each project was added.
- After clicking Run, you should see a "Success. No rows returned" message at the bottom of the editor.
Seeing an error after running the SQL?
- Check that you copied the entire SQL block, including the closing semicolon.
- If you see "relation already exists", you have already run this query. You can verify by clicking Table Editor in the left sidebar and checking for the projects table.
Help me fix my SQL error in the Supabase SQL Editor
Set up a storage bucket for project images
When you upload a screenshot through the admin panel, it needs somewhere to live. Supabase Storage organises files into buckets, similar to folders.
- In the left sidebar, click Storage.
- Click New Bucket.
- Enter project-images as the bucket name.
- Toggle the Public bucket switch to on. This allows anyone to view uploaded images without authentication.
- Click Create Bucket.
Why make the bucket public?
Visitors to your portfolio need to see project screenshots without logging in. A public bucket lets anyone view images using their URL. Uploading and deleting files still requires authentication, which you will secure with a storage policy next.
Now you need to add a storage policy so that only logged-in users can upload images.
- Inside the project-images bucket, click Policies in the sidebar.
- Under the Objects section, click Add Policy.
- Select INSERT as the operation.
- Set the target role to authenticated so only logged-in users can upload.
- Give the policy a name like Authenticated users can upload and save it.
- Repeat the process to add a second policy: choose SELECT as the operation, and allow access for all users (public). This lets anyone view the images.
- Verify you have two policies listed under Objects: one for INSERT (authenticated) and one for SELECT (public).
Don't see the Policies option?
- Make sure you clicked into the project-images bucket first. The Policies sidebar option appears within a specific bucket, not at the top-level Storage page.
Help me find where to set storage policies in Supabase
Enable Row Level Security
Right now, anyone with your Supabase URL could read and write to the projects table. Row Level Security (RLS) lets you define who can perform each operation on your data.
- Switch back to the SQL Editor in the left sidebar.
- Enable RLS and create four access policies by pasting the following SQL and clicking Run:
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Anyone can view projects"
ON projects FOR SELECT
USING (true);
CREATE POLICY "Only authenticated users can insert"
ON projects FOR INSERT
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Only authenticated users can update"
ON projects FOR UPDATE
USING (auth.role() = 'authenticated');
CREATE POLICY "Only authenticated users can delete"
ON projects FOR DELETE
USING (auth.role() = 'authenticated');
What do these policies do?
The first line turns on RLS for the projects table. Without it, all policies are ignored.
- The SELECT policy uses USING (true) which means everyone (logged in or not) can read your projects.
- The INSERT, UPDATE, and DELETE policies check auth.role() = 'authenticated' which restricts write operations to logged-in users only.
This combination means visitors can browse your portfolio freely, but only you (logged in as the admin) can add, edit, or remove projects.
- You should see "Success. No rows returned" after running the SQL.
Finally, you need an admin account so you can actually log into the app.
- In the left sidebar, click Authentication.
- Click Add User and select Create New User.
- Enter your email address and a secure password.
- Click Create User.
- Save your email and password somewhere safe. You will use these to log into the admin panel.
- Verify that your new user appears in the Users list on the Authentication page with a confirmed email status.
User not appearing in the list?
- Make sure you clicked Create New User (not "Invite User"). Inviting sends an email link, while creating adds the user directly.
- Try refreshing the page if the user does not appear immediately.
Help me create an admin user in Supabase Authentication
Your backend is fully configured. Next, you will wire the app to this Supabase project and test everything locally.
Connect the App to Supabase and Test Locally
Your Supabase backend is fully configured with a database table, storage bucket, security policies, and an admin user. Now it is time to wire your generated frontend to that backend and see everything working together.
In this step, you will plug your real Supabase credentials into the app, install dependencies, and run through the full user flow locally. By the end, you will have added a real project through the admin panel and confirmed it displays on the public homepage.
In this step, get ready to:
- Connect the app to your Supabase project using environment variables.
- Install dependencies and start the development server.
- Test login, admin, and the public homepage end to end.
Add environment variables and install dependencies
Your app's Supabase client files reference two environment variables to know which project to talk to. The .env.local file Antigravity created already has placeholder values. You need to swap those for your real credentials.
- Return to the Supabase dashboard.
- Navigate to Project Settings, then select API.
- Copy the Project URL value (it looks like https://abcdefgh.supabase.co).
- Copy the publishable key (a long string starting with eyJ).
Why are these safe to use in client-side code?
The publishable key only allows operations that your Row Level Security policies permit. It cannot bypass RLS or access the service role. That is why Supabase designed it to be embedded in browser code.
- In your Antigravity workspace, open the .env.local file that Antigravity generated earlier.
- Replace the placeholder values so the file looks like this:
NEXT_PUBLIC_SUPABASE_URL=your-project-url-here
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-publishable-key-here
- Replace your-project-url-here with the Project URL you copied from your Supabase dashboard.
- Replace your-publishable-key-here with the publishable key you copied.
- Save .env.local.
Keep this file out of Git
Antigravity typically adds .env.local to .gitignore by default. Confirm it is listed there so your keys are never pushed to GitHub.
- Install all project dependencies by running this command in the Antigravity terminal:
npm install
- Wait for the install to finish. You should see a message confirming packages were added with no critical errors.
Seeing dependency errors?
If you see version conflict warnings, try running npm install --legacy-peer-deps instead. Antigravity-generated projects occasionally reference packages with mismatched peer dependency ranges.
If the error mentions Node.js version compatibility, confirm you are running Node.js v22 or later with node --version.
Help me fix my npm install errors
- Start the development server by running:
npm run dev
- You should see a message in the terminal indicating the server is ready, with a URL pointing to http://localhost:3000.
Server not starting?
Make sure no other process is using port 3000. If something else is running there, stop it first or check the terminal output for an alternate port.
If you see an error about missing environment variables, double-check that your .env.local file is saved in the project root (the same folder as package.json).
Help me get my Next.js dev server running
Test the public portfolio page
With the server running, you can now confirm the frontend loads and connects to Supabase without errors.
- Open your browser and navigate to http://localhost:3000.
- Confirm the homepage loads with the hero section displaying a name, title, and gradient background.
- Scroll down to find the projects grid section. It should be empty since you have not added any projects yet.
What should I see?
The homepage has three main areas. A hero section at the top with animated gradient styling, a projects grid in the middle (currently empty), and a footer with social links at the bottom.
If you see the page but the styling looks broken, check the Antigravity terminal for CSS-related warnings and ask Antigravity to fix them.
Seeing a blank page or error?
Open your browser's developer console (right-click the page, select Inspect, then click the Console tab). Look for errors mentioning NEXT_PUBLIC_SUPABASE_URL or connection failures. These indicate your .env.local values are incorrect or the file is not being read.
If you update .env.local, you must restart the dev server. Press Ctrl+C in the terminal, then run npm run dev again.
Help me fix my portfolio homepage
Test login and admin functionality
The real test is the protected flow. You will log in with the admin account you created in Supabase, access the admin panel, and add your first project.
- Navigate to http://localhost:3000/login in your browser.
- Enter the email and password you used when you created the admin user in Supabase Auth.
- Click the login button.
Login not working?
Make sure you are using the exact email and password you set when creating the user in the Authentication section of your Supabase dashboard. Passwords are case-sensitive.
If you see a "user not confirmed" type of error, return to the Supabase dashboard, go to Authentication, find your user, and confirm the email is verified.
Help me fix my Supabase login
- After logging in successfully, navigate to http://localhost:3000/admin.
- You should see the admin panel with a form to add projects and an empty list below it.
Now add your first test project to confirm the full data flow works.
- In the Title field, enter My First Project.
- In the Description field, enter A test project to verify my portfolio works end to end.
- In the Tech Stack field, enter React, Next.js, Supabase (comma-separated tags).
- For the image upload, select any image file from your computer (a screenshot or sample image works fine).
- Click the submit or add button to save the project.
What happens when you submit?
The form sends a request to Supabase. The image uploads to the project-images storage bucket. The project metadata (title, description, tech stack, and the image URL) inserts into the projects table. Your RLS policy allows this because you are authenticated.
- Navigate back to http://localhost:3000 (the homepage).
- Confirm that your test project now appears in the projects grid with its title, description, tech stack tags, and uploaded image.
Project not showing on the homepage?
Refresh the page. Some generated code fetches data on initial load but does not auto-refresh after a mutation.
If it still does not appear, check the browser console for errors. A common issue is the storage bucket policy not allowing public SELECT access. Return to the Supabase dashboard, go to Storage, click on project-images, and verify the SELECT policy is set to allow everyone.
Help me debug my project display
Your portfolio is working locally with real data flowing between the frontend and Supabase. Next up, you will push this to GitHub and deploy it live on Vercel so the whole world can see your portfolio.
Deploy to Vercel
Your portfolio works perfectly on your local machine. Now it is time to put it on the internet so anyone can visit it.
In this step, you will push your code to GitHub and then import the repository into Vercel. Vercel auto-detects Next.js projects and handles the entire build and hosting process for you.
In this step, get ready to:
- Push your code to GitHub.
- Deploy the project on Vercel with environment variables.
- Verify the live site works end-to-end.
Push code to GitHub
Your code lives locally in the Antigravity workspace. Pushing it to GitHub makes it available for Vercel to pull and deploy automatically.
- Return to the Antigravity terminal.
- Commit and push your code to GitHub by running these commands:
git add .
git commit -m "Initial portfolio site"
git push origin main
What do these commands do?
- git add . stages all your project files for a commit.
- git commit -m "Initial portfolio site" saves a snapshot of your code with a descriptive message.
- git push origin main uploads your commit to the main branch of your GitHub repository.
GitHub may ask you to authenticate
If this is your first time pushing from this machine, Git may open a browser window or prompt you for credentials in the terminal. Sign in with your GitHub account when prompted. If you have two-factor authentication enabled, you will need to use a Personal Access Token instead of your password.
- Confirm the push succeeded by checking for a message like Branch 'main' set up to track remote branch 'main' in your terminal output.
Push failed or authentication error?
- Make sure your GitHub repository is named my-portfolio and is set to public.
- Check that the remote URL matches your repository. Run git remote -v to verify.
- If Git prompts for a password and rejects it, generate a Personal Access Token from GitHub Settings and use it instead.
Help me fix a git push authentication error to GitHub.
Deploy on Vercel
With your code on GitHub, Vercel can pull it and deploy your portfolio in about 60 seconds.
- Open https://vercel.com/new in your browser.
- You should see a list of your GitHub repositories under **Import Git Repository**.Import Git Repository.
- Find your my-portfolio repository and click Import.
- Vercel auto-detects it as a Next.js project. Leave the framework preset and build settings as their defaults.
Before clicking Deploy, you need to add your Supabase credentials so the live site can connect to your database.
- Expand the Environment Variables section on the project configuration page.
- Add your first variable. In the Key field, enter NEXT_PUBLIC_SUPABASE_URL. In the Value field, paste your Supabase project URL.
- Add a second variable. In the Key field, enter NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY. In the Value field, paste your Supabase publishable key.
- Click Deploy.
Why add environment variables here?
Your .env.local file only works on your local machine. Vercel needs its own copy of these values so the deployed app can connect to Supabase. These are stored securely on Vercel's servers and injected at build time.
- Wait about 60 seconds for the deployment to finish. Vercel shows a build log and a success screen with your live URL when complete.
Deployment failed?
- Check the build log for error details. The most common cause is a typo in your environment variable names.
- Make sure you typed NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY exactly as shown, including the NEXT_PUBLIC_ prefix.
- If the build fails with a type error, try running npm run build locally first to see the full error message.
Help me debug a Vercel deployment failure for my Next.js portfolio.
Verify the live site
Your portfolio is now live on the internet. Time to confirm everything works from end to end.
- Copy the URL Vercel assigned to your project (it looks like my-portfolio-yourname.vercel.app).
- Visit the URL in your browser and confirm the homepage loads with your hero section and projects grid.
- Navigate to /login on your live site.
- Log in with the admin email and password you created in Supabase.
- After login, navigate to /admin.
- Add a new project through the live admin panel with a title, description, tech stack, and image.
- Return to your homepage and confirm the new project appears in the projects grid.
What is happening behind the scenes?
When you add a project from the live admin panel, your app writes directly to your Supabase database. The homepage reads from the same database. Row Level Security ensures only your authenticated session can insert or update data, while anyone can view it.
Every time you push new code to main on GitHub, Vercel automatically rebuilds and redeploys your site.
Live site loads but login fails?
- Double-check that both environment variables in Vercel match the values in your Supabase dashboard exactly.
- Make sure you added the variables before deploying. If you added them after, trigger a redeploy from the Vercel dashboard by clicking Redeploy in the deployment menu.
- Confirm your Supabase project is not paused. Free-tier projects pause after 1 week of inactivity.
Help me troubleshoot my live portfolio site not connecting to Supabase.
Your portfolio is live on the internet. Anyone with the URL can see your projects, but only you can manage them through the admin panel. Next up, you will add some extra polish with filtering and scroll animations in the Secret Mission.
Secret mission
Add Project Filtering and Scroll Animations
Your portfolio looks great, but can visitors quickly find projects that use a specific technology? Right now, every project shows up at once. In this secret mission, you'll add interactive filtering by tech stack and smooth scroll-triggered animations that make your portfolio feel polished and professional.
Clean Up Your Resources
Clean Up Your Resources
All three services used in this project are free. Supabase, Vercel, and GitHub all offer free tiers that cover everything you built, so there are no ongoing costs.
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- Supabase project (my-portfolio) on the free tier. Pauses after 1 week of inactivity.
- Vercel deployment (my-portfolio) on the Hobby plan. Free forever for personal use.
- GitHub repository (my-portfolio). Free forever.
- Local project files including .env.local with your Supabase credentials.
Keep everything running
No action needed. Choose this if you are still actively building or want your portfolio live.
- Both Supabase and Vercel are free. Your site stays live indefinitely at your .vercel.app URL.
- Log into Supabase at least once a week to prevent your project from pausing due to inactivity.
- Your local .env.local file contains your Supabase credentials. Keep it safe and do not commit it to Git.
Pause - I'll come back to this later
Do nothing. Supabase automatically pauses free projects after 1 week of inactivity. Your Vercel site keeps serving cached pages.
- After pausing, your portfolio will show errors for any database queries until you resume the Supabase project.
- To resume, log into the Supabase dashboard, select your paused project, and click Restore.
- Vercel continues to serve your deployed site at no cost. No action needed there.
- Your GitHub repository and local files remain unchanged.
Delete - I don't want to use this again
Remove all project resources permanently. This cannot be undone.
- Delete the Supabase project: Open your Supabase dashboard, select the my-portfolio project, click Project Settings in the sidebar, then scroll to the bottom of the General page and click Delete project. Confirm when prompted. This permanently removes your database, storage bucket, and auth users.
- Delete the Vercel project: Open the Vercel dashboard, select my-portfolio, click Settings in the sidebar, scroll to the bottom of the General page, and click Delete in the Delete Project section. Confirm by typing the project name.
- Delete the GitHub repository: Open your my-portfolio repository on GitHub, click Settings, scroll to the Danger Zone section, and click Delete this repository. Confirm by typing the repository name.
- Delete local project files by running this command in your terminal:
rm -rf ~/Desktop/my-portfolio
On Windows?
Use this command instead to remove the local folder:
Remove-Item -Recurse -Force ~\Desktop\my-portfolio
That's a Wrap!
That's a Wrap!
Nice work! You just built and deployed a secure full-stack portfolio website using AI-assisted development.
You've learned how to:
- Use Google Antigravity to generate production-ready Next.js code from a detailed prompt, including pages, components, and backend utilities.
- Configure Supabase for authentication, database storage, file uploads, and Row Level Security policies that protect your admin panel from unauthorized access.
- Deploy a full-stack app to Vercel with environment variables configured, giving you a live .vercel.app URL accessible from anywhere.
- (Secret Mission) Added interactive tech stack filtering and scroll-triggered animations using the IntersectionObserver API.
Ready to quiz yourself?