Global Expat Advisors

The second brand in the Online Taxman group. After rebuilding the slow WordPress site, I migrated it onto an Astro and Svelte stack by initiating a shared-code monorepo first, so the new site could reuse proven components and design tokens rather than starting over.

Global Expat Advisors homepage hero on deep navy with the headline "Where complex lives meet clear strategy", stats for clients, experience, jurisdictions and assets, two call-to-action buttons, and a portrait of founder Vincenzo Villamena
Client

Global Expat Advisors

Status

Live

Introduction

Global Expat Advisors is the second brand of the Online Taxman group, serving international entrepreneurs, high-earning Americans abroad, and cross-border families who need integrated tax, structuring, and residency planning. I rebuilt the original dated, slow WordPress site first — a big aesthetic and performance improvement — and then led its migration onto a modern static-first stack. That second phase started by standing up a shared-code monorepo so GEA could be built on an existing component library and design system rather than from zero.

Global Expat Advisors blog page with a dark navy hero titled "Global Expat Advisors insights" above a "Latest insights" section featuring a category dropdown, search field, and three article image cards

The Challenge

Global Expat Advisors originally ran as a dated WordPress site that looked its age and performed poorly, serving international entrepreneurs and high-earning Americans abroad. After the first rebuild's success, the team committed to migrating GEA onto the same modern static-first stack proven with Online Taxman, but standing up a second brand raised a decision: rebuild from scratch or invest in a shared-component system that could serve multiple brands.

The Outcome

GEA went live in production on the shared stack, proving that a second brand could be stood up on an existing component library, design-token system, and quality contract with theme overrides rather than a parallel codebase.

Tech Stack

Frontend

  • Astro
  • Svelte
  • SCSS
  • CSS
  • Zag.js
  • Usercentrics
  • reCAPTCHA
  • TanStack Form
  • HTML

Language

  • TypeScript
  • GraphQL
  • JavaScript
  • Node.js

Backend

  • WordPress
  • Cloudflare Turnstile
  • Turso
  • OpenAI

Database

  • libSQL
  • SQLite

DevOps

  • pnpm
  • Netlify
  • Husky
  • Knip
  • GitHub Actions

Tooling

  • Google Tag Manager
  • Calendly
  • ESLint
  • Stylelint
  • Prettier
  • Vitest
  • Cursor
  • Claude
  • GitHub Copilot
  • Astro 7 static-first pages with Svelte 5 islands hydrated only where genuine interactivity is needed — forms, dialogs, accordions, and search. GEA is one of two deployable sites in the workspace, alongside Online Taxman.
  • A pnpm workspace monorepo (sites/gea, sites/onlinetaxman, plus @repo/shared, @repo/design-tokens, @repo/eslint-config, @repo/stylelint-config, @repo/tsconfig). Each site owns its own src/, public/, netlify/, Astro config, redirects, and env contract; no deployable app code lives at the root.
  • TypeScript in strict mode (no any) across pages, page-data contracts, loaders, and shared exports.
  • SCSS Modules for all component styling, consuming neutral CSS custom properties emitted by @repo/design-tokens, with a GEA-owned theme layer (src/styles/variables.css) mapping --theme-* inputs to the brand.
  • Zag.js headless state machines back the accessible interactive primitives (accordion, dialog, combobox, select, steps, menu, popover) used by shared components.
  • WordPress content pulled over GraphQL through shared loaders for GEA's blog, categories, and author pages.
  • Deployed on Netlify with site-owned netlify.toml and functions; Google Tag Manager and Usercentrics consent handle analytics and privacy, and Calendly powers discovery-call scheduling.
  • Quality tooling: ESLint, Stylelint, Prettier, Vitest, Husky pre-commit, Knip, and GitHub Actions CI.
Global Expat Advisors About Us page with a dark navy hero reading "The cross-border tax & structuring firm built for a complex world", credential stats, and an "Our Team" section introducing Vincenzo Villamena, CPA

Key Implementation Details

Phase one: the WordPress rebuild

  • The original GEA site was a dated WordPress build that looked its age and performed poorly.
  • I rebuilt it end to end, delivering a substantially better-looking and considerably faster site — the version that carried the brand until the platform migration.

