Как получить URL-адрес страницы или имя хоста в проекте NextJS?

#reactjs #next.js #hostname #domain-name #base-url

#reactjs #next.js #имя хоста #доменное имя #базовый url

Вопрос:

Я хочу получить полный URL-адрес страницы или имя хоста сайта, как показано на рисунке ниже в Static Site Generator.

Я попробую window.location.hostname , но это не сработает.

Ошибка: окно не определено.

введите описание изображения здесь

Ответ №1:

Если вам нужно имя хоста внутри getInitialProps на стороне сервера, вы все равно можете получить его из req

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

Комментарии:

1. Это выдает ошибку во время сборки prnt.sc/vyut51

2. Можете ли вы поделиться блоком кода, как я поделился, ошибка показывает «заменить» на неопределенный.

3. getInitialProps обескуражен, так как Next.js 9.3. Использовать getStaticProps или getServerSideProps

Ответ №2:

С помощью функции рендеринга на стороне сервера ( 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;
 

Но с помощью static generation ( getStaticProps ) имя хоста недоступно, потому что нет запроса на его получение. Как правило, сервер не знает своего собственного общедоступного имени хоста, поэтому вам нужно его сообщить. Использование Next.js переменные среды, поместите это в .env.local :

 HOST=example.com
 

Затем получите к нему доступ с помощью process.env['HOST'] :

 import type { GetStaticProps } from "next";

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

Ответ №3:

Рассмотрим этот пакет> следующий-абсолютный-url

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

Если вы развернули свой Next.js приложение с теперь apiURL будет выглядеть примерно так https://your-app.now.sh/api/job.js .

Однако, если вы запускаете приложение локально, http://localhost:8000/api/job.js вместо него будет использоваться apiURL.

Комментарии:

1. Я думаю, что это для запросов на стороне сервера в getInitialProps, но это тот ответ, который я ищу. в любом случае, спасибо

2. @Necrofantaisie Похоже next-absolute-url , что он также поддерживает клиентскую часть github.com/jakeburden/next-absolute-url/blob/master /…

Ответ №4:

Место, к которому вы обращаетесь window , убедитесь, что вы добавили проверку, чтобы код выполнялся только в браузере, а не во время SSG »

 if (typeof window !== 'undefined') {
   const hostname = window.location.hostname;
}
 

Обновить:
Если вы указали basePath в next.config.js :

 module.exports = {
  basePath: 'https://www.example.com/docs',
}
 

Затем, используя useRouter , вы можете получить доступ к базовому пути:

 import { useRouter } from 'next/router'

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

   ...
}
 

Но если у вас есть относительный базовый путь, вы можете использовать первый подход

Комментарии:

1. Эта basePath деталь не работает, так как она используется только для сокращения пути. Вы не можете использовать там URL-адрес.

Ответ №5:

Использование typeof window !== 'undefined' — это безопасный способ. if (window) {} это приведет вас к проблемам.

 const hostname = typeof window !== 'undefined' amp;amp; window.location.hostname ? window.location.hostname : '';
const origin = typeof window !== 'undefined' amp;amp; window.location.origin ? window.location.origin : '';
 

Использование приведенного выше кода даст вам интерфейс / внешнее имя хоста / источник, который клиент использует: example.com , www.example.com , www.example.com:80 и так далее, а не localhost материал. useRouter() вернет имя хоста / источника на стороне сервера ( localhost , localhost:3000 )

Ответ №6:

Если вы хотите получить полный URL-адрес:

 import { useRouter } from 'next/router';
 
 const { asPath } = useRouter();
    const origin =
        typeof window !== 'undefined' amp;amp; window.location.origin
            ? window.location.origin
            : '';

    const URL = `${origin}${asPath}`;
    console.log(URL);
 

Комментарии:

1. это не возвращает имя хоста

2. @ekkis origin дает вам имя хоста и asPath указывает остальную часть пути.

3. для статического рендеринга нет имени хоста. не может быть, потому что запрос недоступен

4. в Next.js Он выдаст сообщение об ошибке: сбой гидратации произошел из-за того, что начальный пользовательский интерфейс не соответствует тому, что было отображено на сервере. «next»: «12.1.6», «react»: «18.1.0»,

Ответ №7:

Я считаю, что вам лучше сделать это с помощью комбинации useRouter и useEffect крючков. В моем случае я хотел динамически настроить 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>
}
 

Ответ №8:

Вам необходимо убедиться, что ваш доступ window.location.hostname происходит только на стороне клиента, а не во время рендеринга на стороне сервера (где window его не существует). Вы можете добиться этого, переместив его в useEffect обратный вызов в вашем компоненте.

 function Component() {
    useEffect(() => {
        console.log(window.location.hostname) 
        console.log(window.location.href) // Logs `http://localhost:3000/blog/incididunt-ut-lobare-et-dolore`
    }, [])
    
    // Remaining code of the component
}
 

Ответ №9:

AFAIK есть два способа сделать это:

  1. Next JS предоставляет нам хук useRouter, сначала вы должны импортировать его в свой компонент, затем, чтобы использовать объект router, вам просто нужно его объявить. Например:

    const router = Пользовательский маршрут();

    console.log(имя пути к маршрутизатору);

    const {pathname} = маршрутизатор; <—- Для прямого доступа к имени пути.

Кроме того, как уже говорил @Xairoo, если вы хотите использовать объект window, вы должны проверить, window !== 'undefined' чтобы избежать ошибок. Ошибка window not defined возникает из-за того, что Next JS использует NodeJS для рендеринга приложения, а объект window не определен в Node JS.

Вы можете найти более подробное объяснение по этой ссылке.

Ответ №10:

req.заголовки — это символы, а не объекты, поэтому для получения значения вы используете метод get

 const host = req.headers.get("host"); // stackoverflow.com
 

Комментарии:

1. и как мне получить req объект на странице NextJS?

2. на самом деле это для промежуточного программного обеспечения в next.js и страницы API

Ответ №11:

в Next.js вы можете сделать так, используя эффект, чтобы получить окно.location.origin на стороне клиента и установите для него значение state.

отлично работает в: { «next»: «12.1.6», «react»: «18.1.0», }

 const Home: NextPage = () => {
  const { asPath, query } = useRouter();

  const [loading, setLoading] = useState(false);
  const [loginCallBackURL, setLoginCallBackURL] = useState("");
 
  useEffect(() => { 
      setLoginCallBackURL(
        `${window.location.origin}/${query.redirect ? query.redirect : "user"}`,
      ); 
  }, []);

  // if you do something like this, it can't get loginCallBackURL
  // const loginCallBackURL = useMemo(() => {
  //   if (typeof window !== 'undefined') {
  //     return `${window.location.origin}/${
  //       query.redirect ? query.redirect : "user"
  //     }`;
  //   }
  //   return asPath;
  // }, [asPath, query]);
 
  return (
    <div>
      <Button
        variant="contained" 
        href={queryString.stringifyUrl({
          url: `${publicRuntimeConfig.API_HOST}/auth/google/login`,
          query: {
            callbackURL: loginCallBackURL,
          },
        })}
      >
        Sign in with google
      </Button>
    </div>
  );
};

export default Home;