How I Fixed a Geolocation Permission Bug in a Next.js App

Published: (February 27, 2026 at 11:39 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

While contributing to Accuguide—an open‑source platform that helps people discover accessible places and services—I encountered an annoying bug: the browser asked for location permission on every single page load, even on pages where location data was irrelevant.

The Problem

Visiting any page on Accuguide triggered the prompt:

accuguide.org wants to know your location
  • Appeared on pages like /info/about and /legal/privacy.
  • Caused poor UX and hurt the Lighthouse “Avoids requesting permissions on page load” audit.
  • Expected behavior: request location only on the /search page and only when the user has typed a search query.

The location logic lived in a React context LocationProvider (app/contexts/location-context.tsx) with the following effect:

// ❌ The problem
useEffect(() => {
  requestLocationPermission()
}, [])

Because LocationProvider wrapped the entire app in the root layout, the effect ran on every page mount.

The Fix

1. Remove the automatic request from the provider

// ✅ Remove this entirely from LocationProvider
useEffect(() => {
  requestLocationPermission()
}, [])

Now LocationProvider only supplies the context; it no longer triggers a permission request on its own.

2. Request location only on the search page when needed

In app/search/page.tsx:

import { useSearchParams } from 'next/navigation';
import { useLocation } from '@/contexts/location-context';
import { useEffect } from 'react';

const searchParams = useSearchParams();
const query = searchParams.get('q');
const { requestLocationPermission, location } = useLocation();

useEffect(() => {
  if (query && !location) {
    requestLocationPermission();
  }
}, [query]);

Explanation

  • query – the search term from the URL (?q=coffee shops).
  • !location – request only if we don’t already have a location.
  • [query] – re‑run the effect only when the query changes.

Outcome

AspectBeforeAfter
Location promptAppeared on every pageAppears only on /search page
Trigger conditionOn mount (global)When a query exists on the search page
Lighthouse audit❌ Fails✅ Passes
User experienceConfusing, unnecessary promptsIntuitive, only when needed
  • No more permission prompts on unrelated pages.
  • Lighthouse audit now passes the “Avoids requesting permissions on page load” check.
  • Users understand why location is needed (they’re performing a search).

Lessons Learned

  • Side effects belong where they’re needed. Placing useEffect calls in a global provider causes them to run on every render of the provider, which may be far more often than intended.
  • Ask yourself: “Where does this actually need to happen?” and move the logic to that specific component or page.
  • Common pitfalls in React apps include:
    • Analytics tracking firing on pages where it isn’t required.
    • Cookie‑consent popups appearing multiple times.
    • Auth checks running unnecessarily on public pages.

Good vs. Bad Patterns

// ❌ Bad: side effect in a global provider
useEffect(() => {
  doSomethingThatShouldOnlyHappenInOnePlace();
}, []);
// ✅ Good: side effect scoped to the right component/page
useEffect(() => {
  if (conditionIsRight) {
    doSomethingThatShouldOnlyHappenInOnePlace();
  }
}, [dependency]);

Conclusion

By moving the location‑request logic out of the global LocationProvider and into the specific search page component, the permission prompt now appears only when truly necessary, improving both user experience and performance metrics.

If you found this helpful, check out the Accuguide repository and my GitHub profile for more examples.

0 views
Back to Blog

Related posts

Read more »

Did Your Project Really Need Next.js?

Introduction Recently, I’ve been seeing more and more teams migrating projects from Next.js to TanStack. Cases like Inngest, which reduced local dev time by 83...

The Last Dance with the past🕺

Introduction Hello dev.to community! A week ago I posted my first article introducing myself and explaining that I left web development to focus on cryptograph...