case study · pattern · bookmarklet
Capture once, fill everywhere.
A bookmarklet pattern for non-technical users who burn hours retyping the same data into five different portals. Two unrelated proof points; one transferable solution.
The pattern
Multi-portal data entry is a workflow most ops teams quietly endure. A finance manager applies for the same vehicle loan across five lender portals. A marketer registers an executive for seven sessions of the same conference, each on a different event-management platform. The bottleneck is the same in every case: the data is identical, the portals are not.
The usual responses each have a tax. Browser extensions need IT review and a Chrome/Edge extension store listing. RPA tools (UiPath, Blue Prism) need licenses and a maintainer. A custom integration per portal needs an engineer and a vendor contract. None of these clear the bar for "I'm a non-technical operator and I need this working tomorrow."
Bookmarklets do. A bookmarklet is a javascript: URL stored as a regular browser bookmark. It runs in the context of whatever page is open when you click it. No install ceremony, no extension review, no IT approval, no vendor — works in any browser that has a bookmarks bar (which is all of them).
the leverage
One profile-capture page + one bookmarklet = N portals filled. The portals don't have to know you exist. You don't have to know which fields they expose. The matching engine figures it out.
The smart-matching engine
The bookmarklet doesn't ship with hardcoded selectors for each target portal — that would be brittle and wouldn't generalise. Instead it runs four steps on whatever page you click it on:
- 1. Read every input.
document.querySelectorAll('input, select, textarea')— every form control on the page. - 2. Resolve the label. For each input, in priority order:
aria-label→ associated<label for>→ parent<label>→placeholder→name/id(with dashes/underscores normalised to spaces). - 3. Match the label against keyword rules. Each rule lists the surface forms a label can take ("first name", "given name", "forename"). The first match wins.
- 4. Fill, dispatch events, score the result. React/Vue-friendly write via the native value setter;
input/change/blurevents dispatched so reactive frameworks notice. A small overlay reports what was filled and what to check manually.
The matching rules are visible — six examples below. Adding a new portal usually means adding zero rules; adding a new field type means adding one row.
Case 1 — Pinegrove Auto loan applications
A vehicle finance manager at a fictional NZ dealership processes loan applications for buyers who don't qualify with the dealer's primary lender. That means resubmitting the same buyer details — driver licence, employment, income, expenses, vehicle, deposit — into five separate lender portals (Beacon, Pinegrove Lending, Tasman, Northbay, Harbour). Each portal has its own field labels, its own dropdowns, its own validation. A single application can take an hour.
The capture page looks like an internal loan application — sectioned for vehicle, applicants, contacts, financials, assets, compliance. Generate Profile serialises it to localStorage. The bookmarklet, dragged once to the bookmarks bar, reads that profile and fills any lender's portal in a single click. Fields it can't match are listed in the overlay so the manager knows exactly what's left.
Try case 1
Two paths: Simulate (zero friction) opens the Beacon Finance mock portal in a new tab and runs the auto-fill on load. Drag-the-bookmarklet (authentic) is the workflow as it'd actually be used.
Case 2 — Decarbon Summit registrations on Plenari
Same pattern, completely different surface. An operations lead at a fictional climate-tech company is registering for seven sessions at an industry summit, each on a third-party event-management platform. Plenari-style platforms ship form fields you don't see in lender portals: custom-styled dropdowns built from <li>s instead of <select>s, multi-select chip clouds for topics-of-interest, radio groups whose name attributes don't match their visible labels.
The case 2 payload reuses the case 1 matching core but adds three branches: a radio-by-label-text fallback (clicks the radio whose surrounding label text contains the target value), a chip selector (clicks every [role=option] or .chip-opt whose text matches an entry in the profile's topic list), and a custom-dropdown opener (clicks the visible dropdown trigger, waits for the option list to render, then clicks the matching option). One profile, one bookmarklet, seven registrations done in the time it used to take to do one.
What this taught me
The thing I didn't expect: the pattern is more transferable than the cases that prompted it. Multi-portal data entry shows up in expense systems, government tax filings, supplier onboarding, school enrolment, insurance quotes, immigration forms — anywhere a non-technical user is the integration layer between two systems that don't talk to each other.
The thing I expected and got: this is a working observation, not a product. There's no SaaS to build here; the win is recognising the pattern when you see it and shipping the fix in a day, not building a platform.
The first case started with my mom's actual workflow at a NZ dealership. The second came two weeks later when a colleague hit the same kind of pain on a totally different platform. The pattern wasn't the goal — it's what the work taught me.
Try it · view source
Case 1 — loan portal demo · Case 2 — event registration demo · Source on GitHub
A note on the email address marco@northwind.demo shown in case 2: .demo is an IANA-reserved top-level domain that intentionally doesn't resolve, so portfolio writers can show realistic email addresses without accidentally pointing at someone else's real domain.