部署在DirectAdmin的Next.js动态页面刷新时出现404错误求助
解决DirectAdmin上Next.js静态导出应用动态路由404问题
问题根源
你使用output: 'export'静态导出Next.js应用后,动态路由(如/todo/[id])不会预先生成对应每个id的物理HTML文件。刷新页面或直接输入URL访问时,服务器会尝试寻找对应路径的文件,找不到则返回404;而通过Link组件跳转是Next.js前端路由在浏览器端处理,不需要服务器返回对应文件,因此能正常访问。
解决方案:配置服务器重写规则
需要让服务器将所有找不到对应文件/目录的请求转发到index.html,由Next.js前端路由接管处理。根据DirectAdmin使用的Web服务器,选择对应配置:
1. Apache环境(DirectAdmin默认)
在网站根目录(如public_html)创建或编辑.htaccess文件,添加以下规则:
RewriteEngine On # 排除实际存在的文件和目录(如CSS、JS、图片等静态资源) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 将所有不存在的请求转发到index.html RewriteRule ^(.*)$ /index.html [L]
2. Nginx环境
若你的DirectAdmin使用Nginx作为Web服务器,修改站点配置:
- 登录DirectAdmin,找到对应站点的「Custom HTTPD Config」或「Site Customizations」工具
- 在
server块内添加以下规则:
location / { try_files $uri $uri/ /index.html; }
保存后重启Nginx生效。
额外代码修正
你的pages/todo/[slug].jsx存在参数匹配错误:文件名是[slug].jsx,因此router.query中的参数名应为slug而非id,修正后代码如下:
import { useRouter } from 'next/router'; import { useState, useEffect } from 'react'; export default function Todo() { const router = useRouter(); const { slug } = router.query; const [todo, setTodo] = useState(null); useEffect(() => { async function fetchTodo() { const res = await fetch(`https://jsonplaceholder.typicode.com/todos/${slug}`); const data = await res.json(); setTodo(data); } if (slug) { fetchTodo(); } }, [slug]); if (!todo) { return <div>Loading...</div>; } return ( <div> <p>{todo.id}</p> <h1>{todo.title}</h1> </div> ); }
验证步骤
- 重新执行
npm run build生成最新静态文件 - 将
out目录下的所有文件上传到DirectAdmin网站根目录 - 刷新动态页面或直接输入URL测试,确认404问题解决
内容的提问来源于stack exchange,提问作者Amin Ghazi
相关产品推荐
相关产品推荐

