Enroll Course

100% Online Study
Web & Video Lectures
Earn Diploma Certificate
Access to Job Openings
Access to CV Builder



How To Build A Full-Stack App With Next.js, Supabase & AI Integration

How to Build a Full-Stack App with Next.js, Supabase & AI Integration. 

 



What You’ll Build

A simple Next.js app with:

  • Supabase for authentication, database, and real-time updates

  • AI integration (e.g., OpenAI GPT API) for adding AI-powered features like chat, content generation, or smart suggestions


Prerequisites

  • Node.js installed (v16+ recommended)

  • Basic knowledge of React and Next.js

  • Supabase account (free tier available)

  • OpenAI account or another AI provider API key (optional for AI features)


Step 1: Set Up Next.js Project

  1. Create a new Next.js app:

npx create-next-app@latest my-ai-app  cd my-ai-app  
  1. Start the dev server:

npm run dev  

Open http://localhost:3000 to check it’s running.


Step 2: Set Up Supabase

  1. Go to Supabase and create a free project.

  2. Get your API URL and anon public API key from the project dashboard.

  3. Set up your database schema using Supabase SQL editor or table editor (e.g., create a messages table for chat or users table).

Example SQL to create a simple messages table:

create table messages (    id bigint generated by default as identity primary key,    user_id uuid references auth.users not null,    content text not null,    created_at timestamp with time zone default timezone('utc'::text, now()) not null  );  

Step 3: Install Supabase Client in Next.js

npm install @supabase/supabase-js  

Create a file lib/supabaseClient.js to initialize Supabase client:

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);  

Add these environment variables to .env.local:

NEXT_PUBLIC_SUPABASE_URL=your-supabase-url  NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key  

Step 4: Implement Authentication with Supabase

Create a simple auth page (pages/auth.js) using Supabase Auth UI or custom components.

Example for email signup/login:

import { useState } from 'react';  import { supabase } from '../lib/supabaseClient';    export default function Auth() {    const [email, setEmail] = useState('');    const [message, setMessage] = useState('');      const handleLogin = async () => {      const { error } = await supabase.auth.signInWithOtp({ email });      if (error) setMessage(error.message);      else setMessage('Check your email for the login link!');    };      return (      <div>        <h1>Login / Signup</h1>        <input          type="email"          placeholder="your@email.com"          value={email}          onChange={(e) => setEmail(e.target.value)}        />        <button onClick={handleLogin}>Send Magic Link</button>        <p>{message}</p>      </div>    );  }  

Step 5: Create a Basic Chat or Content Page

Example: A page where logged-in users can submit messages and see messages from others (stored in Supabase).

pages/index.js:

import { useEffect, useState } from 'react';  import { supabase } from '../lib/supabaseClient';    export default function Home() {    const [session, setSession] = useState(null);    const [messages, setMessages] = useState([]);    const [input, setInput] = useState('');      useEffect(() => {      setSession(supabase.auth.getSession().then(({ data }) => setSession(data.session)));        const subscription = supabase        .channel('public:messages')        .on('postgres_changes', { event: '*', schema: 'public', table: 'messages' }, payload => {          setMessages((messages) => [...messages, payload.new]);        })        .subscribe();        fetchMessages();        return () => {        supabase.removeChannel(subscription);      };    }, []);      async function fetchMessages() {      let { data } = await supabase.from('messages').select('*').order('created_at', { ascending: true });      setMessages(data);    }      async function sendMessage() {      if (!input) return;      await supabase.from('messages').insert([{ content: input, user_id: session.user.id }]);      setInput('');    }      if (!session) return <p>Please log in</p>;      return (      <div>        <h1>Chat Room</h1>        <div style={{ maxHeight: '300px', overflowY: 'auto' }}>          {messages.map((msg) => (            <p key={msg.id}>{msg.content}</p>          ))}        </div>        <input          type="text"          value={input}          onChange={(e) => setInput(e.target.value)}          placeholder="Type a message"        />        <button onClick={sendMessage}>Send</button>      </div>    );  }  

Step 6: Integrate AI (e.g., OpenAI GPT)

  1. Install OpenAI client:

npm install openai  
  1. Create an API route for AI requests: pages/api/ai.js

import { Configuration, OpenAIApi } from 'openai';    const configuration = new Configuration({    apiKey: process.env.OPENAI_API_KEY,  });  const openai = new OpenAIApi(configuration);    export default async function handler(req, res) {    if (req.method !== 'POST') {      return res.status(405).json({ message: 'Only POST requests allowed' });    }      const { prompt } = req.body;      try {      const completion = await openai.createChatCompletion({        model: 'gpt-4',        messages: [{ role: 'user', content: prompt }],      });        res.status(200).json({ result: completion.data.choices[0].message.content });    } catch (error) {      res.status(500).json({ error: error.message || 'Error with AI API' });    }  }  
  1. Add the API key to .env.local:

