ContentMesh

A marketing and product site for ContentMesh, a no-code data-connector platform, covering home, pricing, a connectors catalogue, use cases, blog and lead capture. I was one of three developers on the build.

ContentMesh homepage featuring automation platform for digital publishers headline, descriptive text about no-code data flow management, call-to-action buttons, video placeholder with logo, and integration partner logos below
Client

ContentMesh

Status

Live

Introduction

A marketing and product website for ContentMesh, a no-code platform that moves and transforms content data between systems like Google Sheets, Strapi, HubSpot and REST APIs. The site covers the full pre-signup journey — home, product and pricing pages, a searchable connectors catalogue, use-case pages, a blog, and contact/waitlist capture — with lead submissions flowing straight into the company's CRM. I was one of three developers on the build, working through merge requests with preview deployments for every branch.

ContentMesh product page displaying a hero section with headline 'Integrate Core Business Systems with No-Code', descriptive text about digital content automation, two call-to-action buttons, and an illustration of a person viewing multiple data dashboard screens

The Challenge

ContentMesh needed a marketing and product site covering the entire pre-signup journey for a no-code data-connector platform: home, product and pricing pages, a searchable connectors catalogue with detail pages, use-case pages, a blog, and contact/waitlist capture feeding straight into the company's CRM. The content set was expected to keep growing, so the site had to make adding a connector, use case or post cheap, and it had to render server-first so content pages stayed light.

The Outcome

A live marketing site covering the whole pre-signup funnel, with leads flowing directly into the CRM and content pages rendered server-first.

Tech Stack

Frontend

  • Next.js
  • React
  • Mantine
  • markdown-to-jsx
  • Vanilla Extract
  • SVGR
  • React Server Components
  • Mantine UI

Language

  • TypeScript
  • Zod
  • Markdown

Backend

  • HubSpot
  • JSON-LD
  • Strapi
  • REST API

DevOps

  • Datadog
  • Vercel
  • Husky
  • lint-staged
  • GitLab CI
  • GitLab

Tooling

  • ESLint
  • Prettier
  • Webpack
  • Google Sheets
  • Next.js 14 App Router with React Server Components, so most of the marketing pages render on the server and ship minimal client JavaScript
  • TypeScript in strict mode across roughly 12,000 lines, with path aliases (@components, @lib, @ts) keeping imports readable
  • Mantine 7 as the component library — chosen over Chakra-style alternatives because it isn't Emotion-based and works cleanly with server rendering
  • vanilla-extract for styling: type-safe CSS-in-TypeScript compiled to static CSS at build time, wired in via the official Next.js plugin and bridged to Mantine's tokens with @mantine/vanilla-extract
  • Zod schemas paired with @mantine/form through mantine-form-zod-resolver, so the same schema validates on both client and server
  • HubSpot forms integration behind a Next.js API route for contact, waitlist and newsletter capture
  • Datadog RUM and browser logs for real-user monitoring, gated behind a cookie consent component
  • Content authored as typed data modules plus Markdown files, rendered with markdown-to-jsx — no CMS dependency to run the site
  • GitLab CI → Vercel: branch pushes get preview deployments, merges to main deploy to production
ContentMesh Connectors page featuring a hero section with headline about connecting and automating favorite applications, descriptive text about Google Sheets integration, call-to-action buttons, and an illustration showing various platform icons interconnected in a network diagram

Key Implementation Details

Consistent, modular route structure — The strongest thing about this codebase is how easy it is to move around in.

  • Every route folder follows the same shape: page.tsx, a colocated *-data.ts content module, a *.css.ts style file, and a sections/ directory for the page's composed blocks
  • Shared UI lives in a deliberately layered components/ tree (content/blocks, content/sections, layout, forms, ui), so a new page is mostly assembly rather than new code
  • Dynamic routes for connectors, use cases and blog posts all read from the same typed data modules, which keeps the catalogue pages cheap to extend

Server-validated form pipeline — Lead capture is the one place the site does real work.

  • Zod schemas live in lib/forms/schemas and are looked up by form name, so a single validateFormSubmission helper covers contact, waitlist and newsletter forms
  • The HubSpot API route re-validates on the server before submitting, returning a 400 with a structured error array on failure
  • Submissions attach HubSpot's hubspotutk tracking cookie and the request IP so form fills are attributed correctly in the CRM, plus explicit legal-consent options

SEO handled at the component level, not bolted on — Structured data is generated where the content lives.

  • Page-specific JSON-LD sits alongside each route, while reusable components like breadcrumbs and the FAQ block generate their own schema automatically for every instance
  • app/sitemap.ts and app/robots.ts use the framework's metadata APIs, backed by a shared sitemap data source and a build-time generation script
  • Full Open Graph and Twitter card metadata is centralised in the root layout, with per-page overrides via typed metadata helpers

Interactive pricing — The pricing page is the most stateful part of the site.

  • A React context drives a calculator with billing-period toggles, a usage slider and a multi-currency switcher (flag SVGs and locale-aware formatting through a shared price utility)
  • Plan cards, tooltips and dropdown comparisons all read from the same context, so the numbers stay in sync as the user changes inputs

Build and quality tooling — Enforced rather than documented.

  • A flat ESLint config covering TS, TSX, YAML and JSON, including type-checked rules, import sorting and unused-import removal
  • Prettier via Husky pre-commit and pre-push hooks with lint-staged
  • Custom webpack config to turn SVG imports into React components with SVGR, plus optimizePackageImports for Mantine to keep bundles trimmed
  • Host and trailing-slash redirects handled in next.config.mjs so canonical URLs stay clean

The friction: vanilla-extract — Worth recording honestly. Type-safe styles are appealing in principle, but the authoring experience was a drag: no imports or PostCSS variables inside .css.ts files meant things like media-query breakpoints had to be hardcoded as raw numbers, and every styling change involved more ceremony than plain CSS or SCSS would have. It works, and the generated CSS is static and fast — but I wouldn't reach for it again on a content-driven site.

What I Contributed

  • One of three developers on the build, working through merge requests with a preview deployment for every branch.
  • Built the site on Next.js App Router with React Server Components, Mantine and vanilla-extract, in a consistently modular route structure: every route folder pairs a page with a colocated content module, style file and sections directory, so a new page is mostly assembly rather than new code.
  • Built the lead-capture pipeline: Zod schemas looked up by form name behind a single validation helper, re-validated server-side in the HubSpot API route, attaching HubSpot's tracking cookie and request IP so form fills attribute correctly in the CRM.
  • Generated structured data where the content lives rather than bolting SEO on afterwards — per-route JSON-LD plus reusable breadcrumb and FAQ components that emit their own schema for every instance.

Outcome

  • A genuinely tidy codebase — clean component boundaries, a predictable route structure and enforced tooling — which is what kept a three-person build with frequent merge requests easy to coordinate.

  • No traffic, signup or revenue figures to report: the product did not find commercial traction.

A live, well-organised marketing site that covers the whole pre-signup funnel and feeds leads directly into the CRM, built server-first so the content pages stay light. There aren't traffic or conversion figures to point at, and the product didn't find commercial traction — but the codebase itself is genuinely tidy: clean component boundaries, a route structure you can predict, and consistent tooling that made a three-person build with frequent merge requests painless to coordinate.