DEV Community

Mohsen Fallahnejad
Mohsen Fallahnejad

Posted on Edited on Originally published at bitlyst.blog

CDN Explained: What It Is, How It Works, and How to Use It in Next.js

A CDN (Content Delivery Network) is a global network of servers that cache and serve your static assets — JS, CSS, images, fonts — from a location close to the user.

Without a CDN, every user hits your origin server (wherever it's hosted).

With a CDN, they hit the nearest edge node instead.


🌍 How It Works

User (Tokyo) → CDN Edge (Tokyo)
  ├─ Cache HIT ✓ → Instant Response
  └─ Cache MISS → Origin Server → Cache → Respond
Enter fullscreen mode Exit fullscreen mode
  1. User requests /logo.png
  2. CDN checks its edge cache
  3. Cache hit → served immediately from edge
  4. Cache miss → CDN fetches from your origin, caches it, serves it

Next request from any user near that edge? Instant.


📦 What Gets Cached?

Asset type Cached by CDN?
JS / CSS bundles ✅
Images / fonts ✅
HTML (static) ✅
API responses ⚠️ optional
Dynamic SSR pages ⚠️ optional

⚡ Why It Matters for Frontend

  • Lower latency — assets served from 50ms away, not 300ms
  • Less load on your server — CDN absorbs most traffic
  • Better Core Web Vitals — faster LCP, less layout shift
  • Global scale — same performance in Tokyo as in London

🔧 CDN in Next.js

Next.js is CDN-ready out of the box. Here's what gets cached automatically:

Static assets in /public

Served with long-lived cache headers automatically.

next/image

Images are optimized and served via CDN edge with proper Cache-Control.

Static pages (SSG)

Pages generated at build time are cached at the CDN edge.


⚙️ Configuration

1. Custom CDN with assetPrefix

If you're using your own CDN (Cloudflare, CloudFront, etc.):

// next.config.js
module.exports = {
  assetPrefix: 'https://cdn.yourdomain.com',
}
Enter fullscreen mode Exit fullscreen mode

Next.js will now load all /_next/static/ assets from your CDN URL.


2. Cache-Control headers

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/static/(.*)',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=31536000, immutable',
          },
        ],
      },
    ]
  },
}
Enter fullscreen mode Exit fullscreen mode
  • max-age=31536000 → cache for 1 year
  • immutable → browser won't revalidate even on hard refresh

3. Per-fetch CDN caching (App Router)

// cached for 1 hour at the CDN edge
const data = await fetch('https://api.example.com/posts', {
  next: { revalidate: 3600 },
})
Enter fullscreen mode Exit fullscreen mode

4. Page-level revalidation (ISR)

// app/blog/page.tsx
export const revalidate = 60 // revalidate every 60 seconds
Enter fullscreen mode Exit fullscreen mode

CDN serves the cached page, Next.js regenerates it in the background when stale.


5. Force static caching

export const dynamic = 'force-static'
Enter fullscreen mode Exit fullscreen mode

Tells Next.js (and the CDN) to never recompute — serve the static version always.


🧠 Cache-Control Cheat Sheet

Header value Meaning
public, max-age=31536000, immutable Cache forever (versioned assets)
public, s-maxage=3600 CDN cache for 1 hour
no-store Never cache
stale-while-revalidate=60 Serve stale, refresh in bg

✨ Final Takeaway

A CDN puts your assets next to your users. Next.js handles most of it automatically — configure assetPrefix for custom CDNs, and use revalidate to control how long pages stay cached at the edge.


Originally published on Bitlyst.

Top comments (0)

⌂ 换网址