Tam stack todo app: Next.js + Supabase + Vercel — 2 saatda
Next.js 14, Supabase və Vercel ilə tam funksional todo app qur, deploy et və portfoliona əlavə et — hamısı 2 saat ərzində, pulsuz.
Tam stack todo app: Next.js + Supabase + Vercel — 2 saatda
Salam, developer dostum! Bu gün səninlə real layihə quracağıq — sıfırdan deploy-a qədər. Nə WordPress, nə drag-and-drop. Əsl full-stack app.
Bunu niyə yazıram? Çünki Bakıda müsahibələrdə "portfolionda nə var?" sualına "calculator app" cavabı verən developer-ləri çox görürəm. Halbuki 2 saata elə bir şey qura bilərsən ki, həm CRUD əməliyyatları olsun, həm authentication, həm də real deployment. Gəl başlayaq.
Niyə bu stack?
Bu üçlüyü seçməyimin konkret səbəbləri var:
- Next.js 14 — React-in production-ready framework-u. Server Components, App Router, API Routes — hamısı bir yerdə. LinkedIn-də Azərbaycanda Next.js tələb edən vakansiyaların sayı 2025-ci ildən 2026-ya 40%-dən çox artıb.
- Supabase — Firebase-in open-source alternativi. PostgreSQL database, authentication, real-time subscriptions — pulsuz tier ilə başlaya bilərsən. 500 MB database, 50,000 aktiv user — kiçik və orta layihələr üçün kifayət edir.
- Vercel — Next.js-in yaradıcılarının hosting platforması. Git push etdiyin an deploy olur. Pulsuz tier-də ayda 100 GB bandwidth var.
Bütün bunlar pulsuz. Yəni sənin xərcin yalnız 2 saat vaxtındır.
Addım 1: Layihəni yarat (5 dəqiqə)
Terminalı aç və bu əmrləri yaz:
bashnpx create-next-app@latest todo-app --typescript --tailwind --app --src-dir cd todo-app npm install @supabase/supabase-js @supabase/ssr
TypeScript istifadə edirik çünki Bakıdakı əksər şirkətlər — ABB tech, Kapital Bank, Pasha Holding-in IT komandaları — artıq TypeScript tələb edir. Tailwind CSS isə UI-ı sürətlə yazmaq üçün.
Addım 2: Supabase setup (10 dəqiqə)
supabase.com-a gir, pulsuz hesab aç və yeni layihə yarat. Sonra SQL Editor-da bu query-ni işlət:
sqlCREATE TABLE todos ( id UUID DEFAULT gen_random_uuid() PRIMARY KEY, user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE, title TEXT NOT NULL, is_completed BOOLEAN DEFAULT FALSE, created_at TIMESTAMPTZ DEFAULT now() ); ALTER TABLE todos ENABLE ROW LEVEL SECURITY; CREATE POLICY "Users can manage their own todos" ON todos FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
Row Level Security (RLS) vacibdir — hər user yalnız öz todo-larını görür. Bu, real production app-lərdə mütləq olmalıdır.
İndi .env.local faylını yarat:
envNEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
Addım 3: Supabase client (5 dəqiqə)
src/lib/supabase.ts faylını yarat:
typescriptimport { createBrowserClient } from '@supabase/ssr'; export function createClient() { return createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! ); }
Addım 4: Todo komponenti (30 dəqiqə)
Bu, layihənin əsas hissəsidir. src/app/page.tsx faylını belə yaz:
typescript'use client'; import { useEffect, useState } from 'react'; import { createClient } from '@/lib/supabase'; interface Todo { id: string; title: string; is_completed: boolean; } export default function Home() { const supabase = createClient(); const [todos, setTodos] = useState<Todo[]>([]); const [newTodo, setNewTodo] = useState(''); useEffect(() => { fetchTodos(); }, []); async function fetchTodos() { const { data } = await supabase .from('todos') .select('*') .order('created_at', { ascending: false }); if (data) setTodos(data); } async function addTodo(e: React.FormEvent) { e.preventDefault(); if (!newTodo.trim()) return; const { data: { user } } = await supabase.auth.getUser(); if (!user) return; await supabase.from('todos').insert({ title: newTodo, user_id: user.id, }); setNewTodo(''); fetchTodos(); } async function toggleTodo(id: string, is_completed: boolean) { await supabase .from('todos') .update({ is_completed: !is_completed }) .eq('id', id); fetchTodos(); } async function deleteTodo(id: string) { await supabase.from('todos').delete().eq('id', id); fetchTodos(); } return ( <main className="max-w-md mx-auto mt-12 p-6"> <h1 className="text-3xl font-bold mb-6">Todo App ✓</h1> <form onSubmit={addTodo} className="flex gap-2 mb-6"> <input value={newTodo} onChange={(e) => setNewTodo(e.target.value)} placeholder="Yeni tapşırıq..." className="flex-1 border rounded px-3 py-2" /> <button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded" > Əlavə et </button> </form> <ul className="space-y-2"> {todos.map((todo) => ( <li key={todo.id} className="flex items-center gap-3 p-3 border rounded"> <input type="checkbox" checked={todo.is_completed} onChange={() => toggleTodo(todo.id, todo.is_completed)} /> <span className={todo.is_completed ? 'line-through text-gray-400 flex-1' : 'flex-1'}> {todo.title} </span> <button onClick={() => deleteTodo(todo.id)} className="text-red-500 text-sm" > Sil </button> </li> ))} </ul> </main> ); }
Bu komponentdə CRUD əməliyyatlarının hamısı var: Create, Read, Update, Delete. Müsahibədə soruşsalar, hər birini izah edə bilərsən.
Addım 5: Authentication əlavə et (20 dəqiqə)
Supabase-in built-in auth sistemindən istifadə et. Ən sadə yol — magic link ilə email authentication. Supabase dashboard-dan Authentication → Providers bölməsində Email-i aktiv et.
Sadə login komponenti yarat və supabase.auth.signInWithOtp({ email }) metodunu çağır. User email-inə link gələcək, klikləyəcək və daxil olacaq. Parol yoxdur, təhlükəsizlik yüksəkdir.
Addım 6: Deploy (10 dəqiqə)
bashgit init git add . git commit -m "initial commit: todo app"
GitHub-a push et, sonra vercel.com-a gir, GitHub repo-nu bağla, environment variable-ları əlavə et — Deploy düyməsini bas. 60 saniyəyə production-da olacaqsan.
Sənin app artıq todo-app-sənin-adın.vercel.app ünvanında canlıdır.
Portfolion üçün nə qazandın?
Bu 2 saatlıq layihə ilə sən müsahibədə bunları deyə bilərsən:
- Next.js 14 App Router ilə işləmisən
- TypeScript ilə type-safe kod yazmısan
- Supabase ilə PostgreSQL database, RLS və authentication qurmusan
- Tailwind CSS ilə responsive UI düzəltmisən
- Vercel-ə deploy etmisən, CI/CD pipeline-ı anlayırsan
- CRUD operations — real database ilə işləyən
Bakıda junior full-stack developer maaşı 800-1500 AZN arasında dəyişir, middle səviyyədə isə 2000-3500 AZN-ə çata bilir. Bu stack-i bilmək sənin bazardakı dəyərini artırır, çünki Next.js + Supabase kombinasiyası startuplarda və freelance layihələrdə çox tələb olunur.
Növbəti addımlar
Bu app-i daha da inkişaf etdirmək istəyirsənsə:
- Real-time sync — Supabase-in real-time subscription-ları ilə todo dəyişiklikləri anında görünsün
- Drag-and-drop —
@dnd-kitilə todo-ları sürüşdürüb sıralama - Dark mode — Tailwind-in
dark:class-ları ilə - PWA —
next-pwailə mobil app kimi işləsin
Hər birini əlavə etdikcə GitHub-dakı commit tarixçən böyüyür, müsahibəçi isə aktiv developer görür.
Son söz
Mükəmməl portfolionu gözləmə. Bu gün başla, deploy et, paylaş. Bakıdakı tech community kiçikdir — LinkedIn-də paylaşdığın hər layihə sənin görünürlüyünü artırır. 2 saat vaxtın var? O zaman bu axşam todo app-in hazır olacaq.
Sualın varsa, kommentlərdə yaz. Kod mübarizəsi davam edir! 🚀
Oxşar məqalələr
Git Workflow — Komanda İşi Üçün Branch Strategiyası
Komandada işləyirsən və Git branch-ləri qarışır? Bu məqalədə real layihələrdə istifadə olunan workflow strategiyalarını praktiki nümunələrlə öyrən.
Stripe Ödənişlərini Next.js-ə İnteqrasiya Et: Tam Praktiki Bələdçi
Azərbaycandan Stripe ilə ödəniş qəbul etmək istəyirsən? Next.js App Router + Stripe Checkout ilə sıfırdan real ödəniş sistemi qururuq — kod, izah və praktiki məsləhətlərlə.
OpenAI API-ni Öz Tətbiqinizə Əlavə Etmək — Başlanğıc Bələdçi
GPT modelini öz layihənizə necə inteqrasiya edəcəyinizi praktiki kod nümunələri ilə addım-addım öyrənin. API key almaqdan tutmuş production-a qədər.