Tarayıcıda kullanıcının konumunu almak için Geolocation API'yi kullanırsınız: navigator.geolocation.getCurrentPosition(basari, hata, secenekler) tek seferlik konum verir, watchPosition() konum değiştikçe geri çağrınızı tekrar çalıştırır, clearWatch() da izlemeyi durdurur. API yalnızca güvenli bağlamda (HTTPS) çalışır ve kullanıcı açıkça izin vermeden konum paylaşılmaz; izin reddedilirse hata geri çağrısı code değeri 1 olan bir GeolocationPositionError alır.
Bu yazıda konum isteme akışını, maximumAge, timeout ve enableHighAccuracy seçeneklerinin tam anlamını, dönen GeolocationPosition ve GeolocationCoordinates nesnelerinin her alanını, hata kodlarını, iframe ve izin politikası kurallarını, çalışan bir örneği ve sık yapılan hataları MDN belgelerine dayanarak anlatıyoruz. Serinin tamamı için Web API öğrenme rehberi sayfasına bakabilirsiniz.
Geolocation API nasıl çalışır?

API'nin giriş noktası navigator.geolocation özelliğidir ve bir Geolocation nesnesi döndürür. Bu nesne üzerinden konum istediğinizde tarayıcı kullanıcıdan izin ister; kullanıcı kabul ederse cihazdaki en uygun yöntemle, örneğin GPS ile konum belirlenir. MDN, konum kaynağının cihaza göre değiştiğini ve GPS'i olan cihazların ilk konum sabitlemesinin bir dakika veya daha uzun sürebileceğini, bu yüzden IP veya Wi-Fi tabanlı daha düşük doğruluklu verinin dönebileceğini belirtir.
Önce özelliğin varlığını kontrol etmek iyi bir alışkanlıktır. MDN'nin önerdiği kontrol "geolocation" in navigator ifadesidir: nesne varsa konum servisleri kullanılabilir demektir.
if ("geolocation" in navigator) {
// Konum servisi kullanılabilir
} else {
// Bu tarayıcıda konum servisi yok
}Konum almak için iki yöntem vardır ve ikisi de aynı üç parametreyi alır: zorunlu bir başarı geri çağrısı, isteğe bağlı bir hata geri çağrısı ve isteğe bağlı bir seçenekler nesnesi. Başarı geri çağrısı tek parametre olarak bir GeolocationPosition nesnesi alır; hata geri çağrısı bir GeolocationPositionError alır. Bu API sözler (promise) değil geri çağrılar kullanır; yazının ilerleyen bölümünde bunu nasıl söze saracağınızı göreceksiniz.
| Yöntem | Ne zaman çağrılır | Döndürdüğü |
|---|---|---|
| getCurrentPosition(basari, hata, secenekler) | Konum bir kez belirlenince | undefined |
| watchPosition(basari, hata, secenekler) | Konum her değiştiğinde veya daha doğru veri geldiğinde | İzleme kimliği (tamsayı) |
| clearWatch(kimlik) | Hemen; izlemeyi kaldırır | undefined |
Güvenlik, izin ve iframe kuralları
Konum verisi kişisel bilgi olduğu için API birkaç katmanla korunur. Birincisi güvenli bağlamdır: sayfanız HTTPS üzerinden sunulmalıdır. HTTP sayfalarda konum istemek çalışmaz; HTTPS geçişinde karşılaşılan sorunlar için karma içerik hatası ve HTTPS ve TLS 1.3 yazılarına bakabilirsiniz.
İkinci katman kullanıcı iznidir. MDN, izin durumu zaten granted veya denied değilse getCurrentPosition() ya da watchPosition() çağrıldığında kullanıcıya bir istem gösterilmesi gerektiğini söyler. Verilen iznin ne kadar süreceği tarayıcıya bağlıdır: zamana bağlı, oturuma bağlı ya da kalıcı olabilir. İzin durumunu kullanıcıyı rahatsız etmeden önceden öğrenmek için Permissions API'deki geolocation iznini sorgulayabilirsiniz; sonuç granted, denied veya prompt olur. Aşağıdaki kod MDN'deki örneğin uyarlamasıdır ve çalıştırılmadı:
navigator.permissions.query({ name: "geolocation" }).then((sonuc) => {
if (sonuc.state === "granted") {
yakindakileriGoster(); // İzin var, doğrudan konum istenebilir
} else if (sonuc.state === "prompt") {
konumDugmesiniGoster(); // Kullanıcı bir düğmeyle izin verebilir
}
// "denied" ise hiçbir şey yapma
});Üçüncü katman izin politikasıdır (Permissions Policy). geolocation yönergesinin varsayılan izin listesi self değeridir; yani konum yalnızca aynı kökenden gelen iç içe çerçevelerde kullanılabilir. Başka bir kökenden yüklenen bir iframe içindeki haritanın konum alabilmesi için iki şey gerekir: üst sayfanın yanıtında o kökene izin veren bir başlık ve iframe öğesinde allow özniteliği. MDN'deki örnek şöyledir:
Permissions-Policy: geolocation=(self b.example.com)<iframe src="https://b.example.com" allow="geolocation"></iframe>Bu iki ayardan biri eksikse gömülü sayfa konum istediğinde hata geri çağrısı PERMISSION_DENIED alır. MDN hata kodları tablosunda, izin politikasıyla engellenmenin de bu kodun nedenleri arasında olduğunu açıkça yazar. Güvenli bağlam ve izin hatalarının genel listesi DOMException ve güvenli bağlam hataları yazısında.
getCurrentPosition ve seçenekler