OPENAI_API_KEY=your-openai-api-key  

Step 7: Call AI API from Frontend

Update the chat app to send user input to AI and display the response.

async function sendMessage() {    if (!input) return;      // Save user message    await supabase.from('messages').insert([{ content: input, user_id: session.user.id }]);      // Call AI API    const response = await fetch('/api/ai', {      method: 'POST',      headers: { 'Content-Type': 'application/json' },      body: JSON.stringify({ prompt: input }),    });    const data = await response.json();      // Save AI response    await supabase.from('messages').insert([{ content: data.result, user_id: 'AI' }]);      setInput('');  }  

Step 8: Deploy Your App

  • Push your code to GitHub.

  • Connect your repository to Vercel for seamless Next.js deployment.

  • Add your environment variables (Supabase URL, anon key, OpenAI API key) in Vercel dashboard.


Bonus Tips

  • Use Supabase Edge Functions for serverless AI calls to protect API keys.

  • Add middleware in Next.js for protected routes.

  • Use Tailwind CSS or UI libraries to style your app faster.

  • Enable real-time subscriptions for live chat experiences.

  • Explore other AI models or tools for image generation, speech, or recommendations.


Summary

Step Key Tools / Concepts
1. Setup Next.js create-next-app
2. Setup Supabase Database, Auth, Real-time DB
3. Connect Supabase Client @supabase/supabase-js
4. Implement Auth Supabase Auth with Magic Link
5. Build Chat Interface Realtime subscriptions, React state
6. AI Integration OpenAI API, Next.js API routes
7. Deploy Vercel or other hosting

Certainly! Below is a comprehensive, detailed 2000-word case study guide on How to Build a Full-Stack App with Next.js, Supabase & AI Integration, including practical examples, explanations, and real-world workflows.


 


 


Overview of the Tech Stack

  • Next.js: React framework optimized for SEO, server-side rendering, API routes, and static generation.

  • Supabase: Provides PostgreSQL database, real-time subscriptions, authentication, and storage out of the box.

  • AI Integration: Using OpenAI GPT APIs (or similar) for natural language processing, code generation, or chatbots.


The Case Study: AI-Powered Chat Application with User Authentication and Real-Time Messaging


Project Goals

  • Allow users to sign up and log in with email magic links (via Supabase Auth).

  • Enable authenticated users to chat with an AI assistant powered by OpenAI GPT.

  • Store all chat messages in Supabase’s real-time PostgreSQL database.

  • Use Next.js API routes as a middle layer to securely proxy requests to the OpenAI API.

  • Provide a clean, responsive UI with real-time message updates.


Part 1: Setting Up the Development Environment


Step 1: Initialize Next.js Project

npx create-next-app ai-chat-app  cd ai-chat-app  npm run dev  

This bootstraps the frontend with React and Next.js features.


Step 2: Create Supabase Project

  1. Go to Supabase and create a free project.

  2. Note your Supabase URL and Anon Key (found under Project Settings).

  3. In Supabase’s SQL editor, create a messages table:

create table messages (    id bigint generated by default as identity primary key,    user_id uuid references auth.users not null,    content text not null,    is_ai boolean default false,    created_at timestamp with time zone default timezone('utc'::text, now()) not null  );  

Step 3: Install Dependencies

npm install @supabase/supabase-js openai  
  • @supabase/supabase-js to interact with Supabase.

  • openai for AI integration.


Step 4: Configure Environment Variables

Create .env.local with:

NEXT_PUBLIC_SUPABASE_URL=your_supabase_url  NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key  OPENAI_API_KEY=your_openai_api_key  

Never expose OPENAI_API_KEY on the client side; use API routes for secure calls.


Part 2: Authentication with Supabase


Example: Magic Link Email Auth

Create a 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);  

Create pages/auth.js:

import { useState } from 'react';  import { supabase } from '../lib/supabaseClient';    export default function Auth() {    const [email, setEmail] = useState('');    const [message, setMessage] = useState('');      async function handleLogin() {      const { error } = await supabase.auth.signInWithOtp({ email });      if (error) setMessage(error.message);      else setMessage('Check your email for a magic link!');    }      return (      <div>        <h1>Login or Sign Up</h1>        <input          type="email"          placeholder="you@example.com"          onChange={(e) => setEmail(e.target.value)}          value={email}        />        <button onClick={handleLogin}>Send Magic Link</button>        <p>{message}</p>      </div>    );  }  

Key Learning:

  • Supabase handles sending magic link emails, authentication state, and user session management seamlessly.

  • No backend code needed for user management.


Part 3: Building the Chat Interface with Next.js & Supabase


Real-Time Message Fetching

Using Supabase’s realtime subscriptions to update the chat UI instantly when new messages arrive.

pages/index.js:

