Changelog
Every feature, improvement, and fix - documented. Watch us build in public.
May 202631 entries
SSR footer missing from all managed pages - fixed
ManagedPageSSR.tsx was rendering without SSRFooter, meaning ~30 managed-page routes had no footer in server-rendered HTML. Fixed. Affects SEO crawlers and social previews.
City H1 now includes "Event Talent" intent phrase
City detail pages now include "Event Talent" in the H1 to capture event-staffing intent queries across 340K+ city pages.
Gig ingest throughput tripled
Gig pipeline batch_size increased from 50 to 150. Processes 3x more listings per cron run.
Blog image validator edge function deployed
New edge function HEAD-checks all Supabase Storage image URLs and flags broken ones. First step toward zero broken hero images.
SVG placeholder backfill cron deployed
Nightly cron backfills SVG placeholder images for city and venue pages with no photo.
Jobs pipeline restored: apply URL column fix
Fixed a column mismatch in job-ingest-worker (TBA-700) where the worker wrote apply links to application_url but the auto-publish sweep and CHECK constraint checked apply_url. Deployed v18 of the edge function. Pipeline unblocked with 448 published jobs now live.
Gig archiving fix: 1,148 expired gigs cleaned up
Fixed archive_stale_content() to correctly check gig_postings.expires_at (TBA-488). Previously expired gigs were not being archived due to a WHERE clause targeting the wrong column. 1,148 stale gigs archived, published gigs stabilized at 2,145.
Stale city URL slugs corrected sitewide
Compound city slugs in cross-links, hire pages, and how-to pages replaced with canonical DB slugs. Prevents internal 404s.
Em-dashes removed from user-facing page titles
Page titles in /vs, /hotels/th/bangkok, and city category pages used Unicode em-dash. Replaced with hyphen or colon.
Banned copy removed from legal pages
"Not a marketplace or booking site" replaced with approved platform description in Client Guidelines and Trust & Neutrality pages.
Card/list view toggle on /jobs and /gigs
Users can now switch between a card grid and a list view on /jobs and /gigs. Preference is saved to localStorage and persists across page visits. Default is list for SSR-safe rendering with no layout shift.
9 competitor comparison pages at /vs/{slug}
Nine /vs/{competitor} pages comparing The Booking Agency to Upwork, Fiverr, Indeed, LinkedIn Jobs, Glassdoor, Wellfound, Contra, Workana, and Freelancer. Each page has a comparison table, win/loss breakdown, use-case scenarios, and JSON-LD FAQPage schema. Includes a /vs index page. All routes added to the sitemap.
Web vitals beacon edge function
New Supabase edge function accepts Core Web Vitals (LCP, INP, CLS, TTFB, FCP) from the browser and stores them in a web_vitals table. Enables real-user performance monitoring for production pages.
Text links now blue; brand pink reserved for CTA buttons
Global CSS update: inline text links render in blue (#2563EB) instead of brand pink, matching web conventions. Brand pink (#FF4D82) is preserved exclusively for CTA buttons and action elements.
Affiliate click tracking restored via sendBeacon
Affiliate click events were being silently dropped when users navigated to partner URLs before fetch() completed. Switched to navigator.sendBeacon() which the browser sends even after page navigation. Fixes a 29-day gap in ad_clicks data.
Hotellook branding updated: all copy now references Booking.com
Hotellook shut down in October 2025. Updated 3 SSR pages and the affiliate disclosure that still referenced Hotellook. All affiliate links already auto-redirected to Booking.com via Travelpayouts, so revenue was never interrupted.
Bangkok hotels hub launched at /hotels/th/bangkok
First hotel affiliate landing page. SSR route with Booking.com search CTAs pre-filled to Bangkok and 6 neighbourhood deep-links (Sukhumvit, Silom, Old City, Ari, Suvarnabhumi Airport, Siam). Hotel tips section included. Route added to sitemap.
All talent profiles now publicly visible
Expanded the discoverable talent pool to 59 published profiles. The /talent directory now reflects the full active member base, with quality-checked profiles visible to all visitors.
Live multi-currency converter shipped
Real-time exchange rates for 50+ currencies, refreshed every 6 hours from open.er-api.com. Available at /tools/currency-converter plus inline on pricing pages.
Talent directory expanded to 50 verified profiles
Published 30 additional talent profiles that met the quality bar (username + name set). The talent directory now shows 50 active freelancers across all categories. Counters on /open and the homepage updated to reflect the new total.
Jobs and gigs filtered to apply-path listings only
Removed jobs and gigs with no valid apply URL from all listings, sitemap, and detail pages. Improves feed quality and eliminates dead-end applications.
Currency converter placeholder launched
Replaced the unfinished currency converter with a clean Coming Soon card. Live multi-currency tool with price updates sitewide is in progress.
Site stats refresh fixed - nightly cron back on schedule
Rewrote refresh_site_stats() to use single-pass aggregations instead of 30+ sequential COUNT scans. Dropped runtime from 120s (over platform limit) to well under 2 minutes. Stats now update nightly again.
Job listings now auto-archive when expires_at passes
Fixed archive_stale_content() to catch date-expired jobs. 124 zombie listings removed from the feed. Runs nightly at 04:00 UTC.
Gig pipeline launched: 4,000+ gigs now live
Path A-selective gig promotion shipped. 4,003 gigs are now published and included in the combined jobs+gigs feed across /jobs, /gigboard, and all city pages. Combined total: 5,759 active opportunities.
City venue cards stable across all cities
Fixed PostgREST statement timeout on large cities. Venue card payload is now pre-computed nightly via venue-card-backfill edge function. London went from 0 to 7 venue cards; all tested cities verified.
Subscription pricing canonical IDs locked
Stripe price IDs are now a single source of truth in _shared/subscription-pricing.ts, mirrored to the pricing_config table. All four edge functions (get-subscription-pricing, create-subscription-checkout, create-checkout-session, create-biab-checkout) redeployed with canonical IDs.
Talent profile URL improvements
Talent profile slugs now resolve correctly. Monique's profile moved from /talent/monique to /talent/monique-van-bokkum with a redirect from the old URL.
Gig Apply CTA fixed - links now go to source listings
Fixed a routing bug where Apply buttons on gig detail pages were pointing at undefined URLs. All gigs now link correctly to their source application pages.
GTM and GA4 removed: privacy-first analytics
Google Tag Manager and GA4 tracking removed from all pages. Analytics is now handled via privacy-first tooling only. Reduces page load overhead and removes third-party cookie dependencies.
Venue card pre-computation shipped - city pages 10x faster
Added pre-computed venue_card_payload column to city_pages. Eliminates per-request venue joins on high-traffic city detail pages. Backfill running across 340K cities.
April 202629 entries
Brand Brief shipped at /brand
/brand SSR page with hero, 11 sections, Hot Coral Pink #FF4D82 accents, Inter typeface. Linked from footer About column. Replaces the need to copy-paste brand language into outbound messages.
Mobile menu and footer rebuild
Header.tsx + Footer.tsx rebuilt. Removed legacy /people, /community, /friends links. Added /hire and /events to primary nav. Pinterest, Instagram, Facebook, LinkedIn, YouTube social icons. All link targets verified 200.
Roadmap cleaned and rescoped for launch
Roadmap state: 19 Now (was 27), 31 Next, 15 Later, 90 Shipped. Removed duplicates: Multi-Language Support, Content Scale 50M, Mobile PWA. Consolidated mobile entries into one canonical "Mobile App (PWA + native shell)".
Sitemap collapsed to a single canonical entry
Single source of truth for crawlers. The old /sitemap.xml and /sitemap-jobs.xml now permanent-redirect to /sitemap-index.xml. Robots.txt declares only one Sitemap line.
Pinterest domain verification shipped
p:domain_verify meta tag shipped to pages/+onRenderHtml.tsx and index.html. After Monique completes the claim flow in Pinterest, all pins linking to bookingagency.io will surface analytics + show the verified domain badge.
Pipeline health monitoring shipped
New check_ingest_health() function and ingest_health_log table. Cron logs alerts when any pipeline goes >6 hours without a new row. This eliminates the "we didn't notice the pipeline was dead" problem we hit last week.
Job ingestion pipeline revived - 1,400+ new jobs in 24 hours
Live job count went from 2,442 to 3,846 in one session. New jobs continue to flow hourly from 11 active sources including WeWorkRemotely, Himalayas, Remotive, Python.org, Ruby on Rails Jobs, and Cyber Security Jobs.
Expat Score Distinct from Nomad
New expat_score column differentiates long-term (1+ year) settlers from nomads (1-12 month). Weighs healthcare, citizenship path, property rights, schools.
OSM Priority Queue
814 nomad cities with sparse data (<10 listings) flagged osm_seed_priority=100. OSM scraper fills these gaps first to make nomad-relevant cities feel complete.
Crosslinks 3K → 61K (20x)
content_linking_matrix expanded with bidirectional links: country↔cities, city↔similar-global, blog↔city, city→visa-calculator, city→categories, city→nearby cities.
All 340K Cities Now Scored
Every city has nomad_score (0-100) and expat_score (0-100). 996 cities scored 60+ as nomad-relevant. ~140 cities scored 70+ as top expat hubs.
577K Venue Descriptions Expanded
city_listings descriptions expanded from 60-char boilerplate to 200-400 char rich descriptions using address, WiFi, power, pet, accessibility, and price data.
Talent Dashboard Save Fixed + RLS Hardened
owner_update_own_profile + owner_insert_own_profile RLS policies applied. Talent dashboard saves now work reliably (TBA-134).
city_listings Meta + JSON-LD Framework
Added meta_title + meta_description columns to 3.57M city_listings. LocalBusiness JSON-LD schema live on listing pages (TBA-167).
Continent Classification - 340K Cities
All 340,025 cities now classified by continent (TBA-165). /cities page will tab by Asia, Europe, North America, South America, Africa, Oceania.
Brand Logo Pack Delivered
Full brand logo package: Design A (pure heart) in 6 colorways × 13 outputs, canonical pink-filled-on-white for /public/.
152 Duplicate Cities Deduped
city_pages dedupe migration shipped (TBA-162). 152 city pairs consolidated; 31 FK tables remapped.
Footer Rewrite + Transparency Gate
Major footer overhaul with Legal, Transparency, About sections (TBA-145). RSS link to /rss/jobs.xml prominent.
Mobile City Carousel
Homepage mobile now shows a scroll-snap carousel of 6 featured cities: Bangkok, Amsterdam, Tokyo, Buenos Aires, Miami, Cape Town (TBA-163).
SEO Fix Worker - 10 Targets
Auto-healing SEO worker extended to 10 targets including images, thin content, meta tags (TBA-131 + TBA-148).
Climate Worker - Köppen Classification
City climate data auto-refreshes via Köppen lat-band approximation (TBA-146). Covers 340K cities.
Visa Verify Worker - /5min
Automated worker refreshes country_visa_info data every 5 minutes (TBA-142). Prevents stale visa info going out to users.
Visa Preset Picker
Creator trips now support 8 pre-configured visa presets - DTV, Schengen, US B1/B2, Thailand Tourist, and more (TBA-140).
Travel Dashboard Reorder
Reorganized travel dashboard for better flow (TBA-138).
Collaborations Banner Shipped
Homepage partnerships and brand collaborations banner live (TBA-137).
Trip Purpose Taxonomy - Education Added
Added Education enum to trip purposes (TBA-133) for DTV/education-visa use cases.
Admin Superbrain Menu
Consolidated admin tools behind single menu (TBA-130).
Seed Cities Tile Fixed
Homepage featured tile now renders correctly across devices (TBA-147).
3-Level Category Architecture
L1: 34 Industries. L2: 10 BLUE bookable + 14 GREEN professions. L3: Specialties JSONB. Ships with buildCategoryFilter() in SSR.