How to get geolocation from user with Next.js?
Asked Answered
M

2

6

I am learning the Next.js. I want to get the latitude and longitude from user. And then call the API. My code is like that:

import Navbar from "../../comps/Navbar";
import Link from "next/link";
import Head from "next/head";
import styles from '../../styles/Mensen.module.css'
import { useEffect } from "react";
import { useState } from "react";
import Location from "../../comps/Location";
import navigator from "react";

export const getStaticProps = async (context) => {    
    const res = await fetch('https://openmensa.org/api/v2/canteens?near[lat]=' + lat+ '&near[lng]=' + long + '&near[dist]=50000');
    const data = await res.json();

    return {
      props: { mensen: data }
    }
}

const Mensen = ({mensen}) => {    
    return ( 
        <>
        <Head>
            <title>HTW Mensa | Mensen</title>
            <meta name="keywords" content="mensa"/>
        </Head>
        <Location />
        <div>
            <h1>Alle Mensen</h1>
            <p>Alle Mensen</p>
            {mensen.map(mensa => ( 
                <Link href={'/mensen/' + mensa.id} key={mensa.id}>
                    <a className={styles.single}> 
                        <h3>{ mensa.name }</h3>
                    </a>
                </Link>))}
        </div>
        </>
    );
}
 
export default Mensen;

The API uses latitude and longitude from user to give the places nearby. I saw that someone recommend using useEffect. But I'm not sure about that.

Could someone help me?

Mistranslate answered 11/9, 2022 at 21:2 Comment(2)
getStaticProps runs on the server at build time, it can't access user-specific information like geolocation. You'll have to move the logic to the client-side or use SSR instead.Cark
@Cark thank you . could you maybe show me how i should do . Because i'm new with javascript and next.js . Thank you so muchMistranslate
C
7

Since getStaticProps runs on the server at build time, it can't access user-specific information like geolocation. You'll have to move the logic to the client-side instead.


Here's an example of how to retrieve the user's geolocation using the Geolocation API built-in in browsers (note that the user is notified and asked to grant permission for the API to work).

import { useEffect, useState } from 'react'
import Link from 'next/link';

const Mensen = () => {
    const [mensen, setMensen] = useState([]);
    const [location, setLocation] = useState();

    const fetchApiData = async ({ latitude, longitude }) => {
        const res = await fetch(`https://openmensa.org/api/v2/canteens?near[lat]=${latitude}&near[lng]=${longitude}&near[dist]=50000`);
        const data = await res.json();
        setMensen(data);
    };

    useEffect(() => {
        if('geolocation' in navigator) {
            // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API
            navigator.geolocation.getCurrentPosition(({ coords }) => {
                const { latitude, longitude } = coords;
                setLocation({ latitude, longitude });
            })
        }
    }, []);

    useEffect(() => {
        // Fetch data from API if `location` object is set
        if (location) {
            fetchApiData(location);
        }
    }, [location]);
    
    return ( 
        <div>
            <h1>Alle Mensen</h1>
            <p>Alle Mensen</p>
            {mensen?.length > 0 && mensen.map(mensa => ( 
                <Link href={`/mensen/${mensa.id}`} key={mensa.id}>
                    <a className={styles.single}> 
                        <h3>{mensa.name}</h3>
                    </a>
                </Link>
            ))}
        </div>
    );
};

The component checks for the existence of navigator.geolocation, then tries to retrieve the current position of the user with navigator.geolocation.getCurrentPosition(). When successful, the location state variable is set which triggers the request to the openmensa.org API. Once the data is successfully fetched, the mensen state variable is set which renders the results on the page.

Cark answered 12/9, 2022 at 22:55 Comment(0)
S
1

My response is unfortunately a bit late, but hopefully it helps someone. The Next.js approach to retrieve the user's country involves using middleware and NextRequest. The middleware is called before each response, providing access to the request element. NextRequest extends the request element with additional parameters, such as 'geo,' where the user's city, country, region, latitude, and longitude are stored (Note: Only applicable when hosted on Vercel). To use this data in a component, it is recommended to store these details in a cookie and then retrieve them in the component. This method should be significantly more efficient as it avoids an extra fetch and simply reads existing data. For more information on this topic, refer to: https://nextjs.org/docs/pages/api-reference/functions/next-server

Sneakers answered 29/11, 2023 at 15:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.