You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 13(App Router):如何从Middleware向组件传递数据?

解决Next.js 13 App Router中Middleware向组件传递语言标识的问题

问题根源

你用Middleware设置Cookie后,组件首次加载无法读取的原因是:Cookie通过响应头的Set-Cookie字段下发给浏览器,浏览器只有收到完整响应后才会存储该Cookie。而首次渲染时(无论服务端还是客户端),组件读取的是请求阶段的Cookie,此时新Cookie还未被浏览器写入,自然拿不到;只有刷新后,请求头才会带上这个Cookie,组件才能读取。

下面是几个无需刷新就能直接传递语言标识的方案:


方案一:通过自定义响应头传递(推荐,支持服务端/客户端组件)

Middleware可以在响应中添加自定义HTTP头,组件能直接从请求头中读取该值,无需等待Cookie写入。

修改Middleware代码

import { NextResponse } from 'next/server'

export const middleware = (req) => {
    const pathname = req.nextUrl.pathname
    const language = pathname.split('/')[1]
    const allowedLanguages = ['en', 'de'];

    if(allowedLanguages.includes(language)) {
        const response = NextResponse.rewrite(new URL(pathname.replace(`/${language}`, ''), req.url))
        
        // 添加自定义响应头,替代Cookie
        response.headers.set('x-language', language)
        
        return response
    }
}

export const config = {
    matcher: ['/((?!assets|api|_next/static|favicon.ico).*)'],
}

在组件中读取语言标识

服务端组件(无需加'use client')

import { headers } from 'next/headers'

export default function Page() {
    const langHeaders = headers()
    const language = langHeaders.get('x-language') || 'en' // 设置默认值

    return <div>当前语言:{language}</div>
}

客户端组件(需加'use client')

'use client'

import { useHeaders } from 'next/headers'

export default function ClientComponent() {
    const headers = useHeaders()
    const language = headers.get('x-language') || 'en'

    return <div>当前语言:{language}</div>
}

方案二:客户端组件直接从URL解析(简单直接)

由于Middleware的rewrite是服务器内部重写,浏览器地址栏仍会保留原始URL(比如/en/asdf/),因此客户端组件可以直接通过Next.js提供的usePathname钩子解析路径中的语言标识,无需依赖Cookie或响应头。

客户端组件代码

'use client'

import { usePathname } from 'next/navigation'

export default function ClientComponent() {
    const pathname = usePathname()
    const language = pathname.split('/')[1] || 'en'
    // 可选:验证语言是否在允许列表内
    const allowedLanguages = ['en', 'de']
    const validLang = allowedLanguages.includes(language) ? language : 'en'

    return <div>当前语言:{validLang}</div>
}

方案三:结合服务器组件传递给子组件

如果你的页面是服务器组件,可以先在服务器组件中解析URL(或通过响应头获取语言),再将语言标识作为props传递给下游的客户端/服务器子组件。

服务器组件示例

import { headers } from 'next/headers'
import ClientComponent from './ClientComponent'

export default function Page() {
    const langHeaders = headers()
    const language = langHeaders.get('x-language') || 'en'

    // 将语言作为props传给子组件
    return <ClientComponent language={language} />
}

客户端子组件

'use client'

export default function ClientComponent({ language }) {
    return <div>当前语言:{language}</div>
}

内容的提问来源于stack exchange,提问作者pak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 14:15:53