How to Fix 403 Forbidden Errors on Next.js Static Sites

Deploying a statically exported Next.js application to an Apache server should be straightforward. However, one of the most frustrating issues developers face is encountering "403 Forbidden" errors, particularly when navigating directly to a URL or when search engine bots try to index pages.
This guide explains why this happens and how to fix it definitively.
Why 403 Errors Happen on Static Next.js Sites
When you run next build with output: "export", Next.js generates static HTML files. By default, a page like /about is generated as /about.html.
If a user goes to yoursite.com/about, the server looks for a directory named "about". Since it doesn't find one (it's a file), and if you have rewrite rules trying to serve about.html, Apache can get confused. If your .htaccess tries to perform internal rewrites that conflict with directory permissions, or if it tries to serve a directory without an index.html, Apache throws a 403 Forbidden error. This is toxic for SEO because Googlebot assumes the page is restricted.
The Fix: Trailing Slashes and Directory Structure
The cleanest way to solve this is to force Next.js to output folders with index.html files inside them, rather than flat HTML files. This perfectly aligns with how Apache naturally serves static content.
Step 1: Update next.config.mjs
Open your next.config.mjs and add the trailingSlash: true option:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
trailingSlash: true, // This is the magic key
// ...other config
};
export default nextConfig;With this setting, the /about route will now be exported as /about/index.html instead of /about.html.
Step 2: Simplify Your .htaccess
Because Next.js is now generating a standard directory structure with index.html files, you no longer need complex, fragile rewrite rules in Apache. Your .htaccess can be incredibly simple.
Create or update the .htaccess file in your public folder (so it gets exported to your out directory):
# Disable directory listing for security
Options -Indexes
# Define custom 404 page
ErrorDocument 404 /404/index.html
# Security headers (optional but recommended)
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
</IfModule>Step 3: Rebuild and Deploy
Run your build command:
npm run buildUpload the newly generated out folder to your server.
Why This Approach is Better
Native Server Behavior: Apache is designed to serve index.html when a directory is requested. You aren't fighting the server with regex rewrites.
SEO Friendly: Search engines correctly follow the directory paths and index the pages without hitting permission walls.
No 403s: Because the directory exists and contains an index.html, the server never throws a Forbidden error.
By aligning your Next.js output with standard web server behavior, you eliminate the fragile rewrites that cause 403 errors and ensure your site is perfectly indexed by search engines.
Written by Waseem, a Senior Software Engineer with 12 years of experience in secure web infrastructure, file systems, and data processing. Founder and lead developer of ZipDownloader. Learn more about us →