DH
4 min read

Deploying Next.js to Vercel - Complete Guide to Free Optimizations

A step-by-step guide to deploying Next.js 15 to Vercel, with essential optimizations for performance and cost using Cloudflare CDN and static generation.

nextjsvercel

These are the bare minimum optimizations I apply to every Next.js site I deploy to Vercel. They're all free, take just a few minutes to implement, and make a significant difference to performance and SEO. I've used this exact setup on numerous production sites, from small projects to applications serving millions of users.

This guide shows you exactly how to implement these essential optimizations step by step.

Prerequisites

  • Next.js 15 project
  • Vercel account
  • Custom domain

Steps

1. Analyzing Build Output

When deploying to Vercel, carefully monitor your build output to understand how your pages are being rendered. This helps optimize both performance and function call usage within the free tier.

# Run build locally to check rendering methods
next build

Look for ƒ (Dynamic) server-rendered on demand indicators in the build output, as these show which routes will consume function executions on Vercel.

2. Free CDN Integration with Cloudflare

2.1 DNS Configuration

Set up Cloudflare as a free CDN by configuring your DNS:

  1. Add your domain to Cloudflare
  2. Set proxy status to OFF initially (gray cloud)
  3. Let Vercel validate the domain
  4. Enable proxy (orange cloud)
  5. Set SSL mode to 'Full' in Cloudflare SSL/TLS settings

2.2 Free Image Optimization

Utilize Cloudflare's free image optimization:

  1. Enable Images in your Cloudflare dashboard
  2. Create an image loader file:
// image-loader.ts
export default function cloudflareLoader({ src, width, quality }) {
const params = [`width=${width}`, `quality=${quality || 75}`, 'format=auto']
return `https://example.com/cdn-cgi/image/${params.join(',')}/${src}`
}

Configure Next.js to use Cloudflare's image optimization:

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
images: {
loader: process.env.NODE_ENV === 'production' ? 'custom' : 'default',
loaderFile: process.env.NODE_ENV === 'production' ? './image-loader.ts' : undefined,
}
}

3. Performance and SEO Optimizations

3.1 Generate a Sitemap

Install and configure next-sitemap to automatically generate a sitemap:

npm install next-sitemap

Create a sitemap configuration file:

// next-sitemap.config.js
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
generateIndexSitemap: false,
changefreq: 'weekly',
priority: 0.7,
robotsTxtOptions: {
additionalSitemaps: [],
policies: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/*'],
},
],
},
}

Add the build script to your package.json:

{
"scripts": {
"postbuild": "next-sitemap"
}
}

3.2 Static Generation

Ensure your public-facing, high-traffic pages are static/SSG for optimal performance and to avoid function calls. Key pages that should be static:

  • Homepage
  • Landing pages
  • Blog posts
  • Documentation pages

For high-traffic pages that need occasional updates, use revalidate instead of making them dynamic:

// app/blog/page.tsx
export const revalidate = 3600 // Revalidate every hour

For dynamic routes that should be static:

// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getPosts()

return posts.map((post) => ({
slug: post.slug,
}))
}

3.2 Middleware Usage

Middleware runs on every request to your application, which counts against your Vercel edge middleware invocations limit. To maximize your free tier allowance, carefully limit middleware to only the routes that absolutely require it:

  • Avoid running middleware on public-facing pages like your homepage, blog, or marketing pages
  • Only use middleware for authenticated sections (like customer dashboards)
  • Be specific with your path matches to prevent unnecessary edge invocations
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
return NextResponse.next()
}

// Configure middleware to run only on specific paths
export const config = {
matcher: [
'/app/:path*', // Customer application routes
'/dashboard/:path*', // Dashboard routes

// Using negated paths to exclude public routes
'/((?!api|_next/static|_next/image|favicon.ico).*)',
]
}

Watch your Vercel deployment analytics closely - if you see high middleware invocation counts, review your matcher configuration to ensure it's not running on static assets or public pages unnecessarily.

Conclusion

These zero-cost optimizations will help you maximize performance on Vercel's free tier while using Next.js 15. By leveraging Cloudflare's free CDN and image optimization, implementing strategic static generation, and carefully managing middleware usage, you can create a performant application while staying within free tier limits. Remember to regularly check your Vercel analytics to monitor function usage and adjust optimizations as needed.

Damian Hodgkiss

Damian Hodgkiss

Senior Staff Engineer at Sumo Group, leading development of AppSumo marketplace. Technical solopreneur with 25+ years of experience building SaaS products.

Creating Freedom

Join me on the journey from engineer to solopreneur. Learn how to build profitable SaaS products while keeping your technical edge.

    Proven strategies

    Learn the counterintuitive ways to find and validate SaaS ideas

    Technical insights

    From choosing tech stacks to building your MVP efficiently

    Founder mindset

    Transform from engineer to entrepreneur with practical steps