Geo-aware IP page powered by Cloudflare Workers and fal.ai
0
stars
3
commits
TypeScript
primary language
Sep 2, 2026
updated
An open-source, geo-aware IP page powered by Cloudflare Workers and fal.ai. Each visitor sees the public IP used for the current connection, Cloudflare's approximate location metadata, and an AI-generated view informed by local place, season, and time.
Production example: https://ip.adsparty.com
.
├── .github/ GitHub Actions and contribution templates
├── docs/assets/ Documentation images
├── fixtures/locations/ Simulated Cloudflare request profiles
├── scripts/ Local developer tools
├── src/
│ ├── assets/ Generated static assets
│ ├── page.ts Server-rendered HTML, CSS, and browser behavior
│ └── worker.ts Worker routes, security, cache, and fal.ai calls
├── tests/ Unit tests
├── wrangler.jsonc Safe default configuration for forks
└── wrangler.production.example.jsonc
npm install
cp .dev.vars.example .dev.vars
npm run preview -- istanbul
Open http://127.0.0.1:8787. Mock preview mode never calls fal.ai and does not consume credits.
Available fixtures: istanbul, tokyo, new-york, sydney, and reykjavik.
Run a fixture with real fal.ai generation:
npm run preview -- tokyo --live
This requires FAL_KEY in .dev.vars.
Public configuration lives in wrangler.jsonc:
| Variable | Required | Purpose |
|---|---|---|
FAL_MODEL_ID | No | fal.ai model; defaults to fal-ai/flux-2/turbo |
APP_HOST | Production | Restricts generation to the configured hostname |
WEB_ANALYTICS_TOKEN | No | Enables Cloudflare Web Analytics |
Secrets must never be committed:
| Secret | Purpose |
|---|---|
FAL_KEY | Server-side fal.ai credentials |
GENERATION_SIGNING_KEY | Signs short-lived, IP-bound generation tokens |
npm run typecheck
npm test
npm run check
npm run check runs TypeScript, unit tests, and a Wrangler dry run. The same
command runs in GitHub Actions for pushes and pull requests.
The default configuration deploys to a personal workers.dev hostname:
npx wrangler secret put FAL_KEY
npx wrangler secret put GENERATION_SIGNING_KEY
npm run deploy
For a custom domain, create an ignored maintainer configuration:
cp wrangler.production.example.jsonc wrangler.production.jsonc
Update its account ID, Worker name, custom domain, APP_HOST, and rate-limit
namespace, then add secrets and deploy:
npx wrangler secret put FAL_KEY --config wrangler.production.jsonc
npx wrangler secret put GENERATION_SIGNING_KEY --config wrangler.production.jsonc
npm run deploy:production
GET /geo-image-data accepts only requests carrying a short-lived HMAC token
issued by the page and bound to the connecting IP. Same-origin checks, hostname
restriction, edge caching, and a Cloudflare rate-limit binding reduce blind
hotlinking and unexpected fal.ai spend. This is cost control, not authentication.
Visit history stays in localStorage; IP addresses are deliberately excluded.
Cloudflare provides only the IP family used for the current HTTP connection, so
the other family may display as not detected.
See SECURITY.md for responsible disclosure.
Contributions are welcome. Read CONTRIBUTING.md before opening a pull request.
3 commits
TypeScript
98.1%
JavaScript
1.9%
Geo-aware IP page powered by Cloudflare Workers and fal.ai
0
stars
3
commits
TypeScript
primary language
Sep 2, 2026
updated
An open-source, geo-aware IP page powered by Cloudflare Workers and fal.ai. Each visitor sees the public IP used for the current connection, Cloudflare's approximate location metadata, and an AI-generated view informed by local place, season, and time.
Production example: https://ip.adsparty.com
.
├── .github/ GitHub Actions and contribution templates
├── docs/assets/ Documentation images
├── fixtures/locations/ Simulated Cloudflare request profiles
├── scripts/ Local developer tools
├── src/
│ ├── assets/ Generated static assets
│ ├── page.ts Server-rendered HTML, CSS, and browser behavior
│ └── worker.ts Worker routes, security, cache, and fal.ai calls
├── tests/ Unit tests
├── wrangler.jsonc Safe default configuration for forks
└── wrangler.production.example.jsonc
npm install
cp .dev.vars.example .dev.vars
npm run preview -- istanbul
Open http://127.0.0.1:8787. Mock preview mode never calls fal.ai and does not consume credits.
Available fixtures: istanbul, tokyo, new-york, sydney, and reykjavik.
Run a fixture with real fal.ai generation:
npm run preview -- tokyo --live
This requires FAL_KEY in .dev.vars.
Public configuration lives in wrangler.jsonc:
| Variable | Required | Purpose |
|---|---|---|
FAL_MODEL_ID | No | fal.ai model; defaults to fal-ai/flux-2/turbo |
APP_HOST | Production | Restricts generation to the configured hostname |
WEB_ANALYTICS_TOKEN | No | Enables Cloudflare Web Analytics |
Secrets must never be committed:
| Secret | Purpose |
|---|---|
FAL_KEY | Server-side fal.ai credentials |
GENERATION_SIGNING_KEY | Signs short-lived, IP-bound generation tokens |
npm run typecheck
npm test
npm run check
npm run check runs TypeScript, unit tests, and a Wrangler dry run. The same
command runs in GitHub Actions for pushes and pull requests.
The default configuration deploys to a personal workers.dev hostname:
npx wrangler secret put FAL_KEY
npx wrangler secret put GENERATION_SIGNING_KEY
npm run deploy
For a custom domain, create an ignored maintainer configuration:
cp wrangler.production.example.jsonc wrangler.production.jsonc
Update its account ID, Worker name, custom domain, APP_HOST, and rate-limit
namespace, then add secrets and deploy:
npx wrangler secret put FAL_KEY --config wrangler.production.jsonc
npx wrangler secret put GENERATION_SIGNING_KEY --config wrangler.production.jsonc
npm run deploy:production
GET /geo-image-data accepts only requests carrying a short-lived HMAC token
issued by the page and bound to the connecting IP. Same-origin checks, hostname
restriction, edge caching, and a Cloudflare rate-limit binding reduce blind
hotlinking and unexpected fal.ai spend. This is cost control, not authentication.
Visit history stays in localStorage; IP addresses are deliberately excluded.
Cloudflare provides only the IP family used for the current HTTP connection, so
the other family may display as not detected.
See SECURITY.md for responsible disclosure.
Contributions are welcome. Read CONTRIBUTING.md before opening a pull request.
3 commits
TypeScript
98.1%
JavaScript
1.9%