spot_imgspot_img

Top 5 This Week

spot_img

Related Posts

VSCode + GitHub + Vercel + Supabase: Deploy Your App Live with a Real Database (Part 2)

This is Part 2 of a 2-part series. If you have not set up your project yet, start with Part 1: VSCode + Git + GitHub Setup.

Welcome back. At this point you have a working Task Manager app running locally on your computer and your code is saved on GitHub. In Part 2, we will:

  1. Add a real database using Supabase (so tasks are saved permanently)
  2. Deploy your app live on the internet using Vercel
  3. Connect a custom domain
  4. Set up environment variables for secrets
  5. Enable automatic deployments (every push to GitHub updates your live site)

By the end, you will have a fully functional, production-grade web application that anyone in the world can use.


What is Supabase?

Supabase is an open-source Firebase alternative that gives you a fully managed PostgreSQL database, real-time subscriptions, authentication, file storage, and an auto-generated API — all for free on the starter plan.

In plain terms: Supabase is your app’s memory. When a user adds a task, it gets saved to Supabase. When they refresh the page or come back tomorrow, the task is still there.


Step 1 — Create a Supabase Account and Project

  1. Go to supabase.com and click Start your project
  2. Sign up with your GitHub account (easiest option — use the same GitHub account you created in Part 1)
  3. Click New Project
  4. Fill in:
    • Organization: your name or team name
    • Project name: my-task-manager
    • Database password: create a strong password and save it somewhere safe
    • Region: choose the one closest to you (e.g., “US East” for Toronto)
  5. Click Create new project

Supabase will take about 1-2 minutes to set up your project. You will see a loading screen. Wait for it to finish.


Step 2 — Get Your API Keys

Once your project is ready, you need two pieces of information to connect your app to Supabase:

  1. In the Supabase dashboard, click Settings (the gear icon in the left sidebar)
  2. Click API
  3. Under “Project URL,” copy the URL that looks like: https://abcdefghijklm.supabase.co
  4. Under “Project API Keys,” copy the anon / public key

Keep these handy — you will need them in the next steps.

⚠️ Important: The anon key is safe to use in your frontend code. Never expose your service_role key in frontend code — that key bypasses all security rules.


Step 3 — Create Your Database Table

Now we need to create a table to store tasks. Supabase uses PostgreSQL, a professional-grade database used by companies like Instagram and Reddit.

  1. In the Supabase dashboard, click Table Editor in the left sidebar
  2. Click Create a new table
  3. Set the table name to: tasks
  4. Add these columns by clicking Add column for each:
    • title — type: text, not nullable
    • completed — type: bool, default value: false
  5. The id and created_at columns are added automatically — leave them as-is
  6. Click Save

Alternatively, you can create the table using SQL. Click SQL Editor in the sidebar, paste this, and click Run:

-- Create the tasks table
create table tasks (
  id uuid default gen_random_uuid() primary key,
  title text not null,
  completed boolean default false,
  created_at timestamp with time zone default now()
);

-- Enable Row Level Security (best practice)
alter table tasks enable row level security;

-- Allow all operations for development (we can restrict this later)
create policy "Allow all for now" on tasks for all using (true);

Your database is ready. No server to manage, no SQL server to install — Supabase handles everything.


Step 4 — Connect Supabase to Your Next.js App

Open your my-task-manager project in VS Code. In the terminal, install the Supabase JavaScript library:

npm install @supabase/supabase-js

Create your environment variables file:

In VS Code, create a new file in your project root called .env.local. This file stores your secrets and is never uploaded to GitHub (notice it is already in your .gitignore file).

NEXT_PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here

Replace the values with the URL and anon key you copied from Supabase in Step 2.

What is NEXT_PUBLIC_? In Next.js, any environment variable starting with NEXT_PUBLIC_ is safe to use in the browser. Variables without that prefix are server-only secrets.

Create the Supabase client file:

In your project, create a new folder called lib and inside it create a file called supabase.js:

// lib/supabase.js
import { createClient } from '@supabase/supabase-js'

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseKey)

This creates one reusable Supabase connection that the rest of your app can import.


Step 5 — Update Your App to Use the Database

Now update app/page.js to load tasks from Supabase and save them there. Replace the entire file with:

'use client'
import { useState, useEffect } from 'react'
import { supabase } from '@/lib/supabase'

