Ödeme adresi alanı, mobil dönüşümlerin öldüğü yerdir. Kullanıcı ürün sayfanıza giriyor, sepete ürün ekliyor, ödemeye geçiyor ve ardından 6 inçlik dokunmatik ekran klavyesinde tam cadde adresini yazmak zorunda kalıyor. Posta kodunu yanlış yazarsa, ev numarası formatını karıştırırsa ya da vazgeçerse, zaten kazandığınız bir satışı kaybediyorsunuz.
Adres otomatik tamamlama bunu çözüyor. Uygulamanın ardından adres girişi 15-25 tuş vuruşundan 3-4'e düşüyor. Kullanıcı bir cadde adı yazmaya başlıyor, yarım saniye içinde eşleşen bir öneri görüyor, dokunuyor ve cadde, ev numarası, şehir, posta kodu, ülke dahil tüm adres otomatik ve doğru biçimde dolduruluyor. Yazım hatalarından kaynaklanan başarısız teslimler azalıyor. Ödeme terki azalıyor. Ve kritik olarak, lojistik ve rota sistemlerinizin doğrudan kullanabileceği doğrulanmış, coğrafi kodlanmış koordinatlar her siparişe ekleniyor.
E-ticaret uygulamalarındaki araştırmalar, adres otomatik tamamlaması eklendikten sonra ödeme tamamlama oranlarında tutarlı biçimde %25-35 iyileşme gösteriyor. Bu etki, manuel metin girişinin en yavaş ve en hata eğilimli olduğu mobilde önemli ölçüde daha güçlü. Mobil öncelikli pazarları hedefleyen bazı uygulamalar tam %35'i bildiriyor.
Bu öğretici, MapAtlas Geocoding API kullanarak gecikme kontrolü (debouncing), klavye navigasyonu, AB adres format yönetimi ve form entegrasyonu dahil eksiksiz bir React adres otomatik tamamlama bileşeni oluşturuyor. Tam bileşen yaklaşık 90 satır.
Adres Hataları Dönüşümleri Neden Öldürür
Başarısız teslimler her yönde maliyetlidir: taşıyıcı yeniden teslimat ücreti alır, müşteri hizmetleri ekibiniz şikayeti ele alır ve müşterinin markanıza güveni sarsılır. B2C e-ticarette adres giriş hataları, tüm teslimat istisnalarının yaklaşık %5-8'ini oluşturuyor.
Temel nedenler öngörülebilir:
- Mobil klavye girişi masaüstüne kıyasla daha fazla yazım hatası üretiyor. Otomatik düzeltme sık sık cadde ve şehir adlarını bozuyor.
- Posta kodu formatları ülkeye göre farklılık gösterir. İngiltere formatı (AN NAA) bekleyen bir alana 5 haneli kod giren Alman müşteri doğrulama hatası tetikleyecek.
- Cadde/ev numarası sıralaması AB ülkeleri arasında farklıdır. Almanya ve Hollanda'da ev numarası cadde adının ardından gelir. Fransa'da önce gelir. Manuel giriş formları kullanıcıları nadiren doğru yönlendiriyor.
- Daire ve kat gösterimleri standart bir formata sahip değildir. Kullanıcılar kargo taşıyıcınızın beklediğiyle sıklıkla örtüşmeyen, doğal hissettiren formatta girerler.
Otomatik tamamlama, önceden doğrulanmış, yapılandırılmış bir adres nesnesi döndürerek bu sorunların çoğunu atlatıyor. Kullanıcı ne istediğini seçiyor ve formunuz doğru formatı alıyor.
MapAtlas Geocoding Otomatik Tamamlama Uç Noktası
Otomatik tamamlama önerileri için uç nokta:
GET https://api.mapatlas.eu/geocoding/v1/autocomplete?text={query}&key={YOUR_API_KEY}
AB e-ticareti için önemli isteğe bağlı parametreler:
| Parametre | Tür | Açıklama |
|---|---|---|
text | string | Kısmi adres sorgusu |
focus.point.lon | number | Kullanıcının boylamı (yakın sonuçları önceliklendirir) |
focus.point.lat | number | Kullanıcının enlemi (yakın sonuçları önceliklendirir) |
boundary.country | string | ISO 3166-1 alpha-3 ülke kodu (ör. DEU, FRA, NLD) |
layers | string | Sonuç türlerini filtrele: address, street, locality |
size | number | Sonuç sayısı (varsayılan 10, maksimum 20) |
Tipik bir yanıt:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [4.9041, 52.3676] },
"properties": {
"id": "address:node/1234567",
"label": "Damrak 1, 1012 LG Amsterdam, Netherlands",
"name": "Damrak 1",
"street": "Damrak",
"housenumber": "1",
"postalcode": "1012 LG",
"locality": "Amsterdam",
"region": "North Holland",
"country": "Netherlands",
"country_code": "NL",
"confidence": 0.98
}
}
]
}
Her sonuç, yapılandırılmış adres bileşenleriyle GeoJSON özelliği olarak geliyor. Formunuz her alana doğrudan ekleyebileceğiniz veya rota ve teslimat planlaması için koordinatlarla birlikte tek bir nesne olarak saklayabileceğiniz temiz, doğrulanmış veriler alıyor.
React Otomatik Tamamlama Hook'unu Oluşturma
API mantığını yeniden kullanılabilir bir hook'a çıkararak başlayın. Bu bileşeni temiz tutar ve hook'u bağımsız olarak test edilebilir kılar.
// hooks/useAddressAutocomplete.js
import { useState, useEffect, useRef } from 'react';
const API_BASE = 'https://api.mapatlas.eu/geocoding/v1/autocomplete';
const API_KEY = process.env.NEXT_PUBLIC_MAPATLAS_KEY;
const DEBOUNCE_MS = 300;
const MIN_CHARS = 3;
export function useAddressAutocomplete(countryCode = null) {
const [query, setQuery] = useState('');
const [suggestions, setSuggestions] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const debounceTimer = useRef(null);
useEffect(() => {
if (query.length < MIN_CHARS) {
setSuggestions([]);
return;
}
clearTimeout(debounceTimer.current);
debounceTimer.current = setTimeout(async () => {
setLoading(true);
setError(null);
try {
const url = new URL(API_BASE);
url.searchParams.set('text', query);
url.searchParams.set('key', API_KEY);
url.searchParams.set('size', '6');
url.searchParams.set('layers', 'address');
if (countryCode) {
url.searchParams.set('boundary.country', countryCode);
}
const res = await fetch(url.toString());
if (!res.ok) throw new Error(`API error: ${res.status}`);
const data = await res.json();
setSuggestions(data.features ?? []);
} catch (err) {
setError(err.message);
setSuggestions([]);
} finally {
setLoading(false);
}
}, DEBOUNCE_MS);
return () => clearTimeout(debounceTimer.current);
}, [query, countryCode]);
return { query, setQuery, suggestions, loading, error };
}
Gecikme zamanlayıcısı yalnızca kullanıcı 300 ms yazmayı duraksattıktan sonra tetikleniyor. MIN_CHARS koruması, sonuçların çok geniş olacağı 1-2 karakterlik girişlerde API çağrılarını engelliyor. Her iki önlem de API kullanımının (ve maliyetlerin) gerçek kullanıcı niyetiyle orantılı kalması için kritik.
Otomatik Tamamlama Bileşeni
// components/AddressAutocomplete.jsx
import { useState, useRef } from 'react';
import { useAddressAutocomplete } from '../hooks/useAddressAutocomplete';
export function AddressAutocomplete({ onSelect, countryCode, placeholder }) {
const { query, setQuery, suggestions, loading } = useAddressAutocomplete(countryCode);
const [open, setOpen] = useState(false);
const [highlighted, setHighlighted] = useState(-1);
const inputRef = useRef(null);
function handleSelect(feature) {
const p = feature.properties;
setQuery(p.label);
setOpen(false);
setHighlighted(-1);
onSelect({
label: p.label,
street: p.street ?? '',
housenumber: p.housenumber ?? '',
postalcode: p.postalcode ?? '',
locality: p.locality ?? '',
region: p.region ?? '',
country: p.country ?? '',
country_code: p.country_code ?? '',
coordinates: feature.geometry.coordinates, // [lng, lat]
});
}
function handleKeyDown(e) {
if (!open || suggestions.length === 0) return;
if (e.key === 'ArrowDown') setHighlighted(h => Math.min(h + 1, suggestions.length - 1));
if (e.key === 'ArrowUp') setHighlighted(h => Math.max(h - 1, 0));
if (e.key === 'Enter' && highlighted >= 0) handleSelect(suggestions[highlighted]);
if (e.key === 'Escape') setOpen(false);
}
return (
<div style={{ position: 'relative' }}>
<input
ref={inputRef}
type="text"
value={query}
placeholder={placeholder ?? 'Start typing your address...'}
onChange={e => { setQuery(e.target.value); setOpen(true); setHighlighted(-1); }}
onKeyDown={handleKeyDown}
onBlur={() => setTimeout(() => setOpen(false), 150)}
style={{ width: '100%', padding: '10px 12px', fontSize: 16, borderRadius: 6, border: '1px solid #ccc' }}
autoComplete="off"
aria-autocomplete="list"
aria-haspopup="listbox"
aria-expanded={open && suggestions.length > 0}
/>
{loading && (
<span style={{ position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)', fontSize: 12, color: '#888' }}>
Searching…
</span>
)}
{open && suggestions.length > 0 && (
<ul
role="listbox"
style={{
position: 'absolute', top: '100%', left: 0, right: 0, zIndex: 999,
background: '#fff', border: '1px solid #ccc', borderTop: 'none',
borderRadius: '0 0 6px 6px', listStyle: 'none', margin: 0, padding: 0,
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
}}
>
{suggestions.map((feature, i) => (
<li
key={feature.properties.id}
role="option"
aria-selected={i === highlighted}
onMouseDown={() => handleSelect(feature)}
onMouseEnter={() => setHighlighted(i)}
style={{
padding: '10px 12px',
cursor: 'pointer',
fontSize: 14,
background: i === highlighted ? '#f0f7e6' : '#fff',
borderBottom: i < suggestions.length - 1 ? '1px solid #f0f0f0' : 'none',
}}
>
{feature.properties.label}
</li>
))}
</ul>
)}
</div>
);
}
Bileşen tam klavye navigasyonunu (ok tuşları, enter, escape), ekran okuyucu uyumluluğu için ARIA niteliklerini ve liste kapanmadan önce öneri üzerindeki fare tıklamalarının kaydedilmesi için 150 ms odak kaybı gecikmesini ele alıyor.
Ödeme Formuyla Entegrasyon
// pages/checkout.jsx
import { useState } from 'react';
import { AddressAutocomplete } from '../components/AddressAutocomplete';
export default function CheckoutPage() {
const [address, setAddress] = useState({
street: '', housenumber: '', postalcode: '',
locality: '', country: '', coordinates: null,
});
function handleAddressSelect(selected) {
setAddress(selected);
// Coordinates are available for routing/delivery estimation
console.log('Delivery coordinates:', selected.coordinates);
}
return (
<form>
<h2>Delivery address</h2>
<AddressAutocomplete
onSelect={handleAddressSelect}
countryCode="NLD" // Restrict to Netherlands, remove for EU-wide
placeholder="Start typing your street address..."
/>
{/* Show structured fields after selection, allow manual edits */}
{address.street && (
<div style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 8, marginTop: 12 }}>
<input value={address.street} onChange={e => setAddress(a => ({ ...a, street: e.target.value }))} placeholder="Street" />
<input value={address.housenumber} onChange={e => setAddress(a => ({ ...a, housenumber: e.target.value }))} placeholder="No." style={{ width: 80 }} />
<input value={address.postalcode} onChange={e => setAddress(a => ({ ...a, postalcode: e.target.value }))} placeholder="Postal code" />
<input value={address.locality} onChange={e => setAddress(a => ({ ...a, locality: e.target.value }))} placeholder="City" />
</div>
)}
<button type="submit" style={{ marginTop: 16 }}>
Continue to payment
</button>
</form>
);
}
Otomatik tamamlamanın ardından düzenlenebilir alanları ayrı ayrı göstermek erişilebilirlik ve uç durumlar için önemli. Kullanıcının gerçek kapı adresi, coğrafi kodlanmış sonucun içermediği daire numarası veya erişim kodu içerebilir. Otomatik tamamlama doğrulanmış temel adresi doldurur; kullanıcı geri kalanını ekler.
AB Adres Format Değerlendirmeleri
Farklı AB ülkelerinin hem görüntülemeyi hem de form alanı sırasını etkileyen adres kuralları vardır:
Almanya (DEU): Önce cadde, ardından ev numarası. Hauptstraße 42, 10115 Berlin. API'nin housenumber özelliği Almanca sonuçlarda caddeyi doğru biçimde takip ediyor.
Fransa (FRA): Ev numarası caddeden önce. 42 rue de Rivoli, 75001 Paris. label özelliği adresleri ülkeye uygun formatta döndürüyor.
Hollanda (NLD): Hollanda posta kodları 4 rakam + boşluklu 2 büyük harf: 1012 LG. Posta kodunu kargo sisteminiz için bölüyorsanız bu formatı doğrulayın.
Belçika (BEL): İkidilli bölgeler, belediyeye bağlı olarak Fransızca veya Flemenkçe adresler döndürebilir.
MapAtlas Geocoding API, ihtiyaç duyulması halinde ülkeye özgü form düzenleri oluşturabilmeniz için yapılandırılmış street, housenumber ve postalcode alanlarını da döndürürken bunların tamamını label alanında doğru biçimde ele alıyor (insan tarafından okunabilir, ülkeye uygun).
Mevcut adres veritabanlarının toplu doğrulaması için, bir teslimat hizmeti başlatmadan önce eski bir CRM'i temizlemek gibi, bkz. Geocoding API ile 10.000 Adresi Toplu Olarak Nasıl Doğrularsınız.
Performans Değerlendirmeleri
Yukarıdaki uygulama, yazılan ortalama 3-4 karakter başına yaklaşık bir API çağrısı yapıyor (300 ms gecikme hızlı yazmayı absorbe ediyor). Anlamlı ödeme hacmine sahip bir e-ticaret sitesi için API anahtarınızın hiçbir zaman istemci tarafı kodunda görünmemesi adına Geocoding API'nin önüne sunucu tarafı proxy'si kurun:
// pages/api/autocomplete.js (Next.js API route)
export default async function handler(req, res) {
const { text, countryCode } = req.query;
const url = new URL('https://api.mapatlas.eu/geocoding/v1/autocomplete');
url.searchParams.set('text', text);
url.searchParams.set('key', process.env.MAPATLAS_KEY); // Server-side env var
url.searchParams.set('size', '6');
url.searchParams.set('layers', 'address');
if (countryCode) url.searchParams.set('boundary.country', countryCode);
const response = await fetch(url.toString());
const data = await response.json();
res.json(data);
}
Ardından hook'u MapAtlas API'sini doğrudan çağırmak yerine /api/autocomplete'i çağıracak şekilde güncelleyin. Bu yaklaşım ayrıca yaygın sorgulardaki API çağrılarını azaltmak için uç katmanda (Vercel Edge Functions, Cloudflare Workers) istek önbelleğe alma eklemenize olanak tanır.
Mevcut Geocoding API oranları ve ücretsiz katman sınırları için MapAtlas Fiyatlandırma sayfasına bakın. Çoğu e-ticaret uygulaması için otomatik tamamlama kullanımı geliştirme sürecinde ücretsiz katmana rahatlıkla sığıyor.
Özet
Tek bir adres otomatik tamamlama alanı, ödeme dönüşüm oranınızı anlamlı ölçüde artırabilir. Uygulama basit: MapAtlas Geocoding API'ye gecikme kontrollü bir fetch, klavye navigasyonlu küçük bir açılır bileşen ve seçilen sonuçtan yapılandırılmış alanları dolduran form entegrasyonu.
Temel kararlar:
- 300 ms gecikme ile hızlı yazanlar için aşırı API çağrılarını önleyin.
- İstekleri tetiklemeden önce 3 karakter gerektirin.
- Kullanıcı tabanı coğrafyanızı biliyorsanız ülkeye göre kısıtlayın, bu sonuç alaka düzeyini önemli ölçüde artırır.
- Daire numaraları, erişim kodları ve düzeltmeler için otomatik tamamlanan alanların manuel olarak düzenlenmesine her zaman izin verin.
- Kimlik bilgilerini istemci paketlerinde açığa çıkarmamak için API anahtarını üretimde sunucu tarafında proxy aracılığıyla kullanın.
Adres alanının yanında ilk harita entegrasyonunuz için, onay sayfasında teslimat konumunu göstermek üzere Web Sitenize İnteraktif Haritalar Nasıl Eklenir bölümüne bakın.
Geliştirmeye başlamak için ücretsiz MapAtlas API anahtarına kaydolun. Geocoding API ücretsiz katmana dahil, kredi kartı gerekmez.
Sıkça Sorulan Sorular
Adres otomatik tamamlama ödeme dönüşümünü nasıl iyileştirir?
Adres girişi, özellikle mobilde çoğu ödeme akışının en fazla sürtünme yaratan adımıdır. Otomatik tamamlama bunu 2-3 tuş vuruşu ve ardından bir dokunuşa indirger, başarısız teslimlere yol açan format hatalarını ortadan kaldırır ve adresin doğru girilip girilmediği konusundaki endişeyi giderir. Araştırmalar, otomatik tamamlama uygulamasının ardından ödeme terkinde tutarlı biçimde %25-35 azalma gösteriyor.
MapAtlas Geocoding API Avrupa adres formatlarını destekliyor mu?
Evet. API, Almanca cadde adının ardından ev numarası sıralaması, Fransız arrondissement'ları, Hollanda 4 haneli posta kodları ve tüm AB üye devletlerindeki çok dilli adres formatları dahil AB'ye özgü formatları ele alır. Sonuçlar yapılandırılmış adres bileşenleriyle GeoJSON olarak döndürülür.
Otomatik tamamlama sırasında aşırı API çağrılarını nasıl önlerim?
Giriş işleyicisini 250-300ms gecikmeyle (debounce) yavaşlatın, böylece yalnızca kullanıcı yazmayı duraksattıktan sonra istek gönderin. Ayrıca istek tetiklenmeden önce minimum karakter eşiği (3-4 karakter) belirleyin. Bu iki önlem, her tuş vuruşunda tetiklemeye kıyasla API çağrılarını yaklaşık %80 azaltır.

