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

求助:NextJS项目中如何在_document.js文件获取hostname?

在NextJS的_document.js中获取Hostname的解决方案

如果你的_document.js里getInitialProps的context.req是undefined,通常是因为代码在客户端执行了(比如客户端导航跳转)。以下是几种靠谱的解决方法:

1. 区分服务端/客户端环境动态获取

直接通过环境判断分别处理服务端和客户端的hostname获取逻辑,覆盖所有场景:

import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    let hostname = ''

    // 服务端:从请求头取,优先处理反向代理场景
    if (ctx.req) {
      hostname = ctx.req.headers['x-forwarded-host'] || ctx.req.headers.host
    } 
    // 客户端:直接访问window对象
    else {
      hostname = window.location.hostname
    }

    return { ...initialProps, hostname }
  }

  render() {
    return (
      <Html>
        <Head>
          {/* 示例:用hostname设置站点元信息 */}
          <meta property="og:site_name" content={this.props.hostname} />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

2. 用环境变量固定配置(适合域名不变的场景)

如果你的项目域名是固定的(比如开发环境localhost:3000,生产环境your-domain.com),直接在.env文件里配置全局变量:

# .env.local(开发环境)
NEXT_PUBLIC_HOSTNAME=localhost:3000

# .env.production(生产环境)
NEXT_PUBLIC_HOSTNAME=your-domain.com

然后在_document.js里直接引用:

const hostname = process.env.NEXT_PUBLIC_HOSTNAME

这种方法最简单,不需要处理环境判断,适合域名固定的项目。

3. 针对App Router的替代方案(NextJS 13+)

如果你用的是App Router(取代了Pages Router的_document.js),在app/layout.js里可以这样获取:

import { headers } from 'next/headers'

export default function RootLayout({ children }) {
  let hostname = ''
  // 服务端:通过headers()获取
  try {
    hostname = headers().get('x-forwarded-host') || headers().get('host')
  } catch (e) {
    // 客户端:捕获服务端API调用错误,改用window
    hostname = window.location.hostname
  }

  return (
    <html lang="en">
      <head>
        <meta property="og:site_name" content={hostname} />
      </head>
      <body>{children}</body>
    </html>
  )
}

关键注意点

  • 反向代理场景(比如用Nginx、Vercel部署)下,必须优先用x-forwarded-host请求头,否则拿到的可能是代理服务器的域名,不是用户实际访问的地址。
  • _document.js仅在Pages Router中生效,App Router请用layout.js替代。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:00:21