Skip to main content

Overview

The JARVIS frontend is a Next.js application featuring a real-time corkboard interface powered by Convex subscriptions. It’s optimized for deployment on Vercel’s edge network.

Tech Stack

  • Framework: Next.js 14+ with App Router
  • Styling: Tailwind CSS
  • Animations: Framer Motion
  • Real-time Data: Convex subscriptions
  • Deployment: Vercel

Prerequisites

Vercel Account

Sign up at vercel.com and connect your GitHub account

Backend Deployed

Backend API must be deployed and accessible

Deployment Steps

1

Configure Environment Variables

Create a .env.local file in the frontend directory:
# Frontend environment variables
NEXT_PUBLIC_CONVEX_URL=https://your-project.convex.cloud
Only variables prefixed with NEXT_PUBLIC_ are exposed to the browser.
The NEXT_PUBLIC_CONVEX_URL is the only required frontend environment variable. Get this from your Convex dashboard.
2

Test Locally

Verify the application works locally:
cd frontend
npm install
npm run dev
Open http://localhost:3000 in your browser.Verify:
  • Convex connection is established
  • Real-time subscriptions are working
  • No console errors
3

Connect to Vercel

Push your code to GitHub, then:
  1. Go to vercel.com/new
  2. Import your repository
  3. Select the frontend directory as the root
  4. Vercel auto-detects Next.js configuration
4

Configure Vercel Environment Variables

In the Vercel dashboard:
  1. Go to Settings > Environment Variables
  2. Add NEXT_PUBLIC_CONVEX_URL with your Convex URL
  3. Add for all environments (Production, Preview, Development)
Alternatively, use Vercel CLI:
vercel env add NEXT_PUBLIC_CONVEX_URL
5

Deploy

Deploy to production:
vercel --prod
Or simply push to your main branch for automatic deployment.Vercel will:
  • Install dependencies
  • Build the application
  • Deploy to edge network
  • Provide a production URL
6

Verify Deployment

Test the deployed application:
  1. Visit your Vercel URL (e.g., https://jarvis.vercel.app)
  2. Open browser DevTools console
  3. Verify Convex connection: Look for “Convex connected” message
  4. Test real-time updates by triggering a backend capture

Build Configuration

package.json Scripts

The frontend uses these npm scripts:
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  }
}

Vercel Configuration

Vercel automatically detects Next.js, but you can customize with vercel.json:
{
  "buildCommand": "npm run build",
  "devCommand": "npm run dev",
  "installCommand": "npm install",
  "framework": "nextjs",
  "outputDirectory": ".next"
}

Key Dependencies

{
  "dependencies": {
    "next": "^14.2.0",
    "react": "^18.3.0",
    "react-dom": "^18.3.0",
    "convex": "^1.14.0",
    "framer-motion": "^11.5.0",
    "tailwindcss": "^3.4.0",
    "autoprefixer": "^10.4.0",
    "postcss": "^8.4.0"
  }
}
These are installed automatically during deployment.

Convex Integration

Client Setup

The frontend uses Convex for real-time subscriptions:
// app/ConvexClientProvider.tsx
import { ConvexProvider, ConvexReactClient } from "convex/react";

const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);

export function ConvexClientProvider({ children }: { children: React.ReactNode }) {
  return <ConvexProvider client={convex}>{children}</ConvexProvider>;
}

Real-time Subscriptions

Example usage in components:
import { useQuery } from "convex/react";
import { api } from "../convex/_generated/api";

export function Corkboard() {
  // Real-time list of persons
  const persons = useQuery(api.persons.list);
  
  // Real-time connections
  const connections = useQuery(api.connections.all);
  
  return (
    <div className="corkboard">
      {persons?.map(person => (
        <PersonCard key={person._id} person={person} />
      ))}
    </div>
  );
}

Corkboard Features

Real-time Updates

The corkboard automatically updates when:
  • New persons are identified
  • Profile data arrives from agents
  • Connections are detected between people
  • Status changes (pending → researching → complete)

Animations

Framer Motion powers all animations:
import { motion } from "framer-motion";