export default function Home() {
  const [tasks, setTasks] = useState([])
  const [newTask, setNewTask] = useState('')
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetchTasks()
  }, [])

  async function fetchTasks() {
    setLoading(true)
    const { data, error } = await supabase
      .from('tasks')
      .select('*')
      .order('created_at', { ascending: false })

    if (error) {
      console.error('Error fetching tasks:', error)
    } else {
      setTasks(data || [])
    }
    setLoading(false)
  }

  async function addTask() {
    if (!newTask.trim()) return

    const { error } = await supabase
      .from('tasks')
      .insert([{ title: newTask.trim() }])

    if (error) {
      console.error('Error adding task:', error)
    } else {
      setNewTask('')
      fetchTasks()
    }
  }

  async function toggleTask(id, completed) {
    const { error } = await supabase
      .from('tasks')
      .update({ completed: !completed })
      .eq('id', id)

    if (!error) fetchTasks()
  }

  async function deleteTask(id) {
    const { error } = await supabase
      .from('tasks')
      .delete()
      .eq('id', id)

    if (!error) fetchTasks()
  }

  return (
    <main className="max-w-xl mx-auto p-8">
      <h1 className="text-3xl font-bold mb-2 text-gray-800">My Task Manager</h1>
      <p className="text-gray-500 mb-6">Powered by Next.js + Supabase</p>

      <div className="flex gap-2 mb-6">
        <input
          type="text"
          value={newTask}
          onChange={(e) => setNewTask(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && addTask()}
          placeholder="Add a new task..."
          className="flex-1 border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
        />
        <button
          onClick={addTask}
          className="bg-blue-600 text-white px-5 py-2 rounded-lg hover:bg-blue-700 transition"
        >
          Add
        </button>
      </div>

      {loading ? (
        <p className="text-center text-gray-400 py-8">Loading tasks...</p>
      ) : (
        <ul className="space-y-3">
          {tasks.length === 0 && (
            <p className="text-gray-400 text-center py-8">No tasks yet. Add one above!</p>
          )}
          {tasks.map((task) => (
            <li key={task.id} className="flex items-center gap-3 p-4 bg-gray-50 rounded-lg border group">
              <input
                type="checkbox"
                checked={task.completed}
                onChange={() => toggleTask(task.id, task.completed)}
                className="w-4 h-4 cursor-pointer"
              />
              <span className={`flex-1 ${task.completed ? 'line-through text-gray-400' : 'text-gray-800'}`}>
                {task.title}
              </span>
              <button
                onClick={() => deleteTask(task.id)}
                className="text-red-400 hover:text-red-600 opacity-0 group-hover:opacity-100 transition text-sm"
              >
                Delete
              </button>
            </li>
          ))}
        </ul>
      )}
    </main>
  )
}

Test it locally:

npm run dev

Visit http://localhost:3000. Add some tasks. Refresh the page — the tasks are still there! They are now saved in your Supabase database. You can even see them by going to your Supabase dashboard → Table Editor → tasks.

Commit this progress:

git add .
git commit -m "Connect Supabase database for persistent task storage"
git push

Step 6 — Deploy to Vercel

Vercel is the company that created Next.js. Their hosting platform is designed specifically for Next.js apps and has a free Hobby tier that is more than enough for personal and small projects.

Create a Vercel account:

  1. Go to vercel.com
  2. Click Sign Up
  3. Choose Continue with GitHub — Vercel will ask permission to access your repositories
  4. Authorize Vercel on GitHub
  5. On the welcome screen, select Personal and Hobby (free)

Import your project:

  1. In the Vercel dashboard, click Add New… → Project
  2. You will see a list of your GitHub repositories — find my-task-manager and click Import
  3. Vercel automatically detects that it is a Next.js project and configures the build settings
  4. Under Environment Variables, add your Supabase credentials:
    • Name: NEXT_PUBLIC_SUPABASE_URL | Value: your Supabase URL
    • Name: NEXT_PUBLIC_SUPABASE_ANON_KEY | Value: your anon key
    • Click Add for each one
  5. Click Deploy

Vercel will:

  • Download your code from GitHub
  • Install dependencies (npm install)
  • Build your Next.js app (npm run build)
  • Deploy it to their global CDN (servers around the world)

This takes about 1-2 minutes. When it finishes, Vercel gives you a live URL like https://my-task-manager-abc123.vercel.app. Click it — your app is live on the internet!


