Engineering note
One backend, many brands
What maintaining a network of profession-specific tax websites taught me about shared templates, configuration boundaries, and safe production changes.
At PoliceTax, I inherited a family of live tax websites aimed at different professions. Each site needs its own identity and content, but maintaining a completely separate implementation for every brand would make every fix slower and riskier.
The system takes a more useful approach: shared PHP templates and application behaviour, with brand-specific configuration around them.
This note deliberately generalises internal names, data structures, integrations, and operational details. The engineering lessons are mine; the private implementation stays private.
The shape of the problem
The sites share important behaviour: page structure, navigation, lead and booking flows, responsive rules, and access to a common application layer. They differ in branding, profession-specific copy, links, and calls to action.
That creates a boundary that has to stay clear:
- Shared behaviour should be fixed once and inherited everywhere.
- Brand-specific decisions should remain configurable without forking the templates.
- A local visual change must not quietly alter another production site.
My work has included standardising headers, footers, and responsive styles across PoliceTax and five sister sites while keeping the details that make each brand distinct.
Shared shell, brand configuration
The reusable layer contains the common page skeleton and behaviour. Per-site configuration supplies the identity around it: names, colours, copy, links, and the identifiers needed by the application.
This is less glamorous than launching six separate frontends, but it has much better leverage. A shared fix can reach the whole network. A new brand starts with an established path rather than another copy of old code.
The difficult part is deciding where configuration stops. If every small structural difference becomes a flag, the shared template turns into a maze of conditions. If too much is hard-coded, the sites stop being meaningfully independent. I now treat that boundary as an ongoing design decision, not a one-time setup task.
Small bugs become network-wide bugs
Asset paths were a good example. A relative image path could work on one site and fail on another because the same template was being resolved from a different location. Standardising shared assets around predictable root-relative paths removed an entire class of inconsistencies.
The same pattern appeared in responsive styles and site-specific links. A header might look correct at one desktop width while a long brand name exposed a mobile wrapping problem elsewhere. A copied call to action could point to the wrong destination even though the page looked finished.
Shared code reduces duplication, but it also increases the blast radius of assumptions.
Changing live sites safely
These are production websites with real booking flows, so I avoid treating a successful local render as the end of the work. My usual sequence is:
- Trace whether the change belongs in shared code or one site's configuration.
- Make the smallest useful edit.
- Check representative brands, not only the site named in the ticket.
- Test narrow and wide layouts and follow the affected calls to action.
- Account for template caching before deciding a deployment failed.
This approach has helped with legacy template cleanup, booking modal behaviour, responsive regressions, stale cached output, and site-specific content changes.
What ownership looked like
I did not design the original architecture, so the first job was understanding it. I read the entry path, followed values from site configuration into shared templates, and traced where common behaviour met the hosted environment.
That mental model mattered when a symptom crossed layers. A modal problem might begin in markup, configuration, JavaScript, or cached output. Without understanding the request and rendering path, each fix would be a guess.
What I would carry forward
The strongest lesson is not simply "reuse code." It is to reuse the right code while making variation explicit.
Shared systems need boring conventions: predictable paths, a readable configuration boundary, small production changes, and checks that cover more than the first site you open. Those conventions are what turn a multi-brand setup from a maintenance risk into useful engineering leverage.