Using the AI Humanizer API with Next.js and Vercel
Next.js and Vercel are a powerful combination for building modern web applications, and integrating the AI Humanizer API is seamless. This guide covers everything from basic API route handlers to advanced Vercel deployment patterns, ensuring your humanization features scale effortlessly.
Project Setup and Dependencies
Start by creating a new Next.js project with TypeScript support.
npx create-next-app@latest humanizer-app --typescript --tailwind
cd humanizer-app
npm install axios dotenv-safe
Create a .env.local file in your project root to store your API credentials securely. Vercel will handle these on deployment.
NEXT_PUBLIC_APP_NAME=AI Humanizer
HUMANIZER_API_KEY=your_api_key_here
HUMANIZER_API_URL=https://api.aihumanizerapi.com/v1
Building API Route Handlers
Next.js API routes provide a simple way to create backend endpoints. Here’s how to set up a route handler for humanizing text.
// app/api/humanize/route.ts
import { NextRequest, NextResponse } from 'next/server';
import axios from 'axios';
interface HumanizeRequestBody {
text: string;
tone?: 'professional' | 'casual' | 'academic';
preserve_formatting?: boolean;
}
export async function POST(request: NextRequest) {
try {
const body: HumanizeRequestBody = await request.json();
if (!body.text || body.text.trim().length === 0) {
return NextResponse.json(
{ error: 'Text is required' },
{ status: 400 }
);
}
if (body.text.length > 50000) {
return NextResponse.json(
{ error: 'Text exceeds maximum length of 50,000 characters' },
{ status: 400 }
);
}
const response = await axios.post(
`${process.env.HUMANIZER_API_URL}/humanize`,
{
text: body.text,
tone: body.tone || 'professional',
preserve_formatting: body.preserve_formatting !== false,
},
{
headers: {
'Authorization': `Bearer ${process.env.HUMANIZER_API_KEY}`,
'Content-Type': 'application/json',
},
timeout: 30000,
}
);
return NextResponse.json(response.data);
} catch (error) {
console.error('Humanize API error:', error);
if (axios.isAxiosError(error)) {
if (error.response?.status === 429) {
return NextResponse.json(
{ error: 'Rate limit exceeded. Please try again later.' },
{ status: 429 }
);
}
return NextResponse.json(
{ error: error.response?.data?.error || 'API request failed' },
{ status: error.response?.status || 500 }
);
}
return NextResponse.json(
{ error: 'An unexpected error occurred' },
{ status: 500 }
);
}
}
Server Actions for Form Submission
Server actions simplify form handling by running code directly on the server. This is perfect for humanization requests from client forms.
// app/actions/humanize.ts
'use server';
import axios from 'axios';
export interface HumanizeResult {
success: boolean;
humanized_text?: string;
original_length?: number;
humanized_length?: number;
error?: string;
}
export async function humanizeText(
text: string,
tone: string = 'professional'
): Promise {
try {
if (!text || text.trim().length === 0) {
return { success: false, error: 'Text cannot be empty' };
}
const response = await axios.post(
`${process.env.HUMANIZER_API_URL}/humanize`,
{ text, tone, preserve_formatting: true },
{
headers: {
'Authorization': `Bearer ${process.env.HUMANIZER_API_KEY}`,
},
timeout: 30000,
}
);
return {
success: true,
humanized_text: response.data.humanized_text,
original_length: response.data.original_length,
humanized_length: response.data.humanized_length,
};
} catch (error) {
console.error('Server action error:', error);
return {
success: false,
error: 'Failed to humanize text. Please try again.',
};
}
}
Building the Client Component
Create a React component that uses the server action to humanize text submitted through a form.
// app/components/HumanizeForm.tsx
'use client';
import { useState } from 'react';
import { humanizeText } from '@/app/actions/humanize';
export default function HumanizeForm() {
const [input, setInput] = useState('');
const [tone, setTone] = useState('professional');
const [output, setOutput] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setLoading(true);
setError('');
setOutput('');
const result = await humanizeText(input, tone);
if (result.success) {
setOutput(result.humanized_text || '');
} else {
setError(result.error || 'An error occurred');
}
setLoading(false);
}
return (
{error && (
{error}
)}
{output && (
Humanized Result
{output}
)}
);
}
Edge Runtime Considerations
Vercel’s Edge Runtime allows your routes to run on edge servers closer to your users. However, not all features are available at the edge. Here’s how to configure an API route for edge deployment.
// app/api/humanize/edge/route.ts
import { NextRequest, NextResponse } from 'next/server';
export const runtime = 'edge';
export const maxDuration = 30;
export async function POST(request: NextRequest) {
try {
const { text, tone } = await request.json();
const apiKey = request.headers.get('x-api-key') || process.env.HUMANIZER_API_KEY;
const response = await fetch(
`${process.env.HUMANIZER_API_URL}/humanize`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ text, tone }),
}
);
if (!response.ok) {
return NextResponse.json(
{ error: 'API request failed' },
{ status: response.status }
);
}
const data = await response.json();
return NextResponse.json(data);
} catch (error) {
return NextResponse.json(
{ error: 'Request processing failed' },
{ status: 500 }
);
}
}
Note that edge routes use native fetch instead of axios, as some dependencies aren’t available in the edge runtime. This approach is lightweight and provides minimal latency globally.
Managing Secrets on Vercel
When you deploy to Vercel, use the Vercel dashboard or CLI to set environment variables. These are securely stored and injected at runtime.
// Using the Vercel CLI
vercel env add HUMANIZER_API_KEY
vercel env add HUMANIZER_API_URL
// Or configure in vercel.json
{
"env": {
"HUMANIZER_API_KEY": "@humanizer_api_key",
"HUMANIZER_API_URL": "https://api.aihumanizerapi.com/v1"
}
}
The @-prefix tells Vercel to use a secret. Secrets are never exposed to the browser, keeping your API key safe.
Implementing Rate Limiting
Rate limiting prevents abuse and manages API quota. Here’s a simple in-memory rate limiter for Vercel.
// lib/rateLimit.ts
interface RateLimitStore {
[key: string]: { count: number; resetTime: number };
}
const store: RateLimitStore = {};
const WINDOW_SIZE = 60000; // 1 minute
const MAX_REQUESTS = 10;
export function checkRateLimit(identifier: string): boolean {
const now = Date.now();
const record = store[identifier];
if (!record || now > record.resetTime) {
store[identifier] = { count: 1, resetTime: now + WINDOW_SIZE };
return true;
}
if (record.count >= MAX_REQUESTS) {
return false;
}
record.count++;
return true;
}
// Usage in your API route
export async function POST(request: NextRequest) {
const clientId = request.headers.get('x-forwarded-for') || 'unknown';
if (!checkRateLimit(clientId)) {
return NextResponse.json(
{ error: 'Rate limit exceeded' },
{ status: 429 }
);
}
// Continue with humanization...
}
Caching Humanized Results
Caching frequently humanized content reduces API calls and improves response times. Use Vercel’s Data Cache or Redis for production systems.
// lib/cache.ts
import { unstable_cache } from 'next/cache';
export const getCachedHumanization = unstable_cache(
async (text: string, tone: string) => {
const response = await fetch(
`${process.env.HUMANIZER_API_URL}/humanize`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HUMANIZER_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ text, tone }),
}
);
if (!response.ok) {
throw new Error('Humanization failed');
}
return response.json();
},
['humanize'],
{ revalidate: 3600 } // Cache for 1 hour
);
Error Handling and Resilience
Production applications need robust error handling. Implement fallbacks and detailed logging.
// lib/humanizeService.ts
export async function humanizeWithFallback(text: string, tone: string) {
try {
const response = await fetch(
`${process.env.HUMANIZER_API_URL}/humanize`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HUMANIZER_API_KEY}`,
},
body: JSON.stringify({ text, tone }),
signal: AbortSignal.timeout(10000),
}
);
if (response.status === 429) {
// Rate limited, return original text
return { text, humanized: false, reason: 'rate_limit' };
}
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
return { text: data.humanized_text, humanized: true };
} catch (error) {
console.error('Humanization error:', error);
// Graceful degradation: return original text
return { text, humanized: false, reason: 'service_error' };
}
}
Monitoring and Analytics
Track API usage and performance to optimize costs and identify issues.
// lib/analytics.ts
interface HumanizeMetric {
timestamp: number;
textLength: number;
processingTimeMs: number;
success: boolean;
errorType?: string;
}
const metrics: HumanizeMetric[] = [];
export function recordMetric(metric: HumanizeMetric) {
metrics.push(metric);
// Send to monitoring service periodically
if (metrics.length >= 100) {
sendMetrics();
metrics.length = 0;
}
}
function sendMetrics() {
const avgProcessingTime = metrics.reduce((sum, m) => sum + m.processingTimeMs, 0) / metrics.length;
const successRate = metrics.filter(m => m.success).length / metrics.length;
console.log({
metricsCount: metrics.length,
avgProcessingTime,
successRate,
timestamp: new Date().toISOString(),
});
// Send to external service like DataDog or New Relic
// fetch('https://monitoring.service/metrics', { method: 'POST', body: JSON.stringify(...) })
}
Deploying to Vercel
Deploying your Next.js app with Humanizer API integration is straightforward with Vercel.
// Step 1: Push to GitHub
git add .
git commit -m "Add AI Humanizer API integration"
git push origin main
// Step 2: Deploy from Vercel dashboard or CLI
vercel deploy
// Step 3: Set production environment variables
vercel env add HUMANIZER_API_KEY
vercel env add HUMANIZER_API_URL
// Redeploy to use new variables
vercel deploy --prod
Vercel automatically handles scaling, SSL, and CDN distribution. Your humanization features will be available globally with minimal latency.
Production Deployment Checklist
Before launching, verify these items are complete.
Environment variables must be set on Vercel, never committed to your repository. API keys should be stored as secrets, not regular environment variables. Configure your rate limiting strategy based on your API tier. Implement comprehensive logging and error tracking. Test all error paths, including API timeouts and rate limit scenarios. Set up monitoring alerts for error rate spikes. Document your API integration for your team. Review security headers and CORS policies.
Next Steps
You now have a production-ready Next.js application integrated with the AI Humanizer API. The patterns shown here scale from simple projects to complex applications handling thousands of requests daily. For advanced features and detailed API specifications, visit our API documentation.
Ready to enhance your content with AI humanization? Get a free API key and start with 10,000 words per month, no credit card required.