Landing Page Instructions
Civix Landing Page & API Setup Instructions
Project Overview
App Name: Civix Purpose: US Citizenship Test Preparation App Platforms: iOS & Android (React Native / Expo) Target Audience: Immigrants preparing for USCIS naturalization interview
1. LANDING PAGE REQUIREMENTS
1.1 Page Structure
civix-landing/
├── app/
│ ├── page.tsx # Home/Landing page
│ ├── layout.tsx # Root layout
│ ├── privacy/page.tsx # Privacy Policy
│ ├── terms/page.tsx # Terms of Service
│ └── support/page.tsx # Support/Contact
├── components/
│ ├── Hero.tsx # Hero section with app preview
│ ├── Features.tsx # Feature cards
│ ├── Pricing.tsx # Pricing tiers
│ ├── Testimonials.tsx # User reviews
│ ├── FAQ.tsx # Frequently asked questions
│ ├── CTA.tsx # Call to action (download)
│ ├── Footer.tsx # Footer with links
│ └── Navbar.tsx # Navigation
├── api/
│ └── interview/
│ ├── chat/route.ts # AI interview endpoint
│ └── evaluate/route.ts # Answer evaluation endpoint
├── lib/
│ ├── ratelimit.ts # Upstash rate limiting
│ └── openai.ts # OpenAI client
└── public/
├── screenshots/ # App screenshots
├── icon.png # App icon
└── og-image.png # Social share image
1.2 Tech Stack
- Framework: Next.js 14+ (App Router)
- Styling: Tailwind CSS
- Animations: Framer Motion
- Deployment: Vercel
- Analytics: Vercel Analytics or Plausible
1.3 Design Requirements
Color Palette
/* Primary - Gold accent (matches app) */
--gold: #f59e0b;
--gold-dark: #d97706;
--gold-light: #fbbf24;
/* Gradients */
--gradient-gold: linear-gradient(135deg, #f59e0b, #d97706);
--gradient-hero: linear-gradient(135deg, #1e3a5f, #0f172a);
/* Backgrounds */
--bg-dark: #0f172a;
--bg-card: #1e293b;
/* Text */
--text-primary: #ffffff;
--text-secondary: rgba(255, 255, 255, 0.7);
Typography
- Headings: Inter or SF Pro Display (bold)
- Body: Inter or SF Pro Text (regular)
- Sizes:
- Hero: 48-64px
- H2: 36-40px
- H3: 24-28px
- Body: 16-18px
1.4 Sections Detail
A. Hero Section
Layout:
- Left: Text content
- Right: Phone mockup with app screenshot
Content:
- Badge: "Trusted by 10,000+ future citizens"
- Headline: "Pass Your US Citizenship Test with Confidence"
- Subheadline: "AI-powered practice with all 100 civics questions, mock interviews, and smart learning that adapts to you."
- CTA Buttons:
- Primary: "Download Free" (links to app stores)
- Secondary: "See How It Works" (scrolls to features)
- App Store badges (iOS + Android)
- Trust indicators: "4.9 stars", "100K+ downloads"
B. Features Section
Title: "Everything You Need to Pass"
Feature Cards (6 total):
1. Smart Learning Algorithm
Icon: Brain/Sparkles
Title: "AI-Powered Learning"
Description: "Our SM-2 spaced repetition algorithm learns your weak areas and prioritizes questions you need to practice most."
2. All 100 Civics Questions
Icon: Book/List
Title: "Complete Question Bank"
Description: "All official USCIS civics questions with answers in English, Farsi, and Pashto."
3. Mock Interview
Icon: Briefcase/Video
Title: "AI Mock Interview"
Description: "Practice the full naturalization interview with our AI officer. Voice input, realistic scenarios, instant feedback."
4. Reading & Writing Practice
Icon: Pencil/Document
Title: "English Test Prep"
Description: "Practice the official USCIS reading and writing vocabulary with audio pronunciation and dictation exercises."
5. Progress Tracking
Icon: Chart/Analytics
Title: "Track Your Progress"
Description: "See your mastery level, weak topics, and test readiness score. Know exactly when you're ready."
6. Gamification
Icon: Trophy/Star
Title: "Stay Motivated"
Description: "Earn XP, level up, unlock badges, and maintain daily streaks. Learning feels like a game."
C. How It Works Section
Title: "3 Steps to Citizenship"
Step 1: Learn
- Icon: Book
- "Study all 100 civics questions with translations and memory tips"
Step 2: Practice
- Icon: Target
- "Take quizzes and practice sessions. Our algorithm adapts to your weak areas."
Step 3: Pass
- Icon: Flag/Checkmark
- "Ace your interview with confidence. Join thousands of successful citizens."
D. Interview Prep Section (Premium Feature Highlight)
Title: "The Most Realistic Interview Practice"
Subtitle: "Premium Feature"
Content:
- "Experience a complete mock naturalization interview"
- "AI officer asks questions just like the real thing"
- "Voice input - speak your answers naturally"
- "Covers all parts: civics, reading, writing, N-400"
- "Three modes: Standard, 65/20 Exemption, 55/15 Exemption"
Visual: Phone mockup showing interview chat UI
E. Pricing Section
Title: "Simple, Affordable Pricing"
Subtitle: "Start free, upgrade when you're ready"
Free Tier:
- 3 quizzes per day
- 3 practice sessions per day
- Basic progress tracking
- Price: Free
Premium Tiers:
1. Monthly - $2.99/month
- Unlimited quizzes & practice
- AI Mock Interview (10/day)
- All languages
- Ad-free
- Full progress tracking
2. Annual - $19.99/year (MOST POPULAR)
- Everything in Monthly
- Save 44%
- Priority support
3. Lifetime - $39.99 one-time
- Everything forever
- Best value
- Family sharing (future)
CTA: "Start Free Trial"
Note: "Cancel anytime. No hidden fees."
F. Testimonials Section
Title: "Join Thousands of Successful Citizens"
Testimonial Cards (4-6):
1. "I passed on my first try! The mock interview was exactly like the real thing."
- Maria G., California
- Flag: Mexico
2. "As a senior, I used the 65/20 mode. The app focused on the 20 questions I needed."
- Hassan A., Texas
- Flag: Afghanistan
3. "The Farsi translations helped me understand everything. Highly recommend!"
- Fatima R., New York
- Flag: Iran
4. "I studied for only 2 weeks using this app and scored 10/10 on civics."
- David L., Florida
- Flag: Cuba
5. "The spaced repetition really works. I remembered everything in my interview."
- Priya S., Washington
- Flag: India
G. FAQ Section
Title: "Frequently Asked Questions"
Q1: Is this app affiliated with USCIS?
A: No, Civix is an independent study tool. We use official USCIS materials but are not affiliated with or endorsed by USCIS.
Q2: How many questions are on the real citizenship test?
A: You'll be asked up to 10 civics questions and must answer 6 correctly. Our app includes all 100 possible questions.
Q3: What languages are supported?
A: English, Farsi (Persian), and Pashto. More languages coming soon.
Q4: What's the 65/20 exemption?
A: If you're 65+ and have been a permanent resident for 20+ years, you only need to study 20 designated questions and can take the civics test in your native language.
Q5: Can I use this offline?
A: Yes! All questions and practice modes work offline. Only the AI Mock Interview requires internet.
Q6: Is there a money-back guarantee?
A: Yes, if you're not satisfied within 7 days, contact us for a full refund.
H. CTA Section (Bottom)
Title: "Ready to Become a US Citizen?"
Subtitle: "Download Civix free and start preparing today"
Buttons:
- App Store badge
- Google Play badge
Trust: "Join 100,000+ future citizens"
I. Footer
Columns:
1. Civix
- Logo
- "Your path to US citizenship"
- Social links (if any)
2. Product
- Features
- Pricing
- Download
3. Legal
- Privacy Policy
- Terms of Service
- Cookie Policy
4. Support
- Contact Us
- FAQ
- Email: support@civix.app
Bottom:
- "© 2025 Civix. All rights reserved."
- "Not affiliated with USCIS"
2. API SETUP INSTRUCTIONS
2.1 Required Environment Variables
Create .env.local:
# OpenAI
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
# Upstash Redis (Rate Limiting)
UPSTASH_REDIS_REST_URL=https://xxxx.upstash.io
UPSTASH_REDIS_REST_TOKEN=xxxxxxxxxxxxxxxx
# App Config
NEXT_PUBLIC_APP_URL=https://civix.app
ALLOWED_ORIGINS=https://civix.app,exp://
# Optional: Analytics
NEXT_PUBLIC_VERCEL_ANALYTICS_ID=xxxxx
2.2 Install Dependencies
npm install openai @upstash/ratelimit @upstash/redis
2.3 Rate Limiting Setup
Create lib/ratelimit.ts:
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
// 100 requests per hour per user
export const ratelimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(100, "1 h"),
analytics: true,
prefix: "civix-api",
});
// Stricter limit for AI endpoints
export const aiRatelimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(50, "1 h"),
analytics: true,
prefix: "civix-ai",
});
2.4 OpenAI Client Setup
Create lib/openai.ts:
import OpenAI from "openai";
export const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// System prompts for interview
export const INTERVIEW_SYSTEM_PROMPT = `You are a USCIS officer conducting a naturalization interview. Be professional, clear, and encouraging.
Your role:
1. Ask civics questions from the official 100 question list
2. Evaluate answers for correctness (accept paraphrased correct answers)
3. Provide brief feedback
4. Move through the interview naturally
Rules:
- Be encouraging but accurate
- Accept reasonable variations of correct answers
- Keep responses concise (2-3 sentences max)
- Use simple, clear English
- Never be rude or discouraging
Current phase will be provided in each message.`;
export const ANSWER_EVALUATION_PROMPT = `Evaluate if this citizenship test answer is correct.
Question: {question}
Official Answer: {officialAnswer}
User's Answer: {userAnswer}
Respond in JSON format:
{
"correct": true/false,
"feedback": "Brief encouraging feedback",
"suggestion": "If wrong, hint at the correct answer without giving it directly"
}`;
2.5 API Endpoints
A. Chat Endpoint
Create app/api/interview/chat/route.ts:
import { NextRequest, NextResponse } from "next/server";
import { openai, INTERVIEW_SYSTEM_PROMPT } from "@/lib/openai";
import { aiRatelimit } from "@/lib/ratelimit";
export async function POST(req: NextRequest) {
try {
// Get user identifier (device ID or user ID from header)
const userId = req.headers.get("x-user-id") || req.ip || "anonymous";
// Rate limit check
const { success, remaining, reset } = await aiRatelimit.limit(userId);
if (!success) {
return NextResponse.json(
{ error: "Rate limit exceeded", retryAfter: reset },
{
status: 429,
headers: {
"X-RateLimit-Remaining": "0",
"X-RateLimit-Reset": reset.toString(),
}
}
);
}
const { messages, phase, mode } = await req.json();
// Validate input
if (!messages || !Array.isArray(messages)) {
return NextResponse.json(
{ error: "Invalid messages format" },
{ status: 400 }
);
}
// Build context
const systemMessage = {
role: "system" as const,
content: `${INTERVIEW_SYSTEM_PROMPT}\n\nCurrent interview phase: ${phase || "civics"}\nInterview mode: ${mode || "standard"}`,
};
// Call OpenAI
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [systemMessage, ...messages.slice(-10)], // Last 10 messages for context
max_tokens: 300,
temperature: 0.7,
});
const reply = response.choices[0]?.message?.content || "";
return NextResponse.json({
reply,
remaining,
usage: {
prompt_tokens: response.usage?.prompt_tokens,
completion_tokens: response.usage?.completion_tokens,
},
});
} catch (error: any) {
console.error("Interview chat error:", error);
return NextResponse.json(
{ error: "Failed to process request" },
{ status: 500 }
);
}
}
B. Answer Evaluation Endpoint
Create app/api/interview/evaluate/route.ts:
import { NextRequest, NextResponse } from "next/server";
import { openai } from "@/lib/openai";
import { aiRatelimit } from "@/lib/ratelimit";
export async function POST(req: NextRequest) {
try {
const userId = req.headers.get("x-user-id") || req.ip || "anonymous";
const { success, remaining } = await aiRatelimit.limit(userId);
if (!success) {
return NextResponse.json(
{ error: "Rate limit exceeded" },
{ status: 429 }
);
}
const { question, officialAnswer, userAnswer } = await req.json();
if (!question || !officialAnswer || !userAnswer) {
return NextResponse.json(
{ error: "Missing required fields" },
{ status: 400 }
);
}
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "system",
content: "You evaluate US citizenship test answers. Be lenient with paraphrasing but accurate with facts. Respond in JSON only.",
},
{
role: "user",
content: `Question: ${question}\nOfficial Answer: ${officialAnswer}\nUser's Answer: ${userAnswer}\n\nEvaluate and respond in JSON: { "correct": boolean, "feedback": "string", "suggestion": "string or null" }`,
},
],
max_tokens: 150,
temperature: 0.3,
response_format: { type: "json_object" },
});
const evaluation = JSON.parse(response.choices[0]?.message?.content || "{}");
return NextResponse.json({
...evaluation,
remaining,
});
} catch (error: any) {
console.error("Evaluation error:", error);
return NextResponse.json(
{ error: "Failed to evaluate answer" },
{ status: 500 }
);
}
}
2.6 CORS Middleware
Create middleware.ts:
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
// Handle preflight requests
if (request.method === "OPTIONS") {
return new NextResponse(null, {
status: 200,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, x-user-id, Authorization",
"Access-Control-Max-Age": "86400",
},
});
}
const response = NextResponse.next();
// Add CORS headers
response.headers.set("Access-Control-Allow-Origin", "*");
response.headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
response.headers.set("Access-Control-Allow-Headers", "Content-Type, x-user-id, Authorization");
return response;
}
export const config = {
matcher: "/api/:path*",
};
2.7 Vercel Configuration
Create vercel.json:
{
"framework": "nextjs",
"regions": ["iad1"],
"functions": {
"app/api/**/*": {
"maxDuration": 30
}
},
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET, POST, OPTIONS" }
]
}
]
}
3. MOBILE APP API CLIENT
The mobile app needs this client to connect to the API.
Create in mobile app lib/api-client.ts:
const API_URL = process.env.EXPO_PUBLIC_API_URL || "https://civix.app";
interface ChatMessage {
role: "user" | "assistant";
content: string;
}
interface ChatResponse {
reply: string;
remaining: number;
}
interface EvaluationResponse {
correct: boolean;
feedback: string;
suggestion: string | null;
remaining: number;
}
// Get unique device ID for rate limiting
async function getDeviceId(): Promise<string> {
// Use expo-device or generate UUID stored in AsyncStorage
return "device-xxx"; // Implement actual device ID
}
export async function sendInterviewMessage(
messages: ChatMessage[],
phase: string,
mode: string
): Promise<ChatResponse> {
const deviceId = await getDeviceId();
const response = await fetch(`${API_URL}/api/interview/chat`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-user-id": deviceId,
},
body: JSON.stringify({ messages, phase, mode }),
});
if (response.status === 429) {
throw new Error("RATE_LIMIT_EXCEEDED");
}
if (!response.ok) {
throw new Error("API_ERROR");
}
return response.json();
}
export async function evaluateAnswer(
question: string,
officialAnswer: string,
userAnswer: string
): Promise<EvaluationResponse> {
const deviceId = await getDeviceId();
const response = await fetch(`${API_URL}/api/interview/evaluate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-user-id": deviceId,
},
body: JSON.stringify({ question, officialAnswer, userAnswer }),
});
if (response.status === 429) {
throw new Error("RATE_LIMIT_EXCEEDED");
}
if (!response.ok) {
throw new Error("API_ERROR");
}
return response.json();
}
4. SEO REQUIREMENTS
Meta Tags (in layout.tsx)
export const metadata = {
title: "Civix - US Citizenship Test Prep App",
description: "Pass your US citizenship test with confidence. AI-powered practice with all 100 civics questions, mock interviews, and smart learning. Available in English, Farsi, and Pashto.",
keywords: "us citizenship test, civics test, naturalization, uscis, citizenship prep, civics questions, citizenship interview",
openGraph: {
title: "Civix - US Citizenship Test Prep",
description: "AI-powered US citizenship test preparation. All 100 civics questions, mock interviews, and personalized learning.",
url: "https://civix.app",
siteName: "Civix",
images: [
{
url: "https://civix.app/og-image.png",
width: 1200,
height: 630,
},
],
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Civix - US Citizenship Test Prep",
description: "Pass your citizenship test with AI-powered practice",
images: ["https://civix.app/og-image.png"],
},
robots: {
index: true,
follow: true,
},
};
Structured Data (JSON-LD)
const structuredData = {
"@context": "https://schema.org",
"@type": "MobileApplication",
"name": "Civix",
"operatingSystem": "iOS, Android",
"applicationCategory": "EducationalApplication",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.9",
"ratingCount": "1000"
},
"description": "US Citizenship Test Preparation App with AI-powered learning"
};
5. DEPLOYMENT CHECKLIST
Before Launch
- Set up Vercel project
- Configure environment variables in Vercel dashboard
- Set up Upstash Redis account (free tier)
- Add OpenAI API key
- Configure custom domain (civix.app)
- Set up SSL certificate (automatic with Vercel)
- Test all API endpoints
- Test rate limiting
- Add Google Analytics / Vercel Analytics
- Submit sitemap to Google Search Console
- Create OG image (1200x630)
- Add app store links when available
- Test on mobile devices
- Test page speed (aim for 90+ Lighthouse score)
Domain Setup
- Add domain in Vercel project settings
- Update DNS records:
- A record: 76.76.21.21
- CNAME: cname.vercel-dns.com
6. APP INFORMATION FOR LANDING PAGE
App Store Links (add when available)
- iOS:
https://apps.apple.com/app/civix/id123456789 - Android:
https://play.google.com/store/apps/details?id=com.civix.app
App Screenshots Needed
- Home screen with greeting
- Quiz in progress
- Practice session
- Mock interview chat
- Results screen with score
- Settings/language selection
App Icon
- Located at:
/assets/icon.png - Size: 1024x1024
Key Statistics (update as real data comes in)
- Downloads: "100,000+"
- Rating: "4.9 stars"
- Success rate: "95% pass rate"
- Questions: "100+ civics questions"
- Languages: "3 languages"
7. CONTACT & SUPPORT
Support Email
Social Media (optional)
- Instagram: @civixapp
- Twitter: @civixapp
Legal Pages Content
Privacy Policy Key Points
- We collect: usage data, device info, language preference
- We don't sell personal data
- Data stored securely
- Users can request data deletion
- COPPA compliant (13+ only)
Terms of Service Key Points
- Educational tool only, not legal advice
- Not affiliated with USCIS
- No guarantee of passing
- Subscription auto-renews
- Refund policy: 7 days
8. QUICK START COMMANDS
# Create Next.js project
npx create-next-app@latest civix-landing --typescript --tailwind --app
# Install dependencies
cd civix-landing
npm install openai @upstash/ratelimit @upstash/redis framer-motion
# Run development
npm run dev
# Build for production
npm run build
# Deploy to Vercel
vercel --prod
Summary
This document contains everything needed to build:
- Landing page with all sections, copy, and design specs
- API endpoints for AI interview with rate limiting
- SEO optimization for search visibility
- Deployment instructions for Vercel
The landing page should be conversion-focused, mobile-responsive, and fast-loading. The API should be secure with proper rate limiting to prevent abuse.
Document created: 2025-12-16 For: Civix US Citizenship App