import { useState, useEffect } from 'react';  import { supabase } from '../lib/supabaseClient';    export default function Chat() {    const [session, setSession] = useState(null);    const [messages, setMessages] = useState([]);    const [input, setInput] = useState('');      useEffect(() => {      supabase.auth.getSession().then(({ data }) => setSession(data.session));        fetchMessages();        const subscription = supabase        .channel('public:messages')        .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) => {          setMessages((messages) => [...messages, payload.new]);        })        .subscribe();        return () => {        supabase.removeChannel(subscription);      };    }, []);      async function fetchMessages() {      let { data } = await supabase.from('messages').select('*').order('created_at', { ascending: true });      setMessages(data);    }      async function sendMessage() {      if (!input.trim() || !session) return;        await supabase.from('messages').insert([        { content: input, user_id: session.user.id, is_ai: false },      ]);        setInput('');    }      if (!session) return <p>Please log in to chat.</p>;      return (      <div>        <div style={{ height: '300px', overflowY: 'auto' }}>          {messages.map((msg) => (            <p key={msg.id} style={{ color: msg.is_ai ? 'blue' : 'black' }}>              {msg.content}            </p>          ))}        </div>          <input          type="text"          placeholder="Type your message..."          value={input}          onChange={(e) => setInput(e.target.value)}        />          <button onClick={sendMessage}>Send</button>      </div>    );  }  

Part 4: AI Integration with OpenAI API


Creating a Secure API Route in Next.js

Create pages/api/chat.js:

import { Configuration, OpenAIApi } from 'openai';    const config = new Configuration({    apiKey: process.env.OPENAI_API_KEY,  });  const openai = new OpenAIApi(config);    export default async function handler(req, res) {    if (req.method !== 'POST') return res.status(405).json({ error: 'Method not allowed' });      const { messages } = req.body;      if (!messages) return res.status(400).json({ error: 'No messages provided' });      try {      const completion = await openai.createChatCompletion({        model: 'gpt-4',        messages,      });        const aiMessage = completion.data.choices[0].message;      res.status(200).json({ message: aiMessage });    } catch (error) {      res.status(500).json({ error: error.message });    }  }  

How to Use This API from the Frontend

Modify sendMessage in pages/index.js:

async function sendMessage() {    if (!input.trim() || !session) return;      // Insert user message    await supabase.from('messages').insert([      { content: input, user_id: session.user.id, is_ai: false },    ]);      // Prepare chat history for context (simplified)    const chatHistory = messages.map(msg => ({      role: msg.is_ai ? 'assistant' : 'user',      content: msg.content,    }));      // Add latest user message to history    chatHistory.push({ role: 'user', content: input });      // Call AI API    const response = await fetch('/api/chat', {      method: 'POST',      headers: { 'Content-Type': 'application/json' },      body: JSON.stringify({ messages: chatHistory }),    });      const data = await response.json();      if (data.message) {      // Save AI response to DB      await supabase.from('messages').insert([        { content: data.message.content, user_id: null, is_ai: true },      ]);    }      setInput('');  }  

Part 5: Real-World Challenges & Solutions

Challenge 1: Maintaining Chat Context

  • Problem: Passing entire chat history to OpenAI every time can grow large.

  • Solution: Limit the message history to recent N messages or summarize previous conversations.


Challenge 2: Handling Authentication State

  • Keep session state updated with Supabase hooks or listeners.

  • Redirect unauthenticated users to /auth.


Challenge 3: Securing API Keys

  • Use Next.js API routes to prevent exposing OpenAI keys.

  • Never call OpenAI directly from frontend.


Challenge 4: Realtime Sync Lag or Missed Events

  • Use Supabase’s real-time channels carefully.

  • Handle reconnection logic and fallback fetches for missed messages.


Part 6: Deployment & Scaling


Deploying to Vercel

  1. Push your code to GitHub.

  2. Connect your repo to Vercel.

  3. Add environment variables on Vercel dashboard.

  4. Deploy and test.


Scaling Tips

  • Use Supabase’s edge functions for low latency.

  • Cache AI responses for repeated queries.

  • Monitor API usage and rate limits on OpenAI.


Part 7: Extending Your App


Ideas for Additional Features

  • Add user profiles and avatars with Supabase storage.

  • Integrate payment gateways for premium AI usage.

  • Add multi-language support by detecting user language and translating prompts.

  • Build analytics dashboards using Supabase and Next.js API routes.

  • Use AI for moderation to filter inappropriate messages.


Conclusion

Building a full-stack app with Next.js, Supabase, and AI integration is an achievable project that leverages modern tools to deliver powerful user experiences. This stack supports fast development, scalability, and real-time interactivity with minimal backend overhead.

You’ve seen how to:

  • Set up authentication and real-time database with Supabase.

  • Build a responsive chat UI with Next.js.

  • Securely integrate AI APIs using Next.js API routes.

  • Handle common challenges and optimize the app.


 


 

 

Corporate Training for Business Growth and Schools