IP-Geolokalisierung in Next.js: Browser- und Servermuster
Next.js kann dieselbe Seite auf dem Server oder im Browser rendern, und diese Entscheidung ändert, welcher Watch-IP-Endpoint tatsächlich den Standort eines Besuchers auflöst — oder stattdessen den Ihres Servers.
Bevor Sie beginnen
- Ein veröffentlichbarer Besucherschlüssel für das Client-Muster oder ein geheimer Lookup-Schlüssel für das Server-Muster — siehe Authentifizierung.
- Ein Next.js-App-Router-Projekt (die Beispiele setzen die Server-/Client-Komponenten-Aufteilung von Next.js 16 voraus).
- Für das Server-Muster ein Header, den Ihre Hosting-Plattform bei eingehenden Anfragen mit der echten IP des Besuchers setzt (zum Beispiel CF-Connecting-IP auf Cloudflare) — nicht einer, den ein Client selbst setzen könnte.
1. Verstehen, was jedes Muster tatsächlich aufruft
GET /v1/geo identifiziert, wessen Verbindung die API erreicht — der Browser eines Besuchers, der ihn direkt aufruft, oder Ihr Next.js-Server, wenn Ihr eigener Code ihn während des Server-Renderings aufruft. Das Aufrufen von GET /v1/geo aus einer Serverkomponente oder einem Route-Handler löst den Netzwerkstandort Ihres Servers auf, nicht den des Besuchers, was in der Regel nicht das ist, was Sie wollen. Zwei Muster lösen tatsächlich den Besucher auf: die Anfrage im Browser ausführen (Client-Komponente) oder sie auf Ihrem Server mit einer gelieferten IP über GET /v1/lookup/{ip} ausführen.
2. Client-Komponente: GET /v1/geo aus dem Browser aufrufen
Dies ist dieselbe Anfrage, die die JavaScript- und React-Leitfäden verwenden — eine Client-Komponente, die mit einem veröffentlichbaren Schlüssel einen fetch durchführt. Der eigene Origin-Header des Browsers erfüllt die Prüfung der erlaubten Origins des Schlüssels, daher muss die öffentliche URL Ihrer App auf dieser Liste stehen.
TypeScript (Client-Komponente)
"use client";
import { useEffect, useState } from "react";
export function VisitorLocation() {
const [city, setCity] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController();
fetch("https://api.watch-ip.com/v1/geo", {
headers: { "X-Api-Key": "YOUR_PUBLISHABLE_KEY" },
signal: controller.signal,
})
.then((res) => (res.ok ? res.json() : null))
.then((geo) => setCity(geo?.city ?? null))
.catch(() => {});
return () => controller.abort();
}, []);
return <span>{city ?? "Ihre Region"}</span>;
}3. Serverkomponente oder Route-Handler: Die IP des Besuchers explizit nachschlagen
Um den Standort eines Besuchers während des Server-Renderings aufzulösen, rufen Sie nicht GET /v1/geo auf — rufen Sie GET /v1/lookup/{ip} mit einem geheimen Schlüssel und der echten IP des Besuchers auf, gelesen aus dem Header, den Ihre Hosting-Plattform bei der eingehenden Anfrage setzt. Vertrauen Sie niemals einem einfachen X-Forwarded-For-Wert, den ein Client selbst setzen könnte, es sei denn, Ihre Plattform entfernt und setzt ihn am Edge neu.
TypeScript (Serverkomponente)
import { headers } from "next/headers";
export async function VisitorLocationServer() {
const ip = (await headers()).get("cf-connecting-ip");
if (!ip) return null;
const response = await fetch(`https://api.watch-ip.com/v1/lookup/${ip}`, {
headers: { Authorization: "Bearer YOUR_SECRET_KEY" },
cache: "no-store",
});
if (!response.ok) return null;
const geo = await response.json();
return <span>{geo.city ?? "Ihre Region"}</span>;
}4. Das Ergebnis eines Besuchers nicht für einen anderen cachen
cache: 'no-store' oben ist Absicht: Ein Lookup-Ergebnis ist spezifisch für den Besucher, der es angefragt hat. Wenn diese Komponente innerhalb einer Route rendert, die Next.js oder ein CDN cachen kann — eine statische Seite, eine ISR-Seite, ein gemeinsam genutzter Fetch-Cache —, würde eine gecachte Antwort danach allen die Stadt eines Besuchers zeigen. Halten Sie den personalisierten Zweig dynamisch gerendert und binden Sie eine Lookup-Antwort niemals in einen Cache auf Seiten- oder CDN-Ebene ein.
Fehler und Grenzfälle
Ein fehlender oder leerer IP-Header (manche lokalen oder Proxy-Setups setzen keinen) bedeutet, dass keine Besucher-IP zum Nachschlagen vorhanden ist — rendern Sie den Fallback, statt den Endpoint mit einem leeren String aufzurufen. Ein 403 von GET /v1/lookup/{ip} bedeutet meist, dass ein veröffentlichbarer Schlüssel verwendet wurde, wo die Route einen geheimen Schlüssel benötigt; ein 400 bedeutet, dass der Header einen Wert enthielt, der keine gültige IPv4-/IPv6-Adresse ist. Siehe Fehler und Ratenbegrenzungen.
Nächster Schritt
Für eine Komponente, die Sie sowohl in reinen Client-React-Apps als auch in Next.js wiederverwenden können, siehe den React-Leitfaden — das obige Client-Komponenten-Muster ist ein Next.js-spezifischer Wrapper um dieselbe Anfrage.
Verwandte Seiten
- Besucher-GeolokalisierungGET /v1/geo aus dem Browser mit einem veröffentlichbaren Schlüssel aufrufen.
- GET /v1/geo-ReferenzVollständige Feldreferenz für den Endpoint zur Besucher-Geolokalisierung.
- GET /v1/lookup/:ip-ReferenzVollständige Feldreferenz für den Endpoint zur beliebigen IP-Abfrage.
- React-LeitfadenBesucherstandort zu einer React-Komponente hinzufügen.