<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: imamovelay0-hue</title>
    <description>The latest articles on DEV Community by imamovelay0-hue (@imamovelay0hue).</description>
    <link>https://dev.to/imamovelay0hue</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4067602%2Fd27b308d-cfc1-41fe-841e-6765ad2d1f40.png</url>
      <title>DEV Community: imamovelay0-hue</title>
      <link>https://dev.to/imamovelay0hue</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/imamovelay0hue"/>
    <language>en</language>
    <item>
      <title>I Built a Free GPS Altitude Finder — Here's What I Learned Shipping a PWA With No Backend</title>
      <dc:creator>imamovelay0-hue</dc:creator>
      <pubDate>Fri, 07 Aug 2026 13:48:03 +0000</pubDate>
      <link>https://dev.to/imamovelay0hue/i-built-a-free-gps-altitude-finder-heres-what-i-learned-shipping-a-pwa-with-no-backend-40fa</link>
      <guid>https://dev.to/imamovelay0hue/i-built-a-free-gps-altitude-finder-heres-what-i-learned-shipping-a-pwa-with-no-backend-40fa</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I kept wanting to know my exact altitude while hiking. Every option I found was either a bloated native app full of ads and permissions I didn't need, or a website that made me create an account before showing me a single number.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://zirve-pro.netlify.app" rel="noopener noreferrer"&gt;Zirvə&lt;/a&gt; — open it, allow location once, get your elevation above sea level in seconds. No install, no account, no ads.&lt;/p&gt;

&lt;p&gt;This post is about the two technical decisions that mattered most: how altitude is actually measured, and what happens when there's no signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Altitude is harder than it looks
&lt;/h2&gt;

&lt;p&gt;The obvious approach is &lt;code&gt;navigator.geolocation&lt;/code&gt; and reading &lt;code&gt;coords.altitude&lt;/code&gt;. It works — sometimes. Phone GPS chips measure vertical position much less accurately than horizontal position (think ±10–30m, versus a few meters for lat/lng), and plenty of devices — most desktops, some older phones — return &lt;code&gt;null&lt;/code&gt; for altitude entirely.&lt;/p&gt;

&lt;p&gt;The fix was to treat GPS altitude as a fallback, not the primary source. The primary source is a terrain elevation API (Open-Meteo), which returns the elevation of your exact coordinates from a real digital elevation model — accurate to about 1–3 meters, regardless of what your device's GPS chip can do.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function fetchElevation(lat, lon){
  try {
    const res = await fetch(elevationApiUrl(lat, lon));
    const data = await res.json();
    applyElevation(Math.round(data.elevation[0]));
  } catch(e) {
    // fall back to GPS altitude below
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  What happens with no signal
&lt;/h2&gt;

&lt;p&gt;This is the part that actually mattered for the use case. A hiker above the treeline, with no signal, still wants a number.&lt;/p&gt;

&lt;p&gt;If the terrain API call fails — timeout, offline, whatever — the app falls back to the raw altitude from the GPS fix that already ran. Locating requests lat, lng and altitude together, so there is no extra permission prompt and no extra round trip. If that is also unavailable, it shows nothing rather than a stale or fabricated number. A wrong altitude is worse than no altitude.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;catch(e){
  if(gpsAltitude === null){
    // device has no altitude data offline — say so, don't guess
    return;
  }
  applyElevation(gpsAltitude);
  markApproximate(); // UI shows "offline — approximate"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The UI marks the reading as approximate whenever it is GPS-sourced, so nobody mistakes ±20m for the API's ±2m.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PWA instead of a native app
&lt;/h2&gt;

&lt;p&gt;Zero install friction was the actual product requirement — someone finding this mid-hike shouldn't need an app store, a download, or a permission dialog beyond location. A service worker with a network-first strategy handles the rest: fresh code when there's a connection, cached shell when there isn't.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;self.addEventListener('fetch', e =&amp;gt; {&lt;br&gt;
  e.respondWith(&lt;br&gt;
    fetch(e.request)&lt;br&gt;
      .then(res =&amp;gt; cacheAndReturn(res))&lt;br&gt;
      .catch(() =&amp;gt; caches.match(e.request))&lt;br&gt;
  );&lt;br&gt;
});&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  What's next&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Right now it's a solo project I maintain in whatever time I have outside work. Next up: a proper elevation profile for the current session's track, and looking at whether a barometric-pressure fallback (where the device exposes it) could tighten the offline accuracy further.&lt;/p&gt;

&lt;p&gt;If you hike, climb, or just like knowing exactly how high you're standing — &lt;a href="https://zirve-pro.netlify.app" rel="noopener noreferrer"&gt;try it&lt;/a&gt;. Free, no ads, no sign-up. Feedback welcome, especially from anyone who's hit the offline fallback path for real.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>pwa</category>
    </item>
  </channel>
</rss>
