score:0

afaik there are two ways of doing this:

  1. next js provides us with the userouter hook, first you have to import it in your component, then, to use the router object, you just have to declare it. for example:

    const router = userouter();

    console.log(router.pathname);

    const {pathname} = router; <---- to access the pathname directly.

besides this, as @xairoo said before, if you want to use the window object, you have to check if window !== 'undefined' to avoid errors. the window not defined error happens because next js use nodejs to render the app and the window object is not defined in node js.

you can find a more detailed explanation in this link.

score:0

req.headers are symbols and not objects, so to get value, you use the get method

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

score:0

in next.js you can do like this, by useeffect to get window.location.origin in client side, and set it to state.

work fine in : { "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;

score:1

you need to ensure your access to window.location.hostname happens on the client-side only, and not during server-side rendering (where window does not exist). you can achieve that by moving it to a useeffect callback in your component.

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
}

score:2

i believe you're better of doing this with a combination of userouter and useeffect hooks. in my case i wanted to dynamically set the og:url of my webpage. this is what i did. we have router.pathname as a dependency so that ogurl is updated every time we move to a different page.

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>
}

score:2

if you want to get the full url:

import { userouter } from 'next/router';
const { aspath } = userouter();
    const origin =
        typeof window !== 'undefined' && window.location.origin
            ? window.location.origin
            : '';

    const url = `${origin}${aspath}`;
    console.log(url);

score:5

using typeof window !== 'undefined' is the secure way. if (window) {} will run you into problems.

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

using above code will give you the frontend/outside hostname/origin the client using: example.com, www.example.com, www.example.com:80 and so on, not the localhost stuff. userouter() will return the server side hostname/origin (localhost, localhost:3000)

score:7

consider this package > next-absolute-url

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

if you deployed your next.js app with now the apiurl will be something like https://your-app.now.sh/api/job.js.

however, if you are running the app locally the apiurl will be http://localhost:8000/api/job.js instead.

score:8

the place where you are accessing the window make sure you add a check so that code is executed only on the browser and no during ssg"

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

update: if you have specified basepath in next.config.js:

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

then using userouter, you can access the base path:

import { userouter } from 'next/router'

function component() {
   const router = userouter();
   
   console.log({ basepath: router.basepath}); 
   // { basepath: 'https://www.example.com/docs' }

   ...
}

but if you have a relative base path then you can use the first approach

score:8

with server-side rendering (getserversideprops), you can use 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;

but with static generation (getstaticprops), the hostname is not available, because there is no request to get it from. in general, a server doesn't know its own public hostname, so you need to tell it. using next.js environment variables, put this in .env.local:

host=example.com

then access it with process.env['host']:

import type { getstaticprops } from "next";

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

score:22

if you want the hostname inside getinitialprops on server side, still you can get it from req

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

Related Query

More Query from same tag