Context
Google Chat did not provide rich-text controls when I built this extension. My first idea was to place a formatting toolbar beside its editor, but the interface used a contenteditable element without stable identifiers. Injecting controls there would tie the extension to implementation details that Google could change at any time.
Process and decisions
I chose an independent browser-extension popup instead. People could prepare formatted text in a predictable interface and paste the result into Google Chat without the extension manipulating a third-party page.
Preact kept the interface small while retaining a familiar component model. CSS Modules isolated its styles, Vite handled the extension build, and Cypress component tests exercised the editor in a real browser rather than a simulated DOM.
The popup supported keyboard operation, accessible names, focus management, and light and dark themes. These behaviours were part of the component tests, alongside automated checks with axe-core.
Result
The extension served its purpose for several months. When Google introduced its own formatting editor, the workaround was no longer necessary—a natural end for a tool built around a temporary product gap.
Learning
A less invasive integration can be more resilient than one that reaches deeply into an interface you do not control. Sometimes success also means knowing when a workaround has finished its job.



