Skip to content

Case study · Travel and tourism

Globalia.

Globalia, the Spanish travel group, wanted its people and its public website on one platform. Polargate built it on a single repository: an employee directory synced from Microsoft 365, a digital business card with Apple Wallet and Google Wallet passes, and the group's public site, made readable by AI crawlers without rebuilding it.

In an office above the city at dusk, a web editor updates a page for one of several brand sites, a phone preview beside the editor

At a glance

Client
Globalia
Sector
Travel and tourism
Year
2026
Services
BuildGrow
Live site
globalia.com
Stack
ViteReactTypeScriptTailwind CSSshadcn/uiSupabasePostgreSQLDenoMicrosoft 365Microsoft Entra IDVercel

01 · Globalia

The challenge.

Globalia runs several consumer brands and wanted its internal platform and its public website to take the next step together. The group wanted a staff directory that stays in step with Microsoft 365 at the scale of a large group, one card and one identity per brand, and a public site whose news archive could be read and cited by the assistants people now ask instead of a search box.

For example: 99 automated tests written for the module, from zero at the start. NationwideLegal

02 · Globalia

What we built.

Polargate built the whole thing as one web platform on a single repository, so the internal platform and the public site share code, build and deploy. The directory sync runs on Microsoft Graph delta queries and is resumable, with the continuation link stored and a time budget per run, and employees sign in with their own Microsoft 365 account, so the accounts stay under the group's control. The directory applies privacy in three layers and serves avatars signed and expiring. On top of it sits the digital business card: provisioned from the directory, claimed by the employee at first single sign-on without the public link changing, with Wallet passes signed on the server and contact data served only against a signed access token. Each brand of the group is assigned by email domain. On the public site, edge middleware injects real content for crawlers only, with no migration to static generation and no change to the application.

A laptop at a desk in an open-plan office on a rainy morning, showing an employee intranet in Spanish with the home page, news cards and quick links, while colleagues walk past behind.
Recreated scene

For example: 2 languages live on the site, Spanish and English. Global Dynamic Security Group

03 · Globalia

The result.

The directory stays in step with Microsoft 365 run after run. On the public site, a news page now gives crawlers 11,421 characters of readable content, and 707 archived articles are readable. In the August 2026 diagnostic the database showed 39 tables with row-level security and zero errors, with the row-level security policies consolidated into one policy per role and action. Before deploy: typecheck, 18 tests, the web build and the app build green, and 20 routes reviewed on desktop and mobile.

repository for the internal platform, the directory and the public site
1
characters of real content an AI crawler gets from a news page
11,421
archived news articles now readable by AI crawlers
707
tables with row-level security and zero errors in the August 2026 diagnostic
39

For example: 6 standard security headers missing before the work. B2B services company, Europe

04 · Globalia

How we did it.

For example: 11 modules delivered in Phase 1. Elite Smart Build

The context

Globalia is a Spanish travel group with several consumer brands. Polargate built the group's corporate web platform: an internal web platform with the employee directory synced from Microsoft 365, a digital business card with Apple Wallet and Google Wallet passes, and the group's public website, all on one repository.

One repository is not a detail. The internal platform and the public site share the same code, the same build and the same deploy, so a brand change happens once instead of once per site. The stack is React, Vite, TypeScript, Tailwind and shadcn/ui on the front end, Supabase on the back end (Postgres with row-level security, Edge Functions on Deno, Storage and Auth), Microsoft Graph for the directory and single sign-on, Apple PassKit and the Google Wallet API for the passes, and Vercel for hosting. The backend lives in a single Supabase project of its own.

The directory: delta queries and a sync that resumes

Employees sign in with their own Microsoft 365 account, and the directory reads from that same Microsoft 365, so the accounts stay under the group's control and nothing about a person is retyped into a second system.

The sync runs on Microsoft Graph delta queries, so each run brings only what changed instead of pulling the whole directory again.

The sync is resumable by design: the continuation link is stored, each run gets a time budget, and the next run carries on from where the last one stopped instead of starting over. That is what lets a sync at the scale of a large group finish.

Duplicates are handled by an identity merge rule that is reversible, joins the aliases of one person, and never merges two different people who happen to share a name.

Three layers of privacy

A staff directory is personal data, so it is not one dataset. It is three. The public layer carries professional information. The second carries corporate contact details. The third, personal data, sits behind an explicit permission. Avatars are served signed and expiring, so an image URL is not a permanent door.

The digital business card

Every employee has a public card page, with a mirrored English route, a vCard download, Apple Wallet and Google Wallet buttons and a branded QR code. Cards are provisioned from the directory and claim themselves when the employee signs in with SSO, and the public link does not change when that happens, so anything already printed stays valid.

Passes are signed on the server, never in the browser

