showcase

Lawfty CMS

year
2025/2026
role
front-end, back-end, ui/ux
based
new york, us
  • next.js
  • typescript
  • sanity.io
  • graphql
  • tailwind
  • redis
  • new relic

front-end, back-end, ui/ux

View Project

available for freelance work

social

twitter / instagram / facebook

I built a Sanity/Next.js project, essentially one CMS that powers multiple landing pages across different campaigns and law firms.

It features a schema architecture that separates environments into distinct “datasets” for production and staging.

When a new page is created in a collection, it’s automatically routed to the correct campaign based on the selected configuration.

This was my first time building a CMS designed to handle multiple page deployments from a single content source. The system was built using Next.js App Router, with GraphQL, Redis, and New Relic integrations to ensure performance, observability, and scalability.


Replacing the legacy templates

Every campaign site used to be its own hardcoded template. Adding a firm meant another page in the codebase, and any copy change had to go through a developer.

Now a page is just a list of modules, so the marketing team can build and rebrand a campaign on their own.


Modules

I wrote a set of reusable modules that editors can drag, drop and reorder: Navigation, Hero, Form, Testimonials, Grid, Bios, Carousel, Fifty-Fifty, Floating CTA, Pop-up, Text, WYSIWYG and Footer.

Here are a few of them on a live firm site: the numbered steps, the attorney bios and the practice areas grid.

The old templates did not disappear on day one. The schema still carries a legacy set of field groups alongside the modern blocks, so pages built the old way keep working while anything new gets assembled from modules. Those two sets are exactly what the control and variant in the experiment screenshot below are being tested against each other.

Content is modelled as firms, campaigns, collections and pages, with bios and testimonials attached to a campaign. Colours come from a colour palette document on the firm, so the same module renders as a different brand depending on which firm the page belongs to.

Pages are also written in English and Spanish from the same document.


Validation

Pages made of modules are easy to break, so I put the rules in the schema where they get enforced. An editor sees the problem in the Studio before publishing. Only one Pop-up module per page, for example.


Experiments

I also added an experiments layer, so a page can show different content based on the experiment returned for that visit.

An editor sets up variants on a page, say Control - Legacy (a) and Variant - Modular (b), and gives each one its own modules. The visit resolves to a variant and the matching modules get rendered. That meant the team could A/B test a whole page layout, not just the copy.

The experiments themselves are not defined in Sanity. They live in the internal admin dashboard, and I wrote custom Studio inputs that pull the experiment list and its variants from that API, so an editor picks a real experiment from a dropdown and never types an ID. The schema catches the rest: adding more variants than the experiment actually has is rejected, and so is pointing two variants at the same one. Each experiment also needs a default variant, which is what gets served when the experiment is switched off.

Visits that should not count, like internal traffic, are filtered out before a variant is assigned.


Delivery

Every firm page comes off one catch-all route, so the CMS decides which pages exist and the file system stays out of it. Sanity responses go through an Apollo link I wrote that caches them in Redis, with an authenticated endpoint the CMS calls to clear the cache when content is published, so editors are not waiting on a deploy to see their change. New Relic covers both the browser and the server side, and the app logs through Winston and Pino.

The two sites share a monorepo. Middleware, the Apollo and Redis setup, logging, env handling and the Sanity layouts sit in a shared workspace both apps import, so a fix lands in both at once.

Results

One content source now runs the campaign sites for several firms, with staging and production kept apart by dataset. Launching a new campaign is now a content job, and any page can be put behind an experiment.


Live sites

injuryfirmstl.com | socarolinainjuryfirm.com | alabamanegligencefirm.com etc.

Happy to send more links on request.

