JavaScript / TypeScript
IPGeoTrace for JavaScript
A typed, isomorphic core that runs on Node 18+, edge runtimes, Deno and Bun, plus thin adapters for the frameworks you already use. Every package ships dual ESM + CJS with full type definitions.
The whole family lives under the @ipgeotrace/*npm scope and builds on two foundation packages. Which one you reach for is decided by a single question: does this code hold the secret API key, or does it run in the visitor's browser?
Two trust zones#
This is the one thing that makes JavaScript different from the .NET clients. .NET lives entirely on the server, where the key is safe. JavaScript spans two places, and they get two different packages and two different kinds of key.
@ipgeotrace/client- server side (Node / edge). Holds the secret key, and you supply the IP: single lookups, batches, caching and retries. Framework adapters build on it to resolve the caller once per request.@ipgeotrace/browser- the browser. Cannot hold a secret, so it uses a publishable key and answers only one question viame(): where is the person looking at this page? React, Vue and Svelte bindings wrap it in reactive sugar.
Never ship the secret key to the browser
The secret key lives in@ipgeotrace/client on your server. The browser only ever gets a domain-locked publishable key. Mixing them up is the one mistake to avoid.Every package#
The whole family, published independently under the @ipgeotrace scope. Take the core plus whatever matches your stack - each tile links straight to its npm page.
Server
Secret key@ipgeotrace/express
Express middleware. Resolves the caller once per request onto req.geo.
@ipgeotrace/fastify
Fastify plugin. Decorates every request with request.geo.
@ipgeotrace/nestjs
NestJS module with a global interceptor, the @Geo() decorator and an injectable service.
@ipgeotrace/next
Next.js helper for Route Handlers, Server Components and edge middleware.
Browser
Publishable key@ipgeotrace/browser
Publishable-key browser client. client.me() resolves the current visitor client-side.
@ipgeotrace/react
React provider and useVisitorGeo() hook. Serves Next.js client components too.
@ipgeotrace/vue
Vue plugin and useVisitorGeo() composable.
@ipgeotrace/svelte
Svelte store via createVisitorGeo(), with context helpers to share one call.
Install#
Install the package for the side you are on. Most apps use one; full-stack apps use both.
npm i @ipgeotrace/clientnpm i @ipgeotrace/browserResolve an IP on the server#
Construct the client with your secret key and call resolve. Every call returns a Result you check with ok before reading value - nothing throws except caller cancellation.
import { IpGeoTraceClient } from '@ipgeotrace/client';
const geo = new IpGeoTraceClient({ apiKey: process.env.IPGEOTRACE_API_KEY! });
const result = await geo.resolve('8.8.8.8');
if (result.ok) {
console.log(result.value.country?.name); // "United States"
}Resolve the visitor in the browser#
createBrowserClient().me() resolves the current visitor from their real connection IP - no IP to supply, and safe to call from client-side code.
import { createBrowserClient } from '@ipgeotrace/browser';
const client = createBrowserClient({ publishableKey: 'pk_geoip_your_key' });
const result = await client.me();
if (result.ok) {
console.log(result.value.country?.currency); // "USD"
}Where to next#
- Server (Node & edge) - the core client, batch lookups, the
GeoLookupstatus model, and middleware for Express, Fastify, NestJS and Next.js. - Browser & frameworks - publishable-key auth, the vanilla client, and one-line bindings for React, Vue and Svelte.
Source & packages
Every package is published under@ipgeotrace on npm. Grab an API key from app.ipgeotrace.com to make live calls.