Step 7 — Connect a Custom Domain

Your site is live but has an ugly .vercel.app URL. Let’s connect a proper custom domain like mytasks.com.

First, you need to own a domain. If you do not have one yet, buy one from a domain registrar like Namecheap, Google Domains, or Cloudflare (usually $10-15/year for a .com).

Add the domain in Vercel:

  1. In the Vercel dashboard, open your project
  2. Click Settings → Domains
  3. Type your domain name (e.g., mytasks.com) and click Add
  4. Vercel will show you DNS records to add

Update your DNS records at your domain registrar:

Log into wherever you bought your domain and look for “DNS Management” or “DNS Records.” You need to add:

For a root domain (yourdomain.com):

Type Name Value
A @ 76.76.21.21

For www subdomain (www.yourdomain.com):

Type Name Value
CNAME www cname.vercel-dns.com

DNS changes take anywhere from a few minutes to 48 hours to propagate worldwide (usually under 30 minutes). Vercel automatically handles SSL/HTTPS — your site will have a padlock icon and a valid certificate at no extra cost.

Once the domain is verified, Vercel shows a green checkmark next to it and your custom domain is live.


Step 8 — The Auto-Deploy Magic

Here is where everything clicks together. From now on, every time you push code to GitHub, Vercel automatically rebuilds and deploys your site. You never have to touch Vercel again — just push to GitHub.

Let’s prove it. Make a small change to your app:

  1. Open app/page.js in VS Code
  2. Change the title from My Task Manager to My Awesome Task Manager
  3. Save the file
  4. Run:
git add .
git commit -m "Update page title"
git push

Go to your Vercel dashboard and watch the Deployments tab. You will see a new deployment start automatically within seconds. After 1-2 minutes, your live site shows the updated title.

This is the professional development loop:

# The daily development workflow
# 1. Write code in VS Code
# 2. Test locally: npm run dev → http://localhost:3000
# 3. Commit and push to GitHub:
git add .
git commit -m "What I changed and why"
git push
# 4. Vercel auto-deploys — done!

Step 9 — Managing Environment Variables

Your app needs secret values (like database credentials) to work. These should NEVER be in your code or on GitHub. There are two places you manage them:

Local development — .env.local

The .env.local file on your computer stores secrets for local development. It is in your .gitignore so it is never uploaded to GitHub.

# .env.local (on your computer only — never commit this file)
NEXT_PUBLIC_SUPABASE_URL=https://yourproject.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Production — Vercel Dashboard

For your live site, environment variables are set in Vercel:

  1. Vercel Dashboard → your project → Settings → Environment Variables
  2. Add your variables here with Production, Preview, and Development scopes
  3. After adding or changing variables, redeploy by pushing a new commit (or triggering a manual redeploy)

Rule of thumb for what belongs in environment variables:

  • API keys and tokens — yes
  • Database URLs and passwords — yes
  • Payment processor keys — yes
  • Your website’s name or color scheme — no (hardcode those)

Step 10 — Understanding Vercel Deployment Types

Vercel creates different kinds of deployments automatically:

Deployment Type When It Happens URL
Production Every push to main branch your custom domain
Preview Every push to other branches or a Pull Request unique-hash.vercel.app
Development npm run dev on your computer localhost:3000

Preview deployments are extremely useful. When you are building a new feature, create a separate Git branch:

# Create a new branch to work on a feature
git checkout -b add-due-dates

# Work on your feature, then commit and push
git add .
git commit -m "Add due date field to tasks"
git push -u origin add-due-dates

Vercel automatically creates a preview deployment at a unique URL so you can test the feature live before it goes to production. When you are happy with it, merge the branch into main on GitHub and Vercel deploys it to production.


Step 11 — Full Production Checklist

Before you share your site with the world, go through this checklist:

Security

  • ✅ No secrets in your code or GitHub (all in .env.local and Vercel settings)
  • ✅ Supabase Row Level Security (RLS) is enabled on all tables
  • ✅ HTTPS is active (Vercel does this automatically)

Performance

  • ✅ Images are optimized (use Next.js <Image> component instead of plain <img>)
  • ✅ App loads in under 3 seconds (check in Chrome DevTools → Network tab)

SEO and Sharing

  • ✅ Add metadata to app/layout.js:
