Google and many other sites know my correct location. How can I fake my location without using a VPN, proxy, Tor or similar?

I went to about:config and looked for geo. What I think I have to modify is geo.wifi.uri? Maybe we can put in false lattitude and longitude values directly? If so, how would it look then? I really have no idea about the format.

Or is there another way using JavaScript in Greasemonkey?

Faking the Geolocation
You can spoof the location provided via the HTML5 Geolocation API this way:

Go to about:config.

Type in geo.provider.network.url (or geo.wifi.uri in older versions)

Change the value to something like this:
data:application/json,{"location": {"lat": 40.7590, "lng": -73.9845}, "accuracy": 27000.0}

(The lat and lng values determine the latitude and longitude of your location.

Confirm that geo.enabled is true.

You may also need to set geo.provider.testing to true. (Create the key if it doesn't exist.)

Congratulations, you're now on Times Square! (Verify the result here.)


Note: This does not stop websites from deriving the location from your IP address. You can't do that on the application layer and would have to go with a proxy instead.
Disabling the Geolocation
For privacy reasons, you may want to prevent use of the API entirely:

Go to about:config and set geo.enabled to false.

Some technical details
The Geolocation service in Firefox is set up in dom/geolocation/Geolocation.cpp. Following nsGeolocationService::Init() you see that without geo.enabled, the API initialization is aborted right away:
  if (!StaticPrefs::geo_enabled()) {
    return NS_ERROR_FAILURE;
  }

Further, the browser chooses between different location providers based on your platform and settings. As you see, there are prefs to switch them individually (e.g., if you're on MacOS,  you can set geo.provider.use_corelocation to false to disable geolocating via Apple's Core Location API):
#ifdef MOZ_WIDGET_ANDROID
  mProvider = new AndroidLocationProvider();
#endif

#ifdef MOZ_WIDGET_GTK
#  ifdef MOZ_GPSD
  if (Preferences::GetBool("geo.provider.use_gpsd", false)) {
    mProvider = new GpsdLocationProvider();
  }
#  endif
#endif

#ifdef MOZ_WIDGET_COCOA
  if (Preferences::GetBool("geo.provider.use_corelocation", true)) {
    mProvider = new CoreLocationLocationProvider();
  }
#endif

#ifdef XP_WIN
  if (Preferences::GetBool("geo.provider.ms-windows-location", false) &&
      IsWin8OrLater()) {
    mProvider = new WindowsLocationProvider();
  }
#endif

  if (Preferences::GetBool("geo.provider.use_mls", false)) {
    mProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1");
  }


Only if none of the platform-specific providers apply, or if geo.provider.testing is true, Firefox defaults to the network (URL-based) provider:
  if (!mProvider || Preferences::GetBool("geo.provider.testing", false)) {
    nsCOMPtr<nsIGeolocationProvider> geoTestProvider =
        do_GetService(NS_GEOLOCATION_PROVIDER_CONTRACTID);

    if (geoTestProvider) {
      mProvider = geoTestProvider;
    }
  }

The network provider (dom/system/NetworkGeolocationProvider.jsm) then requests the URL specified in geo.provider.network.url. You could set up your own mock HTTP location serivce and enter its URL here. But more easily, as in the steps at the top, it's sufficient use a data: pseudo URI to mimic a network provider that unconditionally responds with your desired location details.
