Deployment and Production
Preparing for Production
Before deploying, let's ensure everything is production-ready.
Environment Variables
Create .env.production:
NEXT_PUBLIC_WORDPRESS_URL=https://your-live-wordpress-site.com
NEXT_PUBLIC_SITE_URL=https://your-nextjs-domain.com.env.local or sensitive credentials to git. Add them to .gitignore.
Build and Test Locally
Run a production build to catch issues:
npm run buildCheck for errors or warnings. Common issues:
- Missing environment variables
- API connection errors
- Image optimization warnings
Test the production build:
npm run startVisit http://localhost:3000 and test all pages.
Deploying to Vercel
Vercel is the recommended platform for Next.js. Here's how to deploy:
1. Push to GitHub
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/your-repo.git
git push -u origin main2. Connect to Vercel
- Go to vercel.com and sign in
- Click "New Project"
- Import your GitHub repository
- Configure the project:
- Root Directory: ./ (or your project folder)
3. Set Environment Variables
In Vercel project settings → Environment Variables:
NEXT_PUBLIC_WORDPRESS_URL = https://your-wordpress-site.comClick Deploy.
Configuring WordPress for Production
Enable CORS
Update your WordPress site to allow requests from Vercel:
// In theme's functions.php or a custom plugin
add_action('rest_api_init', function() {
remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
add_filter('rest_pre_serve_request', function($value) {
$origin = get_http_origin();
$allowed_origins = [
'https://your-nextjs-domain.vercel.app',
'https://your-custom-domain.com',
];
if (in_array($origin, $allowed_origins)) {
header('Access-Control-Allow-Origin: ' . $origin);
}
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
return $value;
});
}, 15);Optimize REST API Performance
Add caching headers:
// Add cache headers to REST API responses
add_filter('rest_post_dispatch', function($response) {
$response->header('Cache-Control', 'public, max-age=60, s-maxage=300');
return $response;
});On-Demand Revalidation
For instant updates when content changes, set up webhooks:
1. Create a Revalidation API Route
// src/app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const secret = request.headers.get('x-revalidate-secret');
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ error: 'Invalid secret' }, { status: 401 });
}
try {
const body = await request.json();
const { slug, type } = body;
if (type === 'post' && slug) {
// Revalidate specific post
revalidatePath(`/blog/${slug}`);
// Revalidate blog listing
revalidatePath('/blog');
// Revalidate homepage
revalidatePath('/');
}
return NextResponse.json({ revalidated: true, now: Date.now() });
} catch (error) {
return NextResponse.json({ error: 'Error revalidating' }, { status: 500 });
}
}2. Add Environment Variable
In Vercel:
REVALIDATION_SECRET = your-secret-key-here3. WordPress Webhook Plugin
Create a simple plugin or use WP Webhooks:
// In a custom plugin
add_action('save_post', function($post_id) {
if (wp_is_post_revision($post_id)) return;
$post = get_post($post_id);
if ($post->post_status !== 'publish') return;
$webhook_url = 'https://your-nextjs-domain.com/api/revalidate';
wp_remote_post($webhook_url, [
'headers' => [
'Content-Type' => 'application/json',
'x-revalidate-secret' => 'your-secret-key-here',
],
'body' => json_encode([
'type' => 'post',
'slug' => $post->post_name,
]),
]);
});Custom Domain
In Vercel:
- Go to Project Settings → Domains
- Add your custom domain
- Update DNS records as instructed
- Enable HTTPS (automatic)
Performance Monitoring
Enable Vercel Analytics
npm install @vercel/analytics// src/app/layout.tsx
import { Analytics } from '@vercel/analytics/react';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Analytics />
</body>
</html>
);
}Speed Insights
npm install @vercel/speed-insightsimport { SpeedInsights } from '@vercel/speed-insights/next';
// Add alongside Analytics
<SpeedInsights />Deployment Checklist
Before going live:
- [ ] All environment variables set
- [ ] CORS configured on WordPress
- [ ] Production build tested locally
- [ ] Sitemap accessible at
/sitemap.xml - [ ] Robots.txt configured
- [ ] SSL certificate active
- [ ] Webhook for revalidation working
- [ ] Analytics tracking enabled
- [ ] Error monitoring set up (Sentry, etc.)
Summary
In this lesson, we:
- ✅ Prepared the project for production
- ✅ Deployed to Vercel
- ✅ Configured WordPress for production
- ✅ Set up on-demand revalidation
- ✅ Added analytics and monitoring
Congratulations! 🎉 You've built and deployed a complete headless WordPress site with Next.js!
Next Steps
- Add a search feature
- Implement comments
- Add newsletter signup
- Create custom post types
- Add authentication for previews