Skip to content
GitHub Twitter

Using Next Middleware to access and use geolocation in a non dynamic route

I don’t use Middleware from Next.js often, but I have dabbled a few times. Recently someone in another Developer’s Discord, I also have a Discord if you want to chat Jamstack, asked about how to add the Geolocation to a non-dynamic page.

What is middleware?

Middleware allows you to use code over configuration. This gives you so much more flexibility over how your applications act when a user visits. The Middleware runs before the incoming request is completed, this allows you to modify the response by rewriting, redirecting, adding headers, or even streaming HTML.

Adding Geolocation

Depending on your situation, depends on where you need your middleware.(js.tsx) for this example it will run on every page. However, you can use it in nested routes to run for specific pages or dynamic routes.

Create your file in the root of your application, inside that file you need to import {NextResponse} from “next/server”

Then create export async function middleware(req){} this is where we are going to be doing the work to add our user's location.

The Middleware from Next.js has access to cookies, nextUrl , i18n , ua, geo, ip in the request which means we can use this to add geolocation to our application.

To rewrite our request we are going to need to access the nextUrl and geo from our request.

For example const { nextUrl: url, geo } = req now we can modify the nextUrl to add searchParams (query parameters) to our request.

Then finally return our new URL using NextResponse below is the full request.

import {NextRequest,NextResponse } from 'next/server';

export async function middleware(req: NextRequest) {
    const { nextUrl: url, geo } = req;
    const country = geo.country || 'US';

    url.searchParams.set('country', country);

    return NextResponse.rewrite(url);
}

Updating our page

Now we need to add and use our geolocation to the page, to do that we need to first pass the middleware through getServerSideProps to pass it to the page. Currently, the middleware has all the info on the server.

export const getServerSideProps = ({ query }) => ({
    props: query
});

Finally, we can use it on the page, however, we want by passing the props to the page:

import Head from 'next/head';
import Image from 'next/image';
import styles from '../styles/Home.module.css';
import { useRouter } from 'next/router';


export const getServerSideProps = ({ query }) => ({
    props: query
});

export default function Home(props) {
    // use it right from the props
    console.log(props.country);
    // or you can grab it from the router.
    const router = useRouter();

    console.log(router.query);
    return (
        <div className={styles.container}>
            <Head>
                <title>Create Next App</title>
                <meta name="description" content="Generated by create next app" />
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <main className={styles.main}>
                <h1 className={styles.title}>Welcome to {props.country}</h1>
            </main>
        </div>
    );
}

Now you can handle whatever you need knowing the geolocation.

One thing to note, geolocation made not be available so just be cautious, that is why we have a back up plan of US