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

Next.js客户端组件国际化问题:server-only无法在客户端组件中使用

解决Client Component中使用Server-only翻译字典的问题

方案1:服务器组件预取字典,通过Props传递给客户端组件

在页面或父级服务器组件中先获取翻译字典,再将其作为props传递给标记为"use client"的子组件,避免客户端直接导入server-only模块。

示例代码:

// 页面组件(Server Component,无需"use client")
import { getDictionary } from '@/lib/dictionary'
import ClientComponent from '@/components/ClientComponent'

export default async function Page({ params: { locale } }) {
  // 服务器端获取字典
  const dict = await getDictionary(locale)
  // 将字典传递给客户端组件
  return <ClientComponent dict={dict} />
}
// 客户端组件(标记"use client")
'use client'

type ClientComponentProps = {
  dict: Record<string, string>
}

export default function ClientComponent({ dict }: ClientComponentProps) {
  return <h1>{dict.hello_world}</h1>
}

方案2:封装API路由,客户端通过请求获取字典

把字典的获取逻辑封装成API路由,客户端组件通过HTTP请求获取翻译数据,绕开server-only的导入限制。

  1. 创建API路由:
// app/api/dictionary/[locale]/route.ts
import 'server-only'
import { getDictionary } from '@/lib/dictionary'
import { NextResponse } from 'next/server'

export async function GET(_: Request, { params }: { params: { locale: string } }) {
  const dict = await getDictionary(params.locale as any)
  return NextResponse.json(dict)
}
  1. 客户端组件用数据请求库(如SWR/React Query)获取:
'use client'

import useSWR from 'swr'

// 简单的请求封装
const fetcher = (url: string) => fetch(url).then(res => res.json())

export default function ClientComponent({ locale }: { locale: string }) {
  const { data: dict, isLoading } = useSWR(`/api/dictionary/${locale}`, fetcher)
  
  if (isLoading) return <p>加载中...</p>
  if (!dict) return <p>加载失败</p>
  
  return <p>{dict.greeting}</p>
}

方案3:静态打包字典到客户端(适合语言数量少的场景)

如果你的项目只有4种语言且字典体积不大,可以直接将所有语言的字典打包到客户端,无需server-only限制。

示例代码:

// app/lib/client-dictionary.ts(无server-only标记)
import en from '@/dictionaries/en.json'
import de from '@/dictionaries/de.json'
import fr from '@/dictionaries/fr.json'
import es from '@/dictionaries/es.json'

export const clientDictionaries = {
  en,
  de,
  fr,
  es
}

export const getClientDictionary = (locale: string) => {
  return clientDictionaries[locale as keyof typeof clientDictionaries] || en
}

客户端组件直接使用:

'use client'

import { getClientDictionary } from '@/lib/client-dictionary'

export default function ClientComponent({ locale }: { locale: string }) {
  const dict = getClientDictionary(locale)
  return <p>{dict.welcome}</p>
}

报错原因说明

你遇到的错误是因为server-only标记的模块会被Next.js强制限制在服务器环境运行,而客户端组件的所有依赖都必须能在浏览器中执行,直接导入server-only模块会打破这个边界。上述方案都是通过数据传递或客户端兼容的获取方式来规避这个限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:07:04