How to Build a Secure Next.js App with Supabase and Vercel

How to Build a Secure Next.js App with Supabase and Vercel
Photo by Team Nocoloco / Unsplash

Building a full-stack application can be a daunting task, especially when it comes to managing user authentication, database integration, and deployment. Luckily, the combination of Next.js,

Supabase, and Vercel provides developers with an efficient, secure, and scalable solution. In this guide, we’ll walk through the process of building a secure Next.js application powered by Supabase, and deploying it seamlessly using Vercel. Why Next.js, Supabase, and Vercel? Before diving into the code, let’s briefly discuss why these tools are a powerful trio: Next.js is a React framework that simplifies server-side rendering (SSR), static site generation (SSG), and API route creation. It’s perfect for building fast, modern web applications. Supabase is an open-source Firebase alternative. It provides an easy-to-use Postgres database, authentication services, and storage, all with a simple API. Vercel is a cloud platform optimized for frontend frameworks like Next.js. Deploying applications is straightforward, and Vercel ensures your app scales automatically. Combining these tools allows you to focus on building features while leaving the infrastructure and security concerns mostly handled. Step 1: Setting Up the Next.js Project Start by creating a new Next.js project. Open your terminal and run: npx create-next-app@latest my-secure-app cd my-secure-app You can choose TypeScript if you prefer type safety. Once the project is initialized, you can run npm run dev to start the development server at http://localhost:3000. Step 2: Integrating Supabase Next, we’ll add Supabase to handle authentication and database operations. 1. Install Supabase Client:

npm install @supabase/supabase-js 2. Create a Supabase Project: Go to Supabase.io and create a free account. Create a new project and note the API URL and anon key. These will be used to connect your Next.js app to Supabase. 3. Configure Supabase in Next.js: Create a new file lib/supabaseClient.js: import { createClient } from '@supabase/supabase-js'; const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; export const supabase = createClient(supabaseUrl, supabaseAnonKey); Then, add your credentials to a .env.local file: NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key This ensures your API keys are secure and not exposed in your codebase. Step 3: Implementing Authentication Supabase simplifies authentication with email/password, magic links, or social providers. 1. Sign-Up and Login Pages: Create a pages/auth.js file: import { useState } from 'react'; import { supabase } from '../lib/supabaseClient'; export default function Auth() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleSignUp = async () => { const { error } = await supabase.auth.signUp({ email, password }); if (error) alert(error.message); else alert('Check your email for confirmation!'); }; const handleLogin = async () => { const { error } = await supabase.auth.signInWithPassword({ email, password }); if (error) alert(error.message); else alert('Successfully logged in!'); }; return ( <div> <h2>Sign Up / Login</h2> <input type="email" placeholder="Email" onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Password" onChange={(e) => setPassword(e.target.value)} /> <button onClick={handleSignUp}>Sign Up</button> <button onClick={handleLogin}>Login</button> </div> ); } This setup allows users to securely sign up and log in to your application. Step 4: Protecting Pages with Server-Side Rendering One of Next.js’s strengths is server-side rendering (SSR), which is useful for protecting sensitive pages. export async function getServerSideProps({ req }) { const { user } = await supabase.auth.getUserByCookie(req); if (!user) { return { redirect: { destination: '/auth', permanent: false } }; } return { props: { user } }; } This ensures only authenticated users can access certain pages, adding an extra layer of security. Step 5: Deploying on Vercel After building your app locally, it’s time to deploy: 1. Push your project to GitHub or GitLab. 2. Go to Vercel and connect your repository. 3. Vercel automatically detects a Next.js project and sets up deployment. 4. Add your Supabase environment variables (NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY) in the Vercel dashboard. 5. Click Deploy. Your app will be live in minutes! Vercel handles SSL, caching, and global distribution, ensuring your app is both secure and fast. Step 6: Enhancing Security To further secure your app: Use HTTPS-only cookies and JWTs for authentication. Enable row-level security (RLS) in Supabase for fine-grained access control. Regularly update dependencies to patch vulnerabilities. Limit public exposure of environment variables and API keys. Conclusion Building a secure Next.js application with Supabase and Vercel is surprisingly straightforward. With this stack, you gain powerful features such as server-side rendering, authentication, and managed database hosting—all without the headache of configuring complex infrastructure. By following this guide, you now have a solid foundation for building modern, secure, and scalable web applications. The next steps could include adding real-time features with Supabase Realtime, integrating serverless functions, or enhancing the UI with Tailwind CSS.

The combination of Next.js, Supabase, and Vercel gives you both speed and security, making it an ideal choice for modern web development.

Read more