Apple passes get a manifest with a hash per file and a PKCS#7 signature. Google passes get a JWT signed with RS256. The passes use QR, not NFC.

Contact data is only served against a signed access token, stable per card so printed QR codes do not expire. The field contract is an allowlist with explicitly forbidden fields, the mobile number off by default and a sanitiser as defence in depth. Cards are not indexed.

The vCard follows RFC 2426, with the photo embedded in base64 because iOS does not import photos by URL, and the page carries a visual hint that shows people which button saves the contact.

Multi-company by email domain

Globalia is several companies, so the platform is multi-company. Each brand is assigned by email domain and carries its own name and identity on the card. Access control is role based and verified.

The public site, made readable by AI assistants

A modern web application is painted in the browser, and almost no AI crawler runs JavaScript. The reader and the crawler do not get the same page, and closing that gap was the job on the public site.

We did it without migrating the site to static generation. Edge middleware injects, for crawlers only, title, description, canonical, hreflang, Open Graph, JSON-LD and a real body with a heading and paragraphs. Humans still get the application untouched, and neither the build nor the app changed.

The numbers are the point. A news page now gives a crawler 11,421 characters of readable content. Across six routes and their language mirrors, crawlers now get 756 characters on the home page and 200 to 260 on inner pages. 707 archived articles are readable.

What else is inside

Notifications do not fan out: one notification is a single row with an audience, and each user's feed is computed on the fly, honouring their preferences and the mandatory types. There is a visual board of benefits and offers, published by the people team and visible to everyone. The platform is an installable PWA that tells the user when an update is ready, and it uses Supabase Realtime instead of polling.

Where it stands

Measured, not projected. In the August 2026 diagnostic: 39 tables with row-level security and zero errors, and the row-level security policies consolidated into one policy per role and action, which is both easier to read and cheaper to run.

On weight: re-encoding the 153 frames of the home page hero to WebP cut it by 38% with no visual change, one component went from 739 KB to 3.6 KB by loading only the icons it uses, and a 423 KB chart library moved to lazy loading.

Before deploy: typecheck, 18 tests, the web build and the app build green, and 20 routes reviewed on desktop and mobile.

FAQ

Questions about this project.

Can we sync our staff directory from Microsoft 365 without copying it by hand?
Yes, with Microsoft Graph delta queries: each run brings only what changed instead of the whole directory. The part most people get wrong is size. A sync that restarts on every run never finishes at the scale of a large group, so this one was built resumable: the continuation link is stored, each run gets a time budget and the next run carries on from where the last one stopped. It keeps the whole directory of a large group in sync. Employees sign in with their own Microsoft 365 account, and the directory serves data in three privacy layers, so professional information, corporate contact details and personal data are not the same dataset.
Is it safe to give every employee an Apple Wallet and Google Wallet business card?
It is, if the signing stays on the server and the card is treated as a public page. Apple passes are signed with a manifest and PKCS#7, Google passes with a JWT signed with RS256, and no signing key ever reaches the browser. Contact data is only served against a signed access token, stable per card so printed QR codes keep working. The fields that can appear are an allowlist with explicitly forbidden fields, the mobile number is off by default, and cards are not indexed.
Do we have to rebuild our website as static HTML before AI assistants can read it?
No. Static generation is the better long-term answer, but it is not the only one, and on a live corporate site it is rarely the fastest. Here, edge middleware injects title, description, canonical, hreflang, Open Graph, JSON-LD and a real body with a heading and paragraphs, for crawlers only. Humans keep getting the application untouched, and neither the build nor the application changed. Measured result: a news page now gives crawlers 11,421 characters of readable content, and 707 archived articles are readable. Worth checking first whether your own robots rules exclude AI crawlers, because plenty of them still do.

For example: 100 / 100 / 100 Lighthouse mobile: accessibility, best practices, SEO. KD.tech

Next project

B2B services company, Europe.

B2B services

Hardening a corporate website that a DNS filter was blocking

For example: 4 days from diagnosis to the new backend running. Concert Music Festival

Get started

Tell us what you want to build.

Websites, apps, custom systems and AI for companies that need them in production in weeks. Fill in the form or book a 30 minute call: a senior engineer answers within 48 business hours with a first take on scope, timeline and price.

What do you need?
Budget
When

At least ten characters.

Answer in writing within 48 business hours. No newsletter, no automatic sequence.

Rather answer the full brief?

First step

Discovery Sprint

Two weeks to close scope, architecture and price before anything is built.

No price list. You get a private quote, in writing, after a short call.

Then, to build, always at a fixed price

Not ready yet?

AI-native digital studio for mid-market companies

POLARGATE, S.L. · CIF B24895005
Calle Electrónica 6, 28027 Madrid, Spain