如何在 NextJs 项目中获取页面 URL 或主机名?

Raj*_*mad 5 hostname domain-name base-url reactjs next.js

我想在静态站点生成器上获取页面的完整 URL 或站点主机名,如下图所示。

我会尝试使用window.location.hostname,但它不起作用。

错误:窗口未定义。

在此处输入图片说明

jam*_*her 35

通过服务器端渲染 ( getServerSideProps),您可以使用context.req.headers.host

import type { GetServerSideProps, NextPage } from "next";

type Props = { host: string | null };

export const getServerSideProps: GetServerSideProps<Props> =
  async context => ({ props: { host: context.req.headers.host || null } });

const Page: NextPage<Props> = ({ host }) => <p>Welcome to {host || "unknown host"}!</p>;

export default Page;
Run Code Online (Sandbox Code Playgroud)

但使用静态生成 ( getStaticProps) 时,主机名不可用,因为没有请求从中获取主机名。一般来说,服务器不知道自己的公共主机名,因此您需要告诉它。使用Next.js 环境变量,将其放入.env.local

HOST=example.com
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令访问它process.env['HOST']

import type { GetStaticProps } from "next";

export const getStaticProps: GetStaticProps<Props> = 
  async context => ({ props: { host: process.env['HOST'] || null }});
Run Code Online (Sandbox Code Playgroud)


小智 30

如果你想获取完整的 URL:

import { useRouter } from 'next/router';
Run Code Online (Sandbox Code Playgroud)
const { asPath } = useRouter();
    const origin =
        typeof window !== 'undefined' && window.location.origin
            ? window.location.origin
            : '';

    const URL = `${origin}${asPath}`;
    console.log(URL);
Run Code Online (Sandbox Code Playgroud)

  • 静态端渲染没有主机名。不可能,因为没有可用的请求 (2认同)
  • 在 Next.js 中,它将出现错误:水合失败,因为初始 UI 与服务器上呈现的内容不匹配。“下一个”:“12.1.6”,“反应”:“18.1.0”, (2认同)

Gan*_*ula 13

根据此处提到的答案,您可以使用以下代码使用新的应用程序目录(对于服务器端组件)获取 Next 13 中的主机名:

import { headers } from 'next/headers';

export default function Home() {
  const headersList = headers();
  
  headersList.get('host'); // to get domain
  headersList.get('next-url'); // to get url

  return <div>....</div>
}
Run Code Online (Sandbox Code Playgroud)

注意:请注意,在布局或页面中使用它会在请求时选择一条进入动态渲染的路线


小智 11

考虑这个包> next-absolute-url

import absoluteUrl from 'next-absolute-url'
const { origin } = absoluteUrl(req)
const apiURL = `${origin}/api/job.js`
Run Code Online (Sandbox Code Playgroud)

如果您现在部署了 Next.js 应用程序,则 apiURL 将类似于https://your-app.now.sh/api/job.js

但是,如果您在本地运行应用程序,则将使用 apiURL http://localhost:8000/api/job.js


Xai*_*roo 8

使用typeof window !== 'undefined'是安全的方法。if (window) {}会给你带来麻烦。

const hostname = typeof window !== 'undefined' && window.location.hostname ? window.location.hostname : '';
const origin = typeof window !== 'undefined' && window.location.origin ? window.location.origin : '';
Run Code Online (Sandbox Code Playgroud)

使用上面的代码将为您提供客户端使用的前端/外部主机名/来源:example.comwww.example.com等等www.example.com:80,而不是这些localhost内容。useRouter()将返回服务器端主机名/来源 ( localhost, localhost:3000)


chi*_*imo 8

我相信你最好结合使用useRouteruseEffect钩子来做到这一点。就我而言,我想动态设置og:url我的网页的。这就是我所做的。我们有router.pathname一个依赖项,因此ogUrl每次我们移动到不同的页面时都会更新它。

import { useRouter } from "next/router";
import { useState, useEffect } from "react";

const MyComponent = () => {

  const router = useRouter();
  const [ogUrl, setOgUrl] = useState("");


  useEffect(() => {
    const host = window.location.host;
    const baseUrl = `https://${host}`;

    setOgUrl(`${baseUrl}${router.pathname}`);
  }, [router.pathname]);


  return <div></div>
}
Run Code Online (Sandbox Code Playgroud)


Aad*_*raj 6

您访问的地方window确保添加检查,以便代码仅在浏览器上执行,而在 SSG 期间不执行”

if (typeof window !== 'undefined') {
   const hostname = window.location.hostname;
}
Run Code Online (Sandbox Code Playgroud)

更新:如果您已指定basePathnext.config.js

module.exports = {
  basePath: 'https://www.example.com/docs',
}
Run Code Online (Sandbox Code Playgroud)

然后使用useRouter,您可以访问基本路径:

import { useRouter } from 'next/router'

function Component() {
   const router = useRouter();
   
   console.log({ basePath: router.basePath}); 
   // { basePath: 'https://www.example.com/docs' }

   ...
}
Run Code Online (Sandbox Code Playgroud)

但是如果你有一个相对的基本路径,那么你可以使用第一种方法

  • 面对这个错误 https://prnt.sc/vyuuz2 (3认同)
  • `basePath` 部分不起作用,因为它仅用于缩短路径。您不能在那里使用网址。 (2认同)

Pra*_*bhu 6

如果您想要服务器端 getInitalProps 中的主机名,您仍然可以从 req 中获取它

Home.getInitalProps = async(context) => {
   const { req, query, res, asPath, pathname } = context;
   if (req) {
      let host = req.headers.host // will give you localhost:3000
     }
  }
Run Code Online (Sandbox Code Playgroud)

  • 它在构建时给出错误 https://prnt.sc/vyut51 (3认同)
  • 自 Next.js 9.3 起,不鼓励使用“getInitialProps”。使用“getStaticProps”或“getServerSideProps” (3认同)