export function PersonCard({ person }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: -50 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ type: "spring", stiffness: 300, damping: 20 }}
      className="person-card"
    >
      {/* Card content */}
    </motion.div>
  );
}

Connection Strings

Red strings connecting related people:
export function ConnectionStrings({ connections, persons }) {
  return (
    <svg className="connection-layer">
      {connections?.map(conn => {
        const personA = persons.find(p => p._id === conn.personAId);
        const personB = persons.find(p => p._id === conn.personBId);
        
        if (!personA || !personB) return null;
        
        return (
          <motion.line
            key={conn._id}
            x1={personA.boardPosition.x}
            y1={personA.boardPosition.y}
            x2={personB.boardPosition.x}
            y2={personB.boardPosition.y}
            stroke="#ff0000"
            strokeWidth={2}
            initial={{ pathLength: 0 }}
            animate={{ pathLength: 1 }}
            transition={{ duration: 1 }}
          />
        );
      })}
    </svg>
  );
}

Environment Configuration

Frontend Environment Variables

NEXT_PUBLIC_CONVEX_URL
string
required
Convex deployment URL from your Convex dashboard.Example: https://happy-animal-123.convex.cloud
Must be prefixed with NEXT_PUBLIC_ to be accessible in the browser.

Backend URL Configuration

The backend URL is automatically configured through Convex. API calls go through Convex functions, not directly to the backend.

Performance Optimization

Image Optimization

Next.js automatically optimizes images:
import Image from "next/image";

export function PersonCard({ person }) {
  return (
    <Image
      src={person.photoUrl}
      alt={person.name}
      width={200}
      height={200}
      placeholder="blur"
      blurDataURL="data:image/jpeg;base64,..."
    />
  );
}

Code Splitting

Next.js automatically code-splits by route. For heavy components, use dynamic imports:
import dynamic from "next/dynamic";

const Corkboard = dynamic(() => import("./Corkboard"), {
  ssr: false,
  loading: () => <LoadingSpinner />
});

Caching Strategy

Vercel automatically caches static assets. Configure caching headers:
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: "/:path*",
        headers: [
          {
            key: "Cache-Control",
            value: "public, max-age=31536000, immutable"
          }
        ]
      }
    ];
  }
};

Deployment Modes

Production Deployment

Automatic on push to main branch:
git push origin main
Or manual:
vercel --prod

Preview Deployments

Automatic for all pull requests:
git checkout -b feature-branch
git push origin feature-branch
# Create PR on GitHub
Vercel creates a unique preview URL for each PR.

Development

Local development with hot reload:
npm run dev

Custom Domains

Adding a Domain

1

Add Domain in Vercel

  1. Go to project Settings > Domains
  2. Add your custom domain (e.g., jarvis.yourdomain.com)
2

Configure DNS

Add a CNAME record:
Type: CNAME
Name: jarvis
Value: cname.vercel-dns.com
3

Enable HTTPS

Vercel automatically provisions SSL certificates via Let’s Encrypt. This takes a few minutes after DNS propagation.

Monitoring & Analytics

Vercel Analytics

Enable built-in analytics:
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  );
}

Error Tracking

Integrate Sentry for error tracking:
npm install @sentry/nextjs
// sentry.client.config.ts
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
});

Troubleshooting

Build Failures

Check build logs in Vercel dashboard:
  1. Go to Deployments
  2. Click on failed deployment
  3. View Build Logs
Common issues:
  • Missing environment variables
  • TypeScript errors
  • Dependency conflicts

Convex Connection Errors

Verify NEXT_PUBLIC_CONVEX_URL is set correctly:
vercel env ls
Check browser console for connection errors.

Slow Initial Load

Optimize bundle size:
npm run build
npx @next/bundle-analyzer
Identify large dependencies and consider:
  • Dynamic imports
  • Tree shaking
  • Removing unused dependencies

Real-time Updates Not Working

Verify:
  1. Convex URL is correct
  2. Convex deployment is active
  3. WebSocket connections are not blocked by firewall
  4. Browser DevTools shows “Convex connected”

Next Steps

Environment Variables

Complete list of all environment variables

Backend Deployment

Deploy the FastAPI backend

Build docs developers (and LLMs) love