Geolocation API mit Claude Code: Berechtigungen, Datenschutz, Fallbacks und Tests
Geolocation API mit Claude Code sicher umsetzen: Berechtigungen, HTTPS, Fallback, Datenschutz und Tests.
Standortfunktionen wirken klein, bis echte Nutzer sie verwenden. Ein Button für “Standort verwenden” berührt Browserberechtigungen, HTTPS, Geräteeinstellungen, Timeouts, manuelle Eingabe, Kartenanbieter, Logging und Tests. Wer nur den Erfolgspfad baut, verliert Nutzer genau dann, wenn sie die Standortfreigabe ablehnen oder das Gerät keine Position liefern kann.
Claude Code kann die Implementierung beschleunigen, braucht aber klare Grenzen. Eine Anfrage wie “baue Geolocation ein” erzeugt oft nur getCurrentPosition mit einem Log der Koordinaten. Eine veröffentlichbare Lösung erklärt den Zweck vor dem Browserdialog, fragt erst nach einem Klick, bietet Adresse oder Postleitzahl als Fallback, speichert keine rohen Koordinaten und enthält Tests mit gemockter Position.
Die technischen Aussagen in diesem Artikel wurden gegen Primärquellen geprüft: MDN Geolocation API, getCurrentPosition, watchPosition, Permissions API, W3C Geolocation Specification, Chrome zu secure origins, Chrome DevTools Sensors, Playwright emulation und Claude Code permissions. Passend dazu: Kartenintegration, Security Audit und Responsive Design.
Grenzen vor dem Code klären
Die Geolocation API fragt den Browser nach der geschätzten Geräteposition. Der Browser kann GPS, WLAN, Mobilfunk, IP, Betriebssystemdienste oder Cache verwenden. Die Anwendung kontrolliert diese Quelle nicht und sollte dem Nutzer keine perfekte Genauigkeit versprechen.
Vier Entscheidungen gehören vor die Implementierung. Erstens: Standort erst nach einer klaren Nutzeraktion anfragen. Zweitens: enableHighAccuracy: false als Standard verwenden, solange keine präzise Verfolgung nötig ist. Drittens: immer manuelle Eingabe für Adresse, Stadt oder Postleitzahl anbieten. Viertens: festlegen, was gespeichert wird. Häufig reichen Ergebnisdaten wie Zone oder Entfernungsklasse.
| Entscheidung | Sinnvoller Standard | Typischer Fehler |
|---|---|---|
| Zeitpunkt | Nach Klick auf den Button | Permission-Prompt beim Laden |
| Genauigkeit | Hohe Genauigkeit zunächst aus | GPS für einfache Suche erzwingen |
| Fallback | PLZ, Stadt oder Adresse | Nutzer nach Ablehnung blockieren |
| Logs | Events und grobe Buckets | Rohes position.coords loggen |
Kartenlogik ist eine andere Schicht. Geolocation liefert Koordinaten. Kartendarstellung, Geocoding, Routen und POI-Suche gehören zu Google Maps, Mapbox, OpenStreetMap-Diensten oder zum Backend.
Konkrete Produktfälle
Erster Fall: Filialsuche. Nutzer klicken auf “Standort verwenden”, die App sortiert Filialen nach Entfernung. Neben dem Button sollte “per Postleitzahl suchen” stehen, damit Datenschutzbewusste Nutzer weiterkommen.
Zweiter Fall: Liefer- oder Servicegebiet. Lebensmittel, Reparatur, Vermietung und Vor-Ort-Services können prüfen, ob ein Nutzer in der Zone liegt und welche Zeitfenster verfügbar sind. Dafür muss oft keine exakte Koordinate gespeichert werden.
Dritter Fall: Check-in für Außendienst. Reinigung, Wartung, Events und Vertrieb können prüfen, ob eine Person nahe am Einsatzort ist. Bei Fehlschlag braucht es Foto, Freigabe oder manuelle Notiz, sonst wird ein Geräteproblem zum Prozessproblem.
Vierter Fall: lokale Inhalte. Wetter, Events, Lagerbestand und kommunale Hinweise können regionalisiert werden. Wenn Stadt oder Region reichen, ist eine gespeicherte Präferenz oft besser als präzise Live-Position.
Ausführbares getCurrentPosition-Beispiel
Speichere die Datei als geo-demo.html und öffne sie über localhost oder HTTPS. Das Beispiel zeigt Erklärung, Timeout, Cache, gerundete Ausgabe und manuellen Fallback.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Geolocation demo</title>
<style>
body {
font-family: system-ui, sans-serif;
line-height: 1.6;
margin: 2rem;
}
button,
input {
font: inherit;
padding: 0.7rem 0.9rem;
}
.panel {
border: 1px solid #ddd;
max-width: 36rem;
padding: 1rem;
}
</style>
</head>
<body>
<main class="panel">
<h1>Nahe Filialen finden</h1>
<p>
Wir nutzen deinen Standort nur zum Sortieren der Filialen.
Exakte Adresse und Bewegungsverlauf werden nicht gespeichert.
</p>
<button id="useLocation" type="button">Standort verwenden</button>
<p id="status" role="status" aria-live="polite"></p>
<pre id="result"></pre>
<form id="manualForm">
<label for="postcode">Postleitzahl oder Stadt</label>
<input id="postcode" name="postcode" autocomplete="postal-code" />
<button type="submit">Manuell suchen</button>
</form>
</main>
<script type="module">
const status = document.querySelector("#status");
const result = document.querySelector("#result");
const button = document.querySelector("#useLocation");
const form = document.querySelector("#manualForm");
function showManual(reason) {
status.textContent =
`${reason}. Du kannst auch per PLZ oder Stadt suchen.`;
}
function onSuccess(position) {
const { latitude, longitude, accuracy } = position.coords;
status.textContent = "Standort empfangen.";
result.textContent = JSON.stringify(
{
lat: Number(latitude.toFixed(5)),
lng: Number(longitude.toFixed(5)),
accuracyMeters: Math.round(accuracy),
},
null,
2,
);
}
function onError(error) {
const messages = {
1: "Standortberechtigung wurde abgelehnt",
2: "Gerätestandort ist nicht verfügbar",
3: "Standortanfrage hat zu lange gedauert",
};
showManual(messages[error.code] ?? "Standort nicht verfügbar");
}
button.addEventListener("click", () => {
if (!("geolocation" in navigator)) {
showManual("Dieser Browser unterstützt Geolocation nicht");
return;
}
status.textContent = "Standortberechtigung wird geprüft...";
navigator.geolocation.getCurrentPosition(onSuccess, onError, {
enableHighAccuracy: false,
timeout: 8000,
maximumAge: 60000,
});
});
form.addEventListener("submit", (event) => {
event.preventDefault();
const data = new FormData(form);
status.textContent =
`Suche in der Nähe von "${data.get("postcode")}".`;
});
</script>
</body>
</html>
timeout begrenzt die Wartezeit. maximumAge erlaubt eine ausreichend frische Cache-Position. enableHighAccuracy bittet um höhere Genauigkeit, kann aber langsamer sein und mehr Akku verbrauchen.
watchPosition richtig stoppen
watchPosition liefert wiederholte Updates. Es passt zu Routen und aktiven Einsätzen, nicht zu einer einmaligen Suche. Die zurückgegebene ID muss mit clearWatch beendet werden.
import { useEffect, useRef, useState } from "react";
type LocationPoint = {
lat: number;
lng: number;
accuracy: number;
at: string;
};
export function TrackingPanel() {
const watchId = useRef<number | null>(null);
const [points, setPoints] = useState<LocationPoint[]>([]);
const [error, setError] = useState<string | null>(null);
function start() {
if (!navigator.geolocation || watchId.current !== null) return;
watchId.current = navigator.geolocation.watchPosition(
(position) => {
const { latitude, longitude, accuracy } = position.coords;
setPoints((current) => [
{
lat: Number(latitude.toFixed(5)),
lng: Number(longitude.toFixed(5)),
accuracy: Math.round(accuracy),
at: new Date(position.timestamp).toISOString(),
},
...current.slice(0, 9),
]);
},
(err) => setError(`Tracking fehlgeschlagen: ${err.code}`),
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 5000,
},
);
}
function stop() {
if (watchId.current === null) return;
navigator.geolocation.clearWatch(watchId.current);
watchId.current = null;
}
useEffect(() => stop, []);
return (
<section>
<button type="button" onClick={start}>Tracking starten</button>
<button type="button" onClick={stop}>Stoppen</button>
{error && <p role="alert">{error}</p>}
<ol>
{points.map((point) => (
<li key={point.at}>
{point.lat}, {point.lng}
{" / "}
{point.accuracy}m
</li>
))}
</ol>
</section>
);
}
Ein Produkt mit Tracking braucht sichtbare Zustände: Start, Pause, Ende. Zusätzlich müssen Aufbewahrung, Zugriff und Löschung vor der Umsetzung geklärt sein.
Datenschutz und Logging
Breiten- und Längengrad gehören nicht ungeprüft in Logs. Sie können in Monitoring, Analytics, Support-Screenshots oder Session-Replay landen. Nutze Ereignisse und grobe Gruppen.
type GeoLogInput = {
lat: number;
lng: number;
accuracy: number;
permission: "granted" | "prompt" | "denied" | "unknown";
};
export function toPrivacySafeGeoLog(input: GeoLogInput) {
return {
permission: input.permission,
accuracyBucket:
input.accuracy <= 50 ? "high" :
input.accuracy <= 500 ? "medium" : "low",
latBucket: Number(input.lat.toFixed(2)),
lngBucket: Number(input.lng.toFixed(2)),
};
}
Für Conversion-Analysen reichen oft permission_denied, manual_search_used, timeout und results_shown. Claude Code sollte ausdrücklich angewiesen werden, rohe Koordinaten nicht zu loggen.
Die Permissions API kann den Zustand lesen, ersetzt aber nicht den eigentlichen Browserdialog.
export async function readGeoPermission() {
if (!("permissions" in navigator)) return "unknown";
try {
const status = await navigator.permissions.query({
name: "geolocation",
});
return status.state;
} catch {
return "unknown";
}
}
Fehlerfälle und Tests
Teste HTTP, HTTPS und iframe. Geolocation benötigt einen sicheren Kontext, und Permissions-Policy kann die Nutzung in eingebetteten Frames blockieren.
Teste abgelehnte Berechtigung. Ablehnung ist ein normaler Nutzerwunsch. Die UI muss zur manuellen Eingabe wechseln.
Teste Timeout und nicht verfügbare Position. Desktop, Innenräume, VPN, deaktivierte Betriebssystemdienste und Unternehmensbrowser sind häufige Ursachen.
Teste alte Cache-Positionen. maximumAge macht die UX schneller, kann aber für Check-ins zu ungenau sein.
import { expect, test } from "@playwright/test";
test.use({
geolocation: {
latitude: 52.520008,
longitude: 13.404954,
accuracy: 50,
},
permissions: ["geolocation"],
});
test("shows nearby stores from mocked location", async ({ page }) => {
await page.goto("/stores");
await page.getByRole("button", { name: "Standort verwenden" }).click();
await expect(page.getByText("Standort empfangen")).toBeVisible();
});
Sicherer Claude Code Prompt
Der Prompt muss Umfang, Verbote und Nachweise enthalten.
claude <<'PROMPT'
Implement a beginner-friendly Geolocation feature.
Scope:
- Edit only src/features/location and related tests.
- Do not change billing, analytics, or map provider config.
- Preserve existing API keys and environment variable names.
Requirements:
- Request location only after the user clicks a button.
- Explain why location is needed before the browser prompt.
- Use getCurrentPosition with timeout and maximumAge.
- Add manual postcode/address fallback for denied or timeout cases.
- Do not log raw latitude or longitude.
- Add a Playwright test with mocked geolocation.
- Return a short verification checklist.
PROMPT
Teams sollten zusätzlich die Claude-Code-Berechtigungen begrenzen.
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Bash(git push *)"
],
"allow": [
"Bash(npm test *)",
"Bash(npm run lint)"
]
}
}
Wenn du daraus einen Teamstandard, Review-Checklisten oder repository-spezifische Prompts machen willst, ist Claude Code training and consultation der direkte nächste Schritt.
Praktische Verifikation
Ich habe die Beispiele in Chrome über localhost, mit DevTools Sensors auf Berlin und “Location unavailable” sowie mit Playwright und erteilter Geolocation-Berechtigung geprüft. Vor Produktion sollten zusätzlich OS-Standort aus, Unternehmensrichtlinien, iframe-Embedding, Kartenanbieter-Quota und Logs ohne rohe Koordinaten geprüft werden.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Workflow von Obsidian zu CLAUDE.md
Obsidian-Arbeitsnotizen in CLAUDE.md-Betriebsnotizen verwandeln und Kontext nicht ständig neu erklären.
Claude Code Revenue CTA Routing: Artikel zu PDF, Gumroad und Beratung führen
Ein Claude-Code-Ablauf, der Leser nach Absicht zu Gratis-PDF, Gumroad oder Beratung führt.
Claude-Code-Team-Handoff-Regeln: Belege, Berechtigungen, Rollback und Umsatzpfade
Ein praktisches Claude-Code-Handoff für Review-Belege, Berechtigungen, Rollback, Gratis-PDF, Gumroad und Beratung.