SELECTED WORK · CASE STUDY

Looking after a React and Laravel Shopify card app

Maintaining an inherited custom Shopify app that lets customers design and print their own greeting cards: a React admin and editor, a Laravel API, a checkout extension and Docker on AWS.

Platform: ,
AWS:
  • Client Greeting card brand
  • Platform Shopify app: React (Polaris, App Bridge, Vite), Laravel, checkout UI extension, Docker on AWS
  • My role Technical lead: maintenance, support and releases
  • Focus Keeping a complex custom app reliable

The context

A greeting card brand lets customers design their own cards online, then has them printed and sent. That experience runs on a custom Shopify app, and it is far more than a form on a product page. It is a small product in its own right. Our team didn’t build it; my job was to keep it running well and to change it safely.

What the app does

  • Card personalisation: customers upload their own photos into clipping-masked frames, add stickers, choose fonts, and write or pick from a categorised message library, with a profanity filter.
  • Drafts: designs can be saved and picked up later, with drafts expiring after a set period.
  • Print-ready output: each finished card is turned into a PDF for printing.
  • Checkout: a checkout UI extension for choosing how the card is delivered, plus custom shipping rates and discounts.
  • Merchant admin: an embedded Shopify admin app built with React, Polaris and App Bridge for managing cards, messages, fonts and stickers.

How it’s built

  • React front end on Vite, using Polaris and App Bridge for the embedded admin, and React Query for data.
  • Laravel back end handling the Shopify OAuth flow, the Admin API, webhooks and the card data.
  • A Shopify theme and a checkout UI extension for the customer-facing parts.
  • Docker on AWS, with Bitbucket Pipelines deploying through integration, staging and UAT environments, and SonarQube code analysis in the pipeline.

Maintaining software you didn’t write

  • Understand before changing. With a React app, a Laravel API, a theme and a checkout extension all involved, the first job on any ticket is working out which part actually owns the behaviour.
  • Small, traceable changes. Each change goes through a ticket-named branch and is promoted through staging before production, such as adjusting how long saved card drafts last.
  • Respect the environments. Integration, staging and UAT exist so the client can check changes before customers see them; every release uses them.
  • Leave it easier for the next person. Access, environments and deployment steps are documented, so anyone on the team can connect, diagnose and release.

The lesson

Inherited apps reward patience. Learn how each layer works, change one thing at a time, and let the pipeline and test environments do their job. That is how a complex custom app stays dependable for the people using it every day.


This case study is anonymised. Client names, systems and figures are withheld; architecture details are simplified for illustration.