35

I am trying to send some text on basic of hosted URL (where my build is deployed), but I am getting this error:

ReferenceError: location is not defined

Here is my code.

export const getStaticProps = async ({ preview = false, previewData = {} }) => {
  return {
    revalidate: 200,
    props: {
      //req.host
      name: location.hostname == "www.google.com" ? "Hello" : "ccccc"
    }
  };
};
1
  • 3
    Hello, could you please accept my answer? So that more people could see a solution quickly. Commented Dec 28, 2021 at 20:11

5 Answers 5

103

Can you show your imports, because it could be that you are importing router from 'next/client'

Assuming that you are using functional-based component

You need to import router as follows:

import {useRouter} from "next/router";

import {useRouter} from "next/navigation"; // nextjs v13+

in your function body:

const router = useRouter();

Edit, those who're using NextJS v13+ The router has been moved from next/router to next/navigation https://nextjs.org/docs/app/api-reference/functions/use-router

Sign up to request clarification or add additional context in comments.

1 Comment

👊 Thanks this sorted me out. Was an IDE auto-import.
7

if you are using next js this might occur, if you have a client page and you used useRouter to push the user to another page on that client page so that client page is rendered on server page that let the 'location is not defined' problem/error these problems mostly appears at build time so what you have to do is that in that client page use useEffect hook and let that routing code be in it. like useEffect(() => {router.push('/signin')},[]). this may be fix the error.

Comments

4

The router has been moved from next/router to next/navigation. It still imports from next/router. Please keep that in mind when working with Next.js 13+. Additionally, Next.js tries to render it on the server first. However, location, window, router are client-side. What helped me was to wrap my conditional in useEffect.

1 Comment

Thanks for the update @Akk1, I modified my answer
1

getStaticProps() is executed at build time in Node.js, which has no location global object – Location is part of the browser API. Additionally, because the code is executed at build time, the URL is not yet known.

  1. Change getStaticProps to getServerSideProps (see documentation). This will mean the function is called at runtime, separately for each request.
  2. From the context object passed to getServerSideProps, pull out the Node.js http.IncomingMessage object.
  3. On this object, look for the Host header.
export const getServerSideProps = async ({ req }) => {
  return {
    props: {
      name: req.headers.host === "www.google.com" ? "Hello" : "ccccc"
    }
  };
};

Note:

  • I also changed == to ===, as it's generally advised to use the latter. The former can produce some unexpected results because of silent type conversions.
  • I also removed revalidate, as this is not applicable to getServerSideProps().

Comments

1

Next.js use App Runner

'use client'

/* use 'next/navigation' instead of 'next/router' */
import {useRouter} from 'next/navigation' 
import {useEffect} from 'react'

export default function Page(){
  const router = useRouter()  

  /* try to wrap the router.push into useEffect */
  useEffect(()=>{
    router.push('/some/where')
  })

  return <></>

}

1 Comment

Small typo userRouter -> useRouter

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.