// app/layout.js
export const metadata = {
  title: 'My Task Manager',
  description: 'A simple, fast task manager built with Next.js and Supabase',
  openGraph: {
    title: 'My Task Manager',
    description: 'Stay organized with this full-stack task manager',
  },
}

Monitoring

  • ✅ Check Vercel’s Analytics tab (free basic analytics are built in)
  • ✅ Check your deployment logs if anything breaks: Vercel → project → Deployments → click on a deployment → Functions tab

Troubleshooting Common Issues

Build fails on Vercel with “Module not found” error

This usually means you installed a package locally but forgot to commit package.json. Make sure you run git add . and commit after running npm install.

App works locally but not on Vercel — blank page or database error

Almost always caused by missing environment variables in Vercel. Go to Settings → Environment Variables and make sure NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY are there. After adding them, you need to redeploy.

Tasks not saving — Supabase “row level security” error

Your Supabase table has RLS enabled (good!) but no policy allowing writes. Go to Supabase → Authentication → Policies and create a policy that allows the operations you need, or use the SQL from Step 3 to create an open policy for development.

“This site can’t be reached” after adding custom domain

DNS changes take time to propagate. Wait 30 minutes and try again. You can check propagation status at dnschecker.org — enter your domain and it shows which DNS servers worldwide have updated.

Environment variable changes not taking effect in production

Vercel only reads environment variables at build time. After changing them in the Vercel dashboard, you must trigger a new deployment (push a commit or click “Redeploy” in Vercel).


What You Have Built

Take a moment to appreciate what you have accomplished. Starting from zero, you have built and deployed a full-stack production web application that:

  • ✅ Has a professional code editor setup (VS Code with extensions)
  • ✅ Uses version control (Git + GitHub) — you can never permanently lose your work
  • ✅ Has a real PostgreSQL database (Supabase) — data persists forever
  • ✅ Is live on the internet (Vercel) — accessible from any device, anywhere in the world
  • ✅ Has automatic deployments — push to GitHub, site updates in 2 minutes
  • ✅ Has HTTPS/SSL — your users’ data is encrypted in transit

This is the exact same stack used by professional development teams at startups and tech companies. The difference between you and a professional developer is not which tools they use — it is how much they have practiced using them.


What to Learn Next

Now that you have the foundation, here are natural next steps for each layer of your stack:

Make your app more powerful with Supabase:

  • Authentication — add user login so everyone has their own private tasks (@supabase/auth-helpers-nextjs)
  • Real-time — tasks update instantly on all devices using Supabase Realtime subscriptions
  • Storage — let users attach files or images to tasks

Make your app better with Next.js:

  • Server Components — fetch data on the server for faster initial loads
  • API Routes — create backend endpoints in the same project
  • Middleware — protect pages that require login

Scale your deployment with Vercel:

  • Analytics — understand where your users come from
  • Edge Functions — run code geographically close to your users for ultra-low latency
  • Cron Jobs — run scheduled tasks (daily emails, database cleanup)

The Stack That Powers Modern Web Apps

What you have built today uses the same fundamental architecture as apps like Linear, Notion, and Vercel’s own dashboard. The tools change (different databases, different frameworks), but the concept is identical:

  1. Write code locally in an editor
  2. Track changes with Git
  3. Backup and collaborate through GitHub
  4. Deploy automatically via CI/CD (Vercel does this for you)
  5. Persist data in a managed database (Supabase/PostgreSQL)

You are no longer a person who has never deployed a web application. You are a developer.

Have questions or hit a snag? Contact us — we help GTAVille readers get their first projects live.

ItsRanaJee (Editor)
ItsRanaJee (Editor)http://www.GTAVille.com
ItsRanaJee (Editor) – Author Bio Technology Leader & Business Strategist:- ItsRanaJee is a veteran Technology Leader and Business Strategist with over 30 years of cross-industry expertise in cloud computing, Big Data, and Agentic AI systems. Since beginning his career in 1993, he has driven innovation across diverse sectors, including finance, telecommunications, retail, and semiconductors. Now the Editor of www.GTAtwill.com, he leverages his deep technical background to provide Canadian SMBs with enterprise-level marketing, lead generation, and technology insights, dedicated to making sophisticated business strategies accessible and actionable for every entrepreneur. Passionate about nurturing the next generation, he provides personalized mentorship to young professionals and freelancers navigating IT careers and entrepreneurship. 🚀✨

Popular Articles