A modern, elegant bio card application built with Next.js 16 and Supabase. Create your personalized bio card and share it with the world - like Linktree, but better.
- 🔐 Secure Authentication - Google OAuth & Email/Password via Supabase
- 👤 Custom Usernames - Unique, permanent usernames with availability checking
- 📝 Real-time Editing - Live preview as you type
- 🖼️ Image Uploads - Direct upload to Supabase Storage for profile and cover images
- 🔗 Four Social Links - Instagram, WhatsApp, X (Twitter), and LinkedIn
- 📋 Smart Copy - Copy full URLs with one click
- 🎨 Beautiful UI - Clean, modern design with smooth animations
- 📱 Fully Responsive - Works perfectly on all devices
- 🚀 Shareable Links -
yoursite.com/usernameformat - 🔔 Toast Notifications - Beautiful feedback for all actions
- 🎯 Viral Loop - "Create Your Own" CTA on public profiles
- Node.js 18+ installed
- pnpm (or npm/yarn)
- A Supabase account
-
Clone the repository
git clone <your-repo-url> cd veneer
-
Install dependencies
pnpm install
-
Set up environment variables
Create a
.env.localfile in the root directory:NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
-
Set up Supabase
- Create a new project at supabase.com
- Go to SQL Editor and run the script from
supabase-setup.sql - Go to Storage and create a bucket named
profile-images(make it public) - (Optional) Configure Google OAuth in Authentication > Providers
-
Run the development server
pnpm dev
-
Open your browser
Navigate to http://localhost:3000
veneer/
├── app/
│ ├── auth/ # Authentication pages
│ ├── dashboard/ # Profile editing dashboard
│ ├── onboarding/ # Username selection
│ ├── [username]/ # Public profile pages
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout
│ └── page.tsx # Landing page
├── components/
│ └── Toast.tsx # Toast notification component
├── lib/
│ └── supabase/ # Supabase client utilities
│ ├── client.ts # Browser client
│ ├── server.ts # Server client
│ └── middleware.ts # Auth middleware
├── public/ # Static assets
├── middleware.ts # Next.js middleware
├── supabase-setup.sql # Database schema
└── next.config.ts # Next.js configuration
- Landing Page → User sees the homepage with "Get Started" button
- Authentication → Sign up with Google or Email/Password
- Onboarding → Choose a unique username (permanent)
- Dashboard → Edit profile with live preview:
- Upload profile and cover images
- Add name, role, location, phone, bio
- Add social links (Instagram, WhatsApp, X, LinkedIn)
- Share → Get shareable link:
yoursite.com/username - Public Profile → Anyone can view the bio card
- Framework: Next.js 16.2.3 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS v4
- Authentication: Supabase Auth
- Database: Supabase (PostgreSQL)
- Storage: Supabase Storage
- Icons: Hugeicons React
- Package Manager: pnpm
- Row Level Security (RLS) policies
- HTTP-only cookies for sessions
- Secure image uploads with user-specific paths
- Protected routes with middleware
- Input validation and sanitization
profiles (
id uuid PRIMARY KEY,
username text UNIQUE NOT NULL,
name text,
role text,
location text,
phone text,
bio text,
cover_image text,
profile_image text,
instagram text,
whatsapp text,
twitter text,
linkedin text,
created_at timestamp,
updated_at timestamp
)As you edit your profile in the dashboard, the card preview updates instantly on the right side.
- Click upload buttons to select images
- Images are uploaded to Supabase Storage
- URLs are automatically saved to the database
- Preview shows immediately after upload
When users click the copy button on social links, it copies the full URL:
- Instagram:
https://instagram.com/username - WhatsApp:
https://wa.me/phone - X:
https://x.com/username - LinkedIn:
https://linkedin.com/in/username
Beautiful, non-intrusive notifications for:
- Profile updates
- Image uploads
- Link copying
- Errors and validations
- Push your code to GitHub
- Import project in Vercel
- Add environment variables
- Deploy!
The app can be deployed to any platform that supports Next.js:
- Netlify
- Railway
- Render
- Self-hosted
The app is configured to allow images from your Supabase storage. Update next.config.ts if you change your Supabase URL:
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'your-project.supabase.co',
pathname: '/storage/v1/object/public/**',
},
],
}Ensure your profile-images bucket is:
- Public (for viewing images)
- Has proper RLS policies (see
supabase-setup.sql)
| Variable | Description | Required |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Your Supabase project URL | Yes |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Your Supabase anonymous key | Yes |
Contributions are welcome! Please feel free to submit a Pull Request.
This project is open source and available under the MIT License.
- Built with Next.js
- Powered by Supabase
- Icons by Hugeicons
- Styled with Tailwind CSS
If you have any questions or run into issues, please open an issue on GitHub.
Made with ❤️ by Tayo.