Skip to main content

文件约定

middleware.js

用于编写中间件,并在请求完成之前在服务器上运行的代码;

根据传入的请求,可以通过重写、重定向、修改请求或响应标头或者直接响应来修改响应;

中间件在渲染路由之前,它对于实现自定义服务器端逻辑:

  • 身份认证
  • 日志记录
  • 重定向

特别有用。

一般地,该文件与app或pages同一级,或在src内;

配置对象

可以和中间件一起导出,该对象包括匹配器来指定中间件应用的路径;

matcher

运行指定中间件运行的特定路径:

  • 单个路径,/about
  • 多个路径,['/about', '/contact']
  • 复杂路径,['/((?!api|_next/static|_next/image|.*\\.png$).*)']

matcher还接收具有以下键的对象:

  • source,匹配请求路径或模式

  • regexp,微调正则,路径的额外控制

  • locale,设置为false时,忽略路径匹配中基于区域设置的路由

  • has,根据特定请求元素(header、query、cookie)的存在来指定条件

  • missing,重点关注缺少某些请求元素的情况,例如缺少标头或cookie

export const config = {
matcher: [
{
source: '/api/*',
regexp: '^/api/(.*)',
locale: false,
has: [
{ type: 'header', key: 'Authorization', value: 'Bearer Token' },
{ type: 'query', key: 'userId', value: '123' },
],
missing: [{ type: 'cookie', key: 'session', value: 'active' }],
},
],
}

水合报错

原因:服务器预渲染的React树和在浏览器中第一次渲染时渲染的React树不一致

常见类型

  • 不正确的元素嵌套
  • 服务端和客户端属性不匹配
  • 服务端渲染时使用浏览器API
  • 使用非确定性内容
  • 浏览器插件修改html
  • 不正确的css-in-js配置
  • 不正确的Edge/CDN配置修改html响应

不正确的元素嵌套

  • p嵌套p
  • p嵌套div
  • p嵌套ul或ol
  • 交互式内容嵌套(a嵌套a,button嵌套button等等)

解决方法:避免这种元素结构

服务端和客户端属性不匹配

场景:

<p style={{ color: excessDays <= 3 && !isUsed ? '#E33618' : '' }}></p>
Warning: Prop `style` did not match. Server: "null" Client: "color:"

服务端渲染时使用浏览器API

服务端渲染时使用window、localStorage等浏览器特定API

解决方法:使用useEffect确保仅在客户端使用这些API

使用非确定性内容

比如,Date()

解决方法:避免使用

浏览器插件修改html

比如,Apollo Client Devtools

解决方法:禁用该插件或恢复修改内容

不正确的css-in-js配置

比如,styled-component

解决方法:参考next官网配置 https://nextjs.org/docs/pages/building-your-application/routing/custom-document

不正确的Edge/CDN配置修改html响应

使用边缘网络(Edge Network)或内容分发网络(CDN)时,如果这些服务尝试修改 HTML 响应(例如 Cloudflare 的自动压缩功能),可能会导致 Next.js 的水合报错;

比如,Cloudflare Auto Minify

解决方法:禁用