search
next

Fix: Next.js 404 on page refresh (Vercel / Nginx) error

Quick fix for Next.js 404 on page refresh in Vercel or Nginx deployments. Learn how to configure proper routing for client-side navigation.

person By Gautam Sharma
calendar_today January 8, 2026
schedule 4 min read
Next.js 404 Routing Vercel Nginx Deployment SPA

The ‘Next.js 404 on page refresh’ error occurs when navigating to client-side routes directly or refreshing pages in deployed Next.js applications. This happens because the server doesn’t recognize client-side routes and returns a 404 error instead of serving the main index.html file.


How the Error Happens

❌ Error Scenario - Direct Route Access:

// ❌ This works with client-side navigation but fails on refresh
// Navigate to /dashboard directly in browser
// app/dashboard/page.js
export default function DashboardPage() {
  return <div>Dashboard Content</div>;
}

When users navigate directly to https://yoursite.com/dashboard or refresh the page, the server looks for a /dashboard route on the server, but in a SPA, all routes should serve the main application file.


✅ Quick Fix - Deployment Configuration

Solution 1: Vercel Configuration (Automatic)

// ✅ Vercel handles this automatically with Next.js projects
// vercel.json (optional, usually not needed)
{
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/"
    }
  ]
}

For most Next.js projects deployed on Vercel, this is handled automatically. If you’re experiencing issues, ensure your vercel.json doesn’t interfere with Next.js’s automatic routing.

Solution 2: Nginx Configuration

# ✅ Nginx configuration for Next.js SPA
# /etc/nginx/sites-available/yoursite
server {
    listen 80;
    server_name yoursite.com www.yoursite.com;
    
    location / {
        root /var/www/yoursite;
        index index.html;
        
        # ✅ Serve index.html for all routes
        try_files $uri $uri/ /index.html;
    }
    
    # ✅ Handle API routes separately
    location /api/ {
        proxy_pass http://localhost:3000;  # Your Next.js server
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Solution 3: Apache Configuration (.htaccess)

# ✅ Apache .htaccess for Next.js SPA
# .htaccess in your public directory
Options -MultiViews
RewriteEngine On

# ✅ Redirect all non-file requests to index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [L]

# ✅ Handle API routes separately if needed
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^(.*)$ http://localhost:3000/$1 [P,L]

Solution 4: Custom Server Configuration (Node.js)

// ✅ Custom Express server for Next.js
// server.js
const express = require('express');
const next = require('next');

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  // ✅ Handle API routes normally
  server.use('/api', (req, res) => {
    handle(req, res);
  });

  // ✅ Serve static files
  server.use(express.static('public'));

  // ✅ All other routes should serve index.html
  server.all('*', (req, res) => {
    handle(req, res);
  });

  const port = process.env.PORT || 3000;
  server.listen(port, () => {
    console.log(`Server running on port ${port}`);
  });
});

Solution 5: Docker Configuration

# ✅ Dockerfile with proper nginx configuration
# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine AS production
COPY --from=builder /app/out /usr/share/nginx/html

# ✅ Copy custom nginx config
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# ✅ nginx.conf for Docker deployment
events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    server {
        listen 80;
        root /usr/share/nginx/html;
        index index.html;

        # ✅ Handle Next.js routing
        location / {
            try_files $uri $uri/ /index.html;
        }

        # ✅ API routes (if using standalone mode)
        location /api/ {
            proxy_pass http://backend:3000;
        }
    }
}

Solution 6: Static Export Configuration

// ✅ For static exports, configure next.config.js
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export', // ✅ Generate static export
  trailingSlash: true, // ✅ Add trailing slashes to help with routing
  
  // ✅ Handle rewrites for static export
  async rewrites() {
    return [
      {
        source: '/:path*',
        destination: '/:path*/index.html',
      },
    ];
  },
};

module.exports = nextConfig;
# ✅ Nginx config for static export
server {
    listen 80;
    server_name yoursite.com;

    root /var/www/yoursite/out;
    index index.html;

    # ✅ Handle all routes for static export
    location / {
        try_files $uri $uri/ @fallback;
    }

    location @fallback {
        rewrite ^.*$ /index.html last;
    }

    # ✅ Handle static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
Gautam Sharma

About Gautam Sharma

Full-stack developer and tech blogger sharing coding tutorials and best practices

Related Articles

next

How to Fix Route '/' does not match any routes error

Quick fix for 'Route / does not match any routes' error. Learn how to resolve routing issues in React Router, Next.js, and other JavaScript frameworks.

January 10, 2026
next

Fix: useRouter only works in Client Components Error

Learn how to fix the 'useRouter only works in Client Components' error in Next.js applications. This comprehensive guide covers client components, server components, and proper routing implementation.

January 8, 2026
next

Fix: Middleware not running in Next.js error

Quick fix for middleware not running in Next.js. Learn how to properly configure and troubleshoot Next.js middleware.

January 8, 2026