work

  1. Lawfty D2C Client Facing Project

    Direct-to-consumer campaign landing pages running on the Sanity CMS I built. Marketing assembles a page from modules and A/B tests whole layouts through the experiments layer, no developer needed.

    next.jstypescriptsanity.iographql+32026new york, us
  2. Lawfty Firms Project

    Campaign sites for partner law firms, all from one content source. Each site reads its own colours, logo and copy from the campaign config, so launching a firm is a content job instead of a new codebase.

    next.jstypescriptsanity.iographql+32026new york, us
  3. Lawfty 2.0 Internal Dashboard & Design System

    Lawfty is the data-powered personal injury law firm that offers a clear advantage in uncertain times nationwide, since 2013.

    reacttypescriptlangchainrag+82025/2026new york, us
  4. DebugCon I & II

    DebugCon is a coding conference for developers held in Prishtina, Kosovo. I was tasked to design and develop their website, also helped with branding and marketing.

    jssasshtml5figma+22022auckland, new zealand
  5. Underwriting

    The rebuild of redIQ, a multifamily underwriting platform, as Radix Underwriting. Deals, rent rolls, operating statements and valuations in one React app, with a new design system underneath.

    reacttypescriptprismapostgresql+12026remote
  6. ThankSites

    My own product: personalised birthday, Valentine's and New Year websites you make in a few minutes, pay for once and send as a link, or schedule to land in someone's inbox at the right moment.

    next.jstypescriptprismapostgresql+32026pristina, kosovo
  7. Cimerat

    An app for finding a room or a roommate in Kosovo. Owners post their rooms, people looking post themselves with a budget, and the search understands the many ways people write Albanian.

    react nativeexpotypescriptnode+22025pristina, kosovo
  8. InstaListDiff

    A free tool that shows who doesn't follow you back on Instagram, using the data export Instagram gives you. Everything runs in the browser, so nobody has to hand their login to a third-party app.

    javascriptvitetailwind2024pristina, kosovo
  9. EpicFreeGamesMail

    EpicFreeGamesMail is a tool that sends you an email every time a new free game is available on the Epic Games Store, built with React and TypeScript.

    nodegithub actionsmailjetsupabase+12025pristina, kosovo
  10. Airways New Zealand

    Airways is New Zealand's leading air navigation service provider. I was tasked to design and develop their air trafic controller manuals and showcasing a new way of how to navigate through them.

    jssasshtmlaxure rp7+22021auckland, new zealand
  11. 99urban

    99Urban is a streetwear brand, built by me, using Shopify. I designed and developed the website, worked with marketing and dove into the world of SEO and Dropshipping.

    reactshopifyliquidjest+22021auckland, new zealand
  12. Mailfomo

    Mailfomo is a daily top links aggregator, sending you the most popular links of the day to your email. The goal was to create a simple and easy to use app, with a focus to never miss the latest news.

    reacttypescriptnodesass+42023sydney, australia
  13. Prime Panels Showroom

    Prime Panels is a leading manufacturer of melamine panels. I was tasked to design and develop their showroom website. The website was shown at the Auckland Home Show 2022.

    jshtmltailwindfigma2022auckland, new zealand
  14. NZ Research Information System

    NZRIS is a web application for the New Zealand government. I was tasked with creating a digital solution for NZRIS, a new online hub dedicated to the research, science, and innovation sector.

    jshtmlcssuxpin+22021auckland, new zealand
  15. WilsonArt

    Wilsonart, a leader in decorative laminates, engaged me to design and develop their website for the New Zealand market. The website is built with Umbraco CMS, and it's fully responsive.

    javascripthtml5sassai+22022auckland, new zealand
  16. Kablamo

    Kablamo is a digital product and innovation company. One of the projects I've worked on is a known bank in Canada, an app for iOS and Android built with React Native.

    reactreact nativetypescriptrquery+22024sydney, australia
  17. Lobster & Tap

    Lobster&Tap is a seafood restaurant in Auckland, NZ, Lobster&Tap engaged me to design and develop their Kiosk web-app which allows customers to order food and drinks.

    javascriptbootstrapfigmaai+22022auckland, new zealand
  18. Daruma

    Daruma is a Japanese restaurant in Auckland, NZ. I was tasked to develop their Kiosk web-app which allows customers to order food and drinks.

    javascriptbootstrapumbracofigma+22022auckland, new zealand
  19. Linea Del Plata

    Linea Del Plata is a shipping company made up of private business groups with a long history in the maritime industry. I was tasked to design and develop their booking platform.

    jshtmltailwindfigma2022auckland, new zealand
  20. Scanatrax

    Scanatrax is a static pallet and cargo dimensioning system that delivers fast, accurate and reliable results, with full after-sales support. I was tasked to design and develop their website.

    .netc#javascriptsass+42021auckland, new zealand
  21. Flatmately

    Flatmately is a flatmate finder app, built for New Zealand and Australian market. I was tasked to design and develop their website, and also helped with branding and marketing.

    jshtmltailwindfigma2021auckland, new zealandcase study incoming
  22. NxtStep

    NxtStep is a job board for students and graduates. I was tasked to design and develop their website, and also helped with branding and marketing.

    jshtmlbootstrapsketch+22021auckland, new zealandcase study incoming
  23. Yoga With Kassandra

    Yoga With Kassandra is a yoga teacher and content creator. I was tasked to design and develop her website and courses platform while I was working at VidApp.

    jshtmlsasswordpress+22020auckland, new zealandcase study incoming
  24. Tourism New Zealand

    Tourism New Zealand is a website I've built to showcase my skills utilising JavaScript, HTML5, CSS3, SASS, Bootstrap, Sketch. I was tasked to design and develop their website.

    jshtml5css3sass+22020auckland, new zealandcase study incoming
  25. Renkon

    Renkon is a Japanese restaurant, I've pitched the new website and design for the ordering app. I used JavaScript, HTML5, CSS3, SASS, Handlebars and Bootstrap to build the website.

    jshtml5css3sass+32020auckland, new zealandcase study incoming
  26. DotaPopQuiz

    DotaPopQuiz is a quiz app built with JavaScript, HTML5, SASS, PHP. It was built as a fun project to make a game to increase brand awareness and to learn more about JavaScript and PHP.

    jshtml5css3sass+32020auckland, new zealandcase study incoming
  27. VidApp

    VidApp is a video streaming platform. I was tasked to design and develop their website and the platform where users would publish their customised app for iOS and Android.

    wordpressjshtmlsass+22019auckland, new zealandcase study incoming