5

I'm surprised I can't find this anyway but here is my issue. I have a Next JS site with the path /location/[location].js The page looks pretty basic

import { nodes } from '../../components/data/nodes'

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

    useEffect(() => {
         //Do various things   
    }, [])
   
    return (
        <Layout>
             ...My website...
        </Layout>
    )
}

and nodes looks like this

export const nodes = [
{
    id: 'Test1'
}, {
    id: 'Test2'
}, {
    id: 'Test3'
}]

So how can I say if my [location] slug does not match any node id's go to the 404 page? I tried some janky garbage that just feels wrong and throws console errors:

var counter = 1
  for (var node of nodes) {
    if (router.query.location == node.id) {
      break
    } else if (counter++ >= nodes.length) {
      return <Error statusCode={404} />
    }
  }

Can someone help me work this out. Thanks

MomasVII
  • 4,641
  • 5
  • 35
  • 52

4 Answers4

4

I'd prefer you to use getStaticProps & getStaticPaths In order to solve this problem. You can use the getStaticProps to fetch the static props. and to define what paths are valid you can use getStaticPaths and load the paths from your nodes variable. If the path doesn't exist you can then simply return a 404 error instead of props

Please refer the official document of Next.js to know more about the getStaticProps & getStaticPaths

udoyhasan
  • 1,527
  • 5
  • 19
1

You can easily define a state and according to state render your component.

import Error from "next/error";

// inside functional component
 const [errorCode , setErrorCode] = useState(0);
 const router = useRouter():
 
 useEffect(() => {
  const location =  router.query.location
  const search = nodes.filter(item => item.id === location ):
  if(search.length === 0){
    setErrorCode(404)
  }
 },[])
 
 if (errorCode == 404) {
   return (
      <Error statusCode={errorCode} title="page Not Found" />
   </>
   );
}
return (
  <Layout>
         ...My website...
    </Layout>
)
Paiman Rasoli
  • 1,088
  • 1
  • 5
  • 15
1

Okay so there are lots of reasons why you would want to use ssr over ssg, especially when building an ecommerce store or something similar, while using getStaticPaths will solve the issue, if you want a solution for getServerSideProps, this is my solution:

If you know how the data is formated, in this case the product has a title, then you can use this to set up an error in the returned props.

export async function getServerSideProps({ params }) {
    const slug = params.slug;

    const res = await fetch(`https://someAPI`);
    const product = await res.json();

    return {
        props: {
            params,
            product,
            slug,
            error: !recipe.title 
        }
    }
}

Then somewhere in the component:

function YourComponent({ product, slug, error }) {

    // If there is no product matching the slug
    const router = useRouter();
    if(error) {
        useEffect(() => {
            router.push('/404');
        }, [])
        return
    }

    return (
        //some JSX
    )
1

For nextjs 13,

You can use function notfound()

Refer here
https://nextjs.org/docs/app/api-reference/functions/not-found

In your case, when the location is not found in the nodes array, simply call function

notFound()

var counter = 1
  for (var node of nodes) {
    if (router.query.location == node.id) {
      break
    } else if (counter++ >= nodes.length) {
      notFound()
    }
  }
Meera Datey
  • 1,913
  • 14
  • 15