A free interactive map of public fishing piers on every US coast — Pacific, Gulf, Atlantic, Hawaii and the Caribbean. Live water & weather, what's biting, tides, seafloor/structure, videos, and each state's pier-fishing license rule.
License rules vary by state. A few states (California, Oregon, New Jersey…) let you fish a public pier with no license; most require one. Every pier shows its own rule — green = free, amber = license required. Started as a SoCal license-free guide and grew nationwide.
Acted on the specialist audit + a market-validation pass (demand is real and rising — "fishing spots near me" ~96k/mo; spot-finding search up 250–400% since 2004; record 57.9M US anglers in 2024) in three phases:
- UX focus — reframed the whole app around one job: find a pier → is it open → what's biting. Fixed the old USA-title / California-description / global-data contradiction (now one coherent global scope, branded PierMap); surfaced a colour-coded license chip in the pier-panel header instead of burying it in "the scoop"; collapsed History & Videos into accordions to cut the wall of sections; added
?v=asset cache-busting so updates show without a hard refresh. - SEO —
tools/build_seo.pypre-renders a real, crawlable static page for every curated pier (/piers/<slug>.html) with<title>/meta/canonical, Open Graph, schema.org JSON-LD (TouristAttraction + BreadcrumbList), YouTube thumbnails, and a deep-link into the live map — plus a state-grouped hub,sitemap.xmlandrobots.txt. This is the growth lever: the JS app alone is invisible to Google. A GitHub Action rebuilds these with the real Pages URL on every push. - Backend (free, optional) —
backend/ships a Cloudflare Worker (edge-caches NOAA stations & Overpass; serves a shared catch-log, leaderboard and pier-corrections) on Supabase free Postgres, plussrc/api.js, a drop-in client. The app works 100% with no backend (localStorage + public APIs); setwindow.PIERMAP_APIto your Worker URL to light up the community layer. The Supabase key never reaches the browser. See backend/README.md.
A panel of specialist agents (frontend, QA, UX, backend, SEO, accessibility) audited the app, and a market-validation pass confirmed real, rising demand (spot-finding search up 250–400% since 2004; 57.9M US anglers in 2024). First actions on the findings:
- Split the monolith into a project — the single ~1,800-line
index.htmlis nowindex.html(HTML shell) +app.css(styles) +src/data.js(pier data + helpers) +src/app.js(map app), withLICENSE(MIT),CONTRIBUTING.mdandpackage.json. Identical behaviour, now maintainable, cacheable and open-source-ready. - Critical fixes from the audit — the live-OSM layer now clears on zoom-out and caps at ~2,500 features, so panning the world no longer leaks memory; a request guard stops a fast double-click from showing one pier's header with another pier's live conditions.
The map is now worldwide. Zoom in anywhere on Earth and every public pier loads live from OpenStreetMap (man_made=pier via the Overpass API) — with its real geometry drawn as the pier shape, no backend, hosted-on-static-pages friendly.
- Every pier on the planet, free — viewport queries (selective, within Overpass fair-use), de-duplicated against our 222 curated/enriched piers which stay as "featured." Validated live: Sydney Harbour returns 600+ piers with real shapes.
- Conditions work worldwide — water temp, wind, waves and the 7-day forecast come from Open-Meteo (global, keyless), so an OSM pier in Australia shows live data just like California. (NOAA tides are US-only, so they're shown only when a real US station is nearby — no fake tides abroad.)
- Community via OSM — every OSM pier has an "✏️ Improve" button that opens its OpenStreetMap record, so anyone can fix names, add detail, photos — freshness without a server.
- Honest globally — license shows "Varies — check local rules" outside the US; region-tuned features (bite odds, US license rules) only appear where they apply.
- Competitor check (deep-research): the closest analog, PierSeeker, is free & web-based but US-only (~36k piers). Going global + open-source is the clear white space.
- 222 piers across 10 regions — California (56) plus Pacific NW & Alaska, Hawaii, Western & Eastern Gulf, Florida-Atlantic & Georgia, the Carolinas, Mid-Atlantic, Northeast, and the Caribbean (PR/USVI). Region chips jump to each coast; the default view is the whole country.
- Honest per-state license rules — researched for all 26 coastal states/territories (e.g. WA/AK/most Northeast = license required; CA/OR/NJ = free or mixed). Each pier's panel shows its license status and the state rule, with a "license by state" link.
- Nationwide live tides — tide times now snap to the nearest of NOAA's 3,450 real stations, so an Atlantic or Gulf pier shows its local tide, not California's.
- Extra map overlay — 🗺 Bottom contours (Esri) added to the Map-layers panel (alongside SST, water color, MPA closures).
A single self-contained index.html — open it in any browser, no server or build step needed. A real, full-screen geographic map of California (Leaflet) in the style of apps like FishAngler, focused entirely on license-free public piers.
- Big interactive map of all of California — from Crescent City in the far north to Imperial Beach at the Mexican border. Pan, zoom, and clustered pins that expand as you zoom in. Three base layers: 🛰 Satellite (Esri), 🌊 Ocean chart, and 🗺 Street.
- 56 piers, 8 coastal regions — North Coast, SF Bay Area, Monterey Bay, Central Coast, Santa Barbara/Ventura, LA, Orange County, San Diego. Pins color-coded by status; filter by region, "fishable only", and target fish (halibut, corbina, surfperch, croaker, mackerel, bonito, bass, sharks/rays, bait shop, 24h).
- Honest status & license flags — Open / Partly open / Closed / Demolished, with the reason (Ocean Beach SD closed since 2023; Pacifica closed Jun 2026; Berkeley & SF Municipal closed; Seacliff & Aliso demolished). Private/license-required piers (Trinidad, Eureka Boardwalk) and the Lovers Point no-take reserve are flagged so nobody fishes illegally.
- Live conditions panel — click a pin: real-time water temp, wind, waves, air temp, today's tides, a prime bite window off the incoming tide, plus sunrise/sunset and moon phase.
- 7-day marine forecast — a week strip of weather, hi/lo, wave height and wind per pier (Open-Meteo).
- Bite odds (estimate) — an honest, computed "what's biting now" bar per species from each fish's seasonal pattern + today's water temperature. Not fake catch counts.
- Catch log — "I caught one here" saves your catches in the browser (localStorage) and builds a personal leaderboard of your top piers & species. A shared community leaderboard is the next backend step.
A "Map layers" panel (in the Filters popover) toggles satellite data overlays over the whole coast — turning our per-pier point readings into spatial layers, the way offshore captains read the water:
- 🌡️ Water temperature (SST) — gap-free daily sea-surface-temperature heatmap (NASA GIBS / GHRSST MUR). See warm/cold water and nearshore temperature breaks along the coast.
- 🌿 Water color (chlorophyll) — ocean-color / productivity (NASA GIBS / PACE OCI): clear-blue vs green/baity water.
- 🚫 Protected areas (MPA) — all 155 California Marine Protected Areas (CDFW): red = no-take reserves, amber = restricted; tap one for the rule. Complements the per-pier license flags.
- A colour-scale legend appears for whichever overlay is on; overlays are free, no API key.
Every pier is now researched and rendered as its own mini-guide:
- The pier drawn on the map — a coloured line from shore extending into the water along its real seaward bearing for its real length, so you can see how far each pier reaches (clickable; colour = status).
- Underwater profile — a little cross-section graphic in the panel showing the deck on its pilings and the seabed sloping down to the seaward end, labelled with the water depth at the end (~ft) and the pier's length. 54 of 56 piers have a researched end depth.
- Seafloor & relief — bottom type (sand / rock reef / mud / eelgrass / submarine canyon) and a line on the underwater structure and why it holds fish.
- History & fun facts — when it was built/rebuilt, notable storms/fires, and a few genuinely interesting facts.
- YouTube videos filmed at the pier — thumbnail cards (44 piers have curated clips) that play inline on the site in a lightbox, plus a "more on YouTube" search that always works. Invalid/placeholder thumbnails auto-hide so only real videos show.
- Illustrated nautical-chart map style (now the default): the Esri Ocean basemap given an antique treatment — warm sepia/contrast filter, a procedural paper-grain texture (multiply blend), a soft vignette, and a hand-drawn compass rose. Layer switch: 🎨 Chart (illustrated, default), 🧭 Vintage (Esri / National Geographic cartography), 🛰 Satellite, 🗺 Street.
- Charters & kayak rentals layer — ~46 researched, currently-operating sportfishing charters/landings and kayak/SUP rental shops along the whole coast, toggled from the Filters popover. Distinct pins (⚓ charter / 🛶 kayak); tap one for what they offer, a "Visit site / call / directions" row, and an honest license note (kayak fishing needs a CA license; a licensed charter boat covers you).
Ran a 5-dimension adversarial review of the app and fixed what it found:
- Correctness bugs: timezone handling rewritten (NOAA in GMT, Open-Meteo in unixtime, all times formatted to Pacific) so tides/sun/prime-window are right for any visitor, not just Californians; conditions now cache with a 30-min TTL in
localStorageand only cache real data (a transient fetch failure no longer blanks a pier forever); 7-day wave heights aligned by date instead of array index; the Ocean basemap no longer goes blank past zoom 13; searching a filtered-out pier now still shows its pin. - Honesty/safety: added a "no license, but bag & size limits and seasons still apply" note + CDFW link on every pier, and a white-croaker OEHHA consumption-advisory flag on the LA/Palos Verdes shelf piers; the bite estimate dropped fake-precision percentages for honest qualitative bands ("hot / good / fair / slow").
- Features: "Near me" geolocation with distance shown in search & the panel; deep-linking (
#pier=<id>) so any pier is bookmarkable/shareable, plus a Share button; a "Why no license?" explainer modal + first-visit intro card. - UX/visual: the filter wall became a clean grouped Filters popover; flatter cartographic pins; a compact one-line legend; consistent design tokens; softer accent hierarchy.
- Mobile: the panel is now a bottom sheet, larger tap targets, single-row top bar, icon-only layer switch, pinch-zoom re-enabled.
- A11y: keyboard-focusable pins (Enter/Space), Esc closes panels,
aria-labels on icon buttons, focus moves into the panel on open, user text escaped against XSS. - Robustness: Leaflet falls back from unpkg → jsDelivr, with a load-timeout error message instead of an infinite spinner.
legacy/index-3d.html— the stylized 3D Three.js coastline (Sky + Water, fly-around camera, glowing buoys). SoCal-only.legacy/index-simple.html— the original plain-HTML card list. SoCal-only, zero dependencies, best for SEO/accessibility.
| Feature | Source | Notes |
|---|---|---|
| Water temp + waves | Open-Meteo Marine | sea-surface temp (model), wave height/period/direction. CORS-enabled, no key. |
| Air temp + wind | Open-Meteo Forecast | live temp + wind speed/direction/gusts. |
| Tides | NOAA Tides & Currents | high/low predictions, nearest of 7 SoCal stations (auto-picked by distance). |
| Regulations | CDFW Ocean Sport Fishing | summarized; CDFW is the legal source. |
Pier data was researched in June 2026. Always verify pier status before a trip — storms and construction change things fast.
It's a static site — no build step.
npm run dev # serves on http://localhost:8123 (uses npx serve)Or just open index.html in a browser (a local server is recommended so the live
OpenStreetMap/Overpass queries work without cross-origin issues). To self-host,
drop the folder behind any static host — GitHub Pages, Netlify, Cloudflare Pages,
Vercel — it's pure static HTML/CSS/JS.
index.html HTML shell (loads app.css, src/data.js, src/api.js, src/app.js)
app.css all styles
src/data.js curated pier data, per-state license rules, shared helpers
src/app.js Leaflet map, markers, pier panel, overlays, live OSM, UI
src/api.js API client — backend when window.PIERMAP_API is set, else local
data/piers.json export of the 222 curated piers (SEO build input)
tools/build_seo.py pre-renders /piers/<slug>.html + sitemap.xml + robots.txt
backend/ Cloudflare Worker + Supabase schema + deploy guide (optional)
.github/workflows/ GitHub Pages build+deploy (runs the SEO build)
legacy/ earlier standalone snapshots (3D + simple list)
piers/ sitemap.xml robots.txt ← generated by build_seo.py (git-ignored)
Frontend → GitHub Pages. Push the repo to GitHub, then Settings → Pages → Source: GitHub Actions. The included workflow (.github/workflows/pages.yml) runs build_seo.py with your real Pages URL and publishes the site on every push to main. (Prefer "deploy from branch"? Run PIERMAP_BASE_URL="https://<you>.github.io/<repo>" py tools/build_seo.py locally and commit the piers/, sitemap.xml, robots.txt it produces.)
Backend (optional) → Cloudflare + Supabase. Both have free tiers. Follow backend/README.md: create the Supabase tables (backend/schema.sql), deploy the Worker (backend/worker.js), then set window.PIERMAP_API in index.html to your Worker URL. Until then the app runs fully on free public APIs with an on-device catch log — no backend required.
Phase 2 — the live "what's biting" feed. Facebook killed automated access to group posts in 2024, so a real feed has to come from a tiny backend (Cloudflare Worker / Vercel function) on a 15–30 min cron that ingests ToS-clean sources and serves one /api/feed.json:
- Forum RSS: PFIC, BloodyDecks (XenForo
index.rss) - WordPress RSS: Fish the Surf, SurfFishingSoCal, CDFW Marine
- YouTube channel RSS (SoCal surf channels + CDFW)
- Reddit
/new.jsonvia the backend (keyword-filtered to pier/surf/SoCal) — Reddit blocks browser & cloud-IP direct calls, so it must be proxied - An operator "recent reports" mini-CMS for hand-curated bait-shop / personal reports
Other expansions
- Interactive Leaflet/Mapbox map view (markers colored by status)
- Per-pier 7-day forecast + best-day picker
- More regions (Central Coast: Pismo, Morro Bay, Cayucos, Avila)
- Catch-log / "I caught X here today" crowd input
- SEO pages per pier (huge organic intent: "free fishing pier near me")
- PWA / installable, offline pier data
Pier status, hours and regulations change — confirm with the managing city/agency and CDFW before you go. Check local water-quality advisories before eating any catch (especially Imperial Beach / South Bay). Not affiliated with any government agency. MVP v0.1.