Tek seferlik konum için getCurrentPosition() çağırırsınız. Tarayıcı eşzamansız bir istek başlatır, konum belirlendiğinde başarı geri çağrınız çalışır. MDN varsayılan davranışın mümkün olduğunca hızlı ve düşük doğruluklu bir yanıt vermek olduğunu belirtir; bu, doğruluktan çok hızın önemli olduğu durumlar için uygundur. Davranışı üç seçenekle ayarlarsınız:
| Seçenek | Varsayılan | Anlamı |
|---|---|---|
| maximumAge | 0 | Kabul edilebilecek önbellekteki konumun milisaniye cinsinden en büyük yaşı. 0 ise önbellek kullanılmaz, Infinity ise yaşına bakılmadan önbellekteki konum döner. |
| timeout | Infinity | Cihazın konum döndürmek için kullanabileceği en uzun süre (ms). Infinity iken konum gelene kadar yanıt dönmez. |
| enableHighAccuracy | false | true ise cihaz yapabiliyorsa daha doğru konum verir; yanıt yavaşlayabilir ve güç tüketimi artabilir. |
Bu tablodaki en önemli ayrıntı timeout varsayılanıdır. Değeri vermezseniz bekleme süresi sonsuzdur; konum hiç belirlenemezse kullanıcı arayüzünüz sonsuza kadar "Konum aranıyor" durumunda kalabilir. Bu yüzden pratikte her zaman makul bir timeout verin. maximumAge ise pil ve hız dengesini kurar: örneğin 30 saniye verirseniz, son 30 saniye içinde alınmış bir konum varsa yeni ölçüm yapılmadan o kullanılır. MDN'nin örneği şöyle:
const secenekler = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0,
};
function basari(konum) {
const k = konum.coords;
console.log(`Enlem: ${k.latitude}`);
console.log(`Boylam: ${k.longitude}`);
console.log(`Yaklaşık ${k.accuracy} metre doğrulukla.`);
}
function hata(err) {
console.warn(`HATA(${err.code}): ${err.message}`);
}
navigator.geolocation.getCurrentPosition(basari, hata, secenekler);Konum nesnesinin yapısı
Başarı geri çağrısına gelen GeolocationPosition nesnesinin yalnızca iki özelliği vardır: coords ve timestamp. timestamp, konumun cihaz tarafından alındığı anı Unix zamanı olarak milisaniye cinsinden verir; Date.now() ile aynı birimdedir, bu yüzden konumun ne kadar eski olduğunu hesaplamak için ikisini çıkarabilirsiniz. coords ise bir GeolocationCoordinates nesnesidir ve koordinatlar WGS84 sistemine göre verilir.
| Özellik | Birim | null olabilir mi | Açıklama |
|---|---|---|---|
| latitude | ondalık derece | Hayır | Enlem |
| longitude | ondalık derece | Hayır | Boylam |
| accuracy | metre | Hayır | Enlem ve boylamın yüzde 95 güven düzeyindeki doğruluğu, kesinlikle pozitif |
| altitude | metre | Evet | WGS84 elipsoidine göre yükseklik |
| altitudeAccuracy | metre | Evet | Yükseklik değerinin doğruluğu |
| heading | derece | Evet | Gerçek kuzeyden saat yönünde hareket yönü; doğu 90, batı 270. Hız 0 ise null |
| speed | metre/saniye | Evet | Cihazın hızı, ölçülemiyorsa null |
Bu tablo iki pratik sonuç doğurur. Birincisi, accuracy değerini mutlaka kullanın: 2000 metre doğrulukla gelen bir konumu bir sokak adresine çevirmek kullanıcıyı yanıltır. Haritada nokta yerine doğruluk yarıçapında bir daire çizmek daha dürüsttür. İkincisi, altitude, heading ve speed değerlerinin null gelebileceğini varsayın; masaüstü tarayıcılarda bu alanların dolu olmasını beklemeyin. heading özellikle cihaz dururken her zaman null olur.
Konumu sunucuya göndermek veya kaydetmek istediğinizde JSON.stringify(konum) doğrudan çalışır, çünkü iki arayüz de toJSON() metoduna sahiptir ve JSON.stringify() bunu otomatik çağırır. MDN'nin gösterdiği örnek çıktı şuna benzer (okunabilirlik için biçimlendirilmiş hali):
{
"timestamp": 1717509611840,
"coords": {
"accuracy": 13.5,
"latitude": 53.125,
"longitude": 8.75,
"altitude": null,
"altitudeAccuracy": null,
"heading": null,
"speed": null
}
}JSON serileştirmenin ayrıntıları için JSON.parse ve JSON.stringify yazısına bakabilirsiniz.
watchPosition ve clearWatch ile konumu izlemek
Navigasyon, koşu takibi veya teslimat izleme gibi senaryolarda tek konum yetmez. watchPosition() aynı parametreleri alır ama geri çağrınızı birden çok kez çalıştırır: cihaz hareket ettikçe ya da farklı yöntemlerle daha doğru bir konum belirlendikçe. MDN hata geri çağrısının da tekrar tekrar çağrılabileceğini belirtir; yani bir zaman aşımı hatası aldıktan sonra izleme devam edebilir. Önce getCurrentPosition() çağırmanız gerekmez, izlemeye doğrudan başlayabilirsiniz.
watchPosition() bir tamsayı kimlik döndürür. Bu kimliği saklayıp işiniz bittiğinde clearWatch(kimlik) ile izlemeyi kaldırmalısınız; aksi halde konum donanımı çalışmaya devam eder. MDN'nin hedefe ulaşınca izlemeyi durduran örneğinin uyarlaması:
let kimlik;
const hedef = { latitude: 41.0082, longitude: 28.9784 };
function basari(konum) {
const k = konum.coords;
if (hedef.latitude === k.latitude && hedef.longitude === k.longitude) {
console.log("Hedefe ulaştınız");
navigator.geolocation.clearWatch(kimlik);
}
}
function hata(err) {
console.error(`HATA(${err.code}): ${err.message}`);
}
kimlik = navigator.geolocation.watchPosition(basari, hata, {
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 0,
});Bu örnek kavramı göstermek için koordinatları birebir karşılaştırıyor. Gerçek bir uygulamada konum her ölçümde biraz oynadığı için tam eşitlik neredeyse hiç sağlanmaz; iki nokta arasındaki mesafeyi hesaplayıp accuracy değeriyle birlikte bir eşikle karşılaştırmak gerekir. Sayfa arka plana alındığında izlemeyi durdurmak da mantıklıdır; görünürlük değişikliğini yakalamak için sayfa yaşam döngüsü yazısındaki visibilitychange olayını kullanabilirsiniz.
Hata kodları ve doğru mesajlar

Hata geri çağrısına gelen GeolocationPositionError nesnesinin iki özelliği vardır: sayısal code ve insan tarafından okunabilir message. MDN, spesifikasyona göre message alanının hata ayıklama amaçlı olduğunu ve doğrudan kullanıcı arayüzünde gösterilmemesi gerektiğini not eder. Kullanıcıya göstereceğiniz metni code değerine göre kendiniz üretin:
| code | Sabit | Ne zaman | Kullanıcıya önerilebilecek mesaj |
|---|---|---|---|
| 1 | PERMISSION_DENIED | İzin yok; kullanıcı reddetti veya izin politikası engelledi | Konum izni verilmedi. Adresi elle girebilirsiniz. |
| 2 | POSITION_UNAVAILABLE | Konum kaynaklarından en az biri iç hata verdi | Konumunuz şu an belirlenemiyor. |
| 3 | TIMEOUT | timeout süresi konum gelmeden doldu | Konum zamanında alınamadı, tekrar deneyin. |
function hataMesaji(err) {
switch (err.code) {
case err.PERMISSION_DENIED:
return "Konum izni verilmedi. Adresi elle girebilirsiniz.";
case err.POSITION_UNAVAILABLE:
return "Konumunuz şu an belirlenemiyor.";
case err.TIMEOUT:
return "Konum zamanında alınamadı, tekrar deneyin.";
default:
return "Konum alınamadı.";
}
}Çalışan örnek: düğmeyle konum gösterme
MDN'nin rehberindeki örnek, konumu sayfa açılır açılmaz değil, kullanıcı bir düğmeye tıkladığında ister ve sonucu bir harita bağlantısına dönüştürür. Bu yaklaşım kullanıcıya izin isteminin neden çıktığını anlatır. Örneği Türkçeleştirdik ve bir zaman aşımı ekledik; tarayıcı gerektirdiği için çalıştırılmadı.
<button id="konumum" type="button">Konumumu göster</button>
<p id="durum"></p>
<a id="harita" href="" target="_blank">Konum bilinmiyor</a>function konumBul() {
const durum = document.querySelector("#durum");
const harita = document.querySelector("#harita");
harita.href = "";
harita.textContent = "";
function basari(konum) {
const { latitude, longitude, accuracy } = konum.coords;
durum.textContent = `Doğruluk: yaklaşık ${Math.round(accuracy)} m`;
harita.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
harita.textContent = `Enlem: ${latitude}, Boylam: ${longitude}`;
}
function hata(err) {
durum.textContent = hataMesaji(err);
}
if (!navigator.geolocation) {
durum.textContent = "Tarayıcınız konum servisini desteklemiyor.";
} else {
durum.textContent = "Konum aranıyor...";
navigator.geolocation.getCurrentPosition(basari, hata, { timeout: 10000 });
}
}
document.querySelector("#konumum").addEventListener("click", konumBul);Geri çağrıları söze sarmak
Kodunuzun geri kalanı async/await kullanıyorsa getCurrentPosition() çağrısını küçük bir yardımcıyla söze çevirebilirsiniz. Başarı geri çağrısı sözü çözer, hata geri çağrısı reddeder. Bu, API'nin kendisinin bir özelliği değil, dilin sunduğu genel bir kalıptır; ayrıntısı async/await rehberi yazısında.
function konumAl(secenekler) {
return new Promise((coz, reddet) => {
navigator.geolocation.getCurrentPosition(coz, reddet, secenekler);
});
}
document.querySelector("#konumum").addEventListener("click", async () => {
try {
const konum = await konumAl({ timeout: 10000, maximumAge: 60000 });
console.log(konum.coords.latitude, konum.coords.longitude);
} catch (err) {
console.warn(hataMesaji(err));
}
});MDN ayrıca konum verisini işlemek için alternatif bir mekanizma olarak HTML tarafında bir <geolocation> öğesinden söz eder; tutarlı bir arayüz ve daha anlaşılır izin yönetimi sunmayı amaçlar. Tarayıcı desteği için MDN uyumluluk tablosuna bakın. HTML öğeleri HTML öğrenme rehberi serisinin konusudur. MDN'nin bir notu da bölgesel erişilebilirlikle ilgilidir: Wi-Fi tabanlı konum çoğu zaman Google tarafından sağlandığı için standart API'nin Çin'de kullanılamayabileceğini ve orada yerel sağlayıcıların tercih edilebileceğini belirtir.
Sık yapılan hatalar
- Sayfa açılır açılmaz konum istemek. Kullanıcı nedenini anlamadan istemle karşılaşır ve sıklıkla reddeder. İsteği bir düğmeye bağlayın.
timeoutvermemek. VarsayılanInfinityolduğu için konum gelmezse yanıt hiç dönmeyebilir.- Hata geri çağrısını atlamak. İzin reddi veya zaman aşımı sessizce kaybolur, arayüz yükleniyor durumunda takılı kalır.
accuracydeğerini yok saymak. Düşük doğruluklu bir konum, kesin bir adresmiş gibi gösterilmemeli.clearWatch()çağırmamak. İzleme gereksiz yere sürer ve pil tüketir.messagemetnini kullanıcıya göstermek. Bu alan hata ayıklama içindir; kullanıcı mesajınıcodedeğerinden üretin.- HTTP veya yanlış yapılandırılmış iframe üzerinde test etmek. Güvenli bağlam ve izin politikası olmadan konum alınamaz.
Sık Sorulan Sorular
Konum neden bazen yüzlerce metre sapıyor?
Varsayılan istek hızlı ve düşük doğruluklu bir yanıtı tercih eder; cihaz IP veya Wi-Fi tabanlı bir tahmin döndürebilir. Daha doğru sonuç için enableHighAccuracy: true verin, ama yanıtın yavaşlayabileceğini ve güç tüketiminin artabileceğini kabul edin. Her durumda accuracy değerine bakın.
Kullanıcı izni reddettiyse tekrar sorabilir miyim?
İzin durumu denied olduğunda MDN'nin anlattığı istem gösterilmez; kullanıcı izni tarayıcı ayarlarından değiştirmelidir. Permissions API ile durumu sorgulayıp reddedilmişse kullanıcıya adresi elle girme seçeneği sunmak en iyi yoldur.
Konum ne kadar süre önbellekte tutulur?
Bunu siz maximumAge ile belirlersiniz. Varsayılan 0 olduğu için önbellek kullanılmaz ve her istekte yeni konum aranır. Değeri artırırsanız o süreden genç bir konum varsa yeniden ölçüm yapılmadan döndürülür.
Konumu bir Web Worker içinde alabilir miyim?
Bu yazıda kullandığımız MDN sayfaları API'ye navigator.geolocation üzerinden, sayfa bağlamında erişimi anlatır. Konumu sayfada alıp ağır hesaplamaları bir worker'a göndermek güvenli bir yoldur; ileti alışverişi Web Workers yazısında.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Web API öğrenme rehberi · DOMException ve güvenli bağlam hataları · Sayfa yaşam döngüsü · Notifications API ve izinler · Kamera ve mikrofon erişimi · Karma içerik hatası