Skip to content
Viewing: all (23)
  1. David Lowbridge From fixed values to behaviours Brand automationUX & UIDigital strategy
  2. Mike Leonard The web is fun Motion designUX & UITechnical validation
  3. Jara Santamaria Martinez Every year is a new brief PlatformsContent strategyTechnical validation
  4. Kristina Radonjic The work between the work Digital strategyMarketing
  5. Guanglun Wu Choosing the right tech stack Technical validationPlatformsDigital strategy
  6. Barry Cumberlidge Security deep dive Technical validationContent strategyDigital strategy
  7. David Lowbridge Startups are prototypes Digital strategyBrand automation
  8. Tara Heal Shapeshifting the Future UX & UIMarketing
  9. Tom Small The theme is the guardrail Brand automationPlatforms
  10. Barry Cumberlidge Your biggest asset in an RFP, your website SEOContent strategyDigital strategyMarketing
  11. Michael Gunner Cache Components: the right content at the right time PlatformsTechnical validationContent strategy
  12. David Lowbridge From static frames to a creative operating system Brand automationUX & UI
  13. Tom Small We build by leaving things out PlatformsDigital strategyUX & UI
  14. Michael Gunner Standardise the foundations, not the brand experience PlatformsBrand automation
  15. Charlie Clarke Letting type move Motion designUX & UI
  16. Andy Purbrick Putting video back where it belongs PlatformsTechnical validation
  17. Mike Leonard The cache that doubled as a coordinator PlatformsTechnical validation
  18. Andy Purbrick We test the revenue path Technical validationDigital strategy
  19. Mike Leonard Two months in Three.js, we started over Motion designTechnical validation
  20. Rhona Mackay The form we actually trust PlatformsTechnical validation
  21. Andy Purbrick The testbed nobody will see PlatformsTechnical validation
  22. Andy Purbrick Twenty-four modules, one wrapper PlatformsContent strategy
  23. Andy Purbrick We haven’t missed a Thursday in 33 weeks Content strategyMarketing

The form we actually trust

Rhona Mackay 3 min read Platforms Technical validation

In February 2026, we replaced our contact form with a submission pipeline we built and own.

For the two years before that, it was a Pipedrive iframe inside our page. We had no control over fields, no client-side validation, no error handling beyond whatever Pipedrive showed inside its frame. When a submission failed, we found out from the client, not the system.

A screenshot of the new form we designed, built and tested.
A form we built, designed and control

Two forms, one pipeline

The start-a-project form is the full version: budget, brief, file upload, preferred dates, auto-detected timezone. It’s built as a Preact component with React Hook Form and Zod handling validation on the client. A minimal variant, just name, email and consent, runs on the AI Brand Engine page where a lighter touch makes more sense.

Both variants share the same submission pipeline. Different form surfaces, identical processing underneath. Every entry point gets the same validation, error handling and recovery, regardless of which page the inquiry came from.

The pipeline

The submission pipeline handles the sequence after the form is sent: validate with Cloudflare Turnstile, create the contact and lead in our CRM, attach any uploaded files and send a confirmation email. Newsletter signups follow a shorter version of the same flow.

Both pipeline functions accept a typed dependencies object and every external service is injected rather than imported directly, which keeps the pipeline decoupled from its environment and makes each service boundary explicit. (How this enables testing is covered in a later note.)

When things go wrong

If the lead is created but a secondary step like file upload fails, the submission still returns success to the user. The lead is safe. A structured alert fires to our team channel with enough context to recover manually.

Fatal errors, when the lead itself fails to create, alert the team with the same detail and rethrow so the user sees an error state. Nobody loses an inquiry silently.

Zod on both ends

The server-side actions run the same Zod schema again on the incoming data. Same validation, different boundary. A tampered request that bypasses client-side checks gets caught before it reaches the CRM.

From the user’s side

A form that validates as they type, shows clear error states when something’s wrong and lands on a confirmation screen with links to Labs and our Instagram, not a generic “thank you” page. They don’t know about the pipeline. They just know the form worked and the response didn’t feel like an afterthought.

The contact form’s success state: "Thank you! We’ve received your submission and will reach out within 24 hours," followed by links to our Instagram and Labs, sitting below the form’s privacy checkbox and Submit button.
The success screen — links to Labs and our Instagram, not a generic thank-you message

Since the pipeline went live in February, every submission failure has alerted the team within seconds, with enough context to recover manually.