Phase two: the monorepo as step one, not cleanup

  • Rather than scaffolding a second standalone Astro app, I initiated the pnpm workspace monorepo first, extracting Online Taxman's proven components, icons, utilities, WordPress helpers, and TypeScript contracts into @repo/shared.
  • Design tokens moved into their own @repo/design-tokens package with a documented ownership contract: neutral tokens upstream, brand decisions in each site's theme layer, and hard rules against shared code importing site style paths.
  • Boundary enforcement is automated — style:boundaries:check plus a design-token reference checker that rejects undefined custom properties and retired token names.
  • The design system itself is the work of my design partner Laurel; I own the monorepo architecture and the engineering that makes it consumable by two brands.

Theme-layer overrides instead of forks

  • GEA reuses shared heroes, cards, steps, accordions, CTA blocks, headers, and footers, then varies them through site-owned --theme-* inputs: dark surface tokens, brand typography and radii, button font tokens, and per-theme heading and eyebrow styling.
  • Where a shared component genuinely couldn't express a GEA need neutrally, the rule was site-local composition rather than coupling shared code to one brand — keeping the library honest for a third and fourth site.
  • Site-private palette constants (--gea-*) are permitted for one-off art direction but banned from @repo/shared and from the other site.

Page data as the single source of truth

  • Every route has a mirrored entry under src/data/pages/, so copy, section composition, SEO metadata, and routing live in typed data files rather than inline in .astro routes.
  • GEA's data directory is organised into site/, site-shell/, content/, marketing/, and pages/, which keeps navigation, legal pages, service pages, and team/authority content editable without touching layout code.

Forms, anti-abuse, and lead capture

  • GEA has site-owned Astro Actions for newsletter and discovery-call workflows, built on the shared form backend rather than a per-site reimplementation.
  • Anti-bot coverage runs through a captcha provider abstraction supporting Cloudflare Turnstile and reCAPTCHA, with rate limiting, hostname fail-open handling, and Bouncer email validation.
  • The newsletter form is progressively enhanced so it still submits without client JavaScript, and submission logging uses Turso/libSQL via Netlify functions.

CI and AI-assisted development workflow

  • GitHub Actions CI detects affected workspaces and runs only the relevant shared/GEA/Online Taxman quality gates and Vitest suites, so a GEA-only change doesn't pay for a full-monorepo run.
  • A second workflow runs an OpenAI-backed PR review that loads path-scoped repository rules (forms, content loaders, page data, schema, WordPress GraphQL) and a component inventory, then scores changes against a merge threshold.
  • The repo carries a first-class agent surface — .agents/rules and .agents/skills as canonical, with thin mirrors for Copilot, Cursor, and Claude — plus an .ai/tasks archive documenting the decision trail for every migration slice.

What I Contributed

  • Rebuilt the original dated, slow WordPress site end-to-end, delivering a substantially better-looking and considerably faster site that carried the brand until the platform migration.
  • Initiated the pnpm workspace monorepo as step one of the modern-stack build, extracting proven components, design tokens, and typed contracts from Online Taxman into shared packages so GEA could be built on reuse rather than from zero.
  • Built GEA's public surface on the shared foundation: service pages, blog/content loading, legal and resources pages, form workflows, and Netlify functions, with brand differentiation expressed through a site-owned theme layer rather than forking shared code.
  • Engineered theme-layer overrides consuming neutral design tokens via --theme-* inputs for dark surface tokens, brand typography, radii, button styling, and per-theme heading design, enabling two brands to share one component library with zero coupling to either.

Outcome

  • Shared components, fixes, and improvements now land on both GEA and Online Taxman at once under one enforced set of architectural and styling boundaries, materially lowering the long-term maintenance burden across both brands.

GEA is live in production on the shared stack, and it's the proof that the shared-system bet paid off: a second brand was stood up on an existing component library, design-token system, and quality contract, with brand differences expressed as theme overrides rather than a parallel codebase. The practical wins are speed of standing up brand two and a materially lower long-term maintenance burden — fixes and improvements to shared components now land on both sites at once, under one enforced set of architectural and styling boundaries.