Jonathan Elmgren

Portfolio

Volvo Cars

Stack: TypeScript, React, Next.js, Node.js, GraphQL, REST, Headless CMS (ContentStack), ADO

Demo: https://volvocars.com/

Built and maintained high-traffic pages on volvocars.com (homepage, category, electrification) with Next.js, TypeScript and App Router. Developed customer-facing interactive tools including Range Map, Range Calculator and Charging Cost Tool, serving millions of visitors across all global markets.

  • Built a global recommendation engine integrating multiple systems to present market-adapted car recommendations based on popularity and sales trends, replacing a previously manual process.
  • Served as a supervisor for LIA students, coaching and supporting future developers in their professional development.

Mystery Lane - Website and Booking System

Stack: TypeScript, React, Next.js, Node.js, REST, Headless CMS (Payload CMS), Linux/Ubuntu

Demo: https://mysterylane.se

Built Mystery Lane's website from scratch with Next.js, TypeScript and a headless CMS to create a fast and search engine optimized experience. The website is adapted for escape room operations and contains informative pages and landing pages for various events.

  • Developed a customized booking system handling advanced logic for booking times and pricing, specifically adapted for escape room operations.
  • The system accounts for factors such as group size, time schedules and special pricing to optimize both the user experience and business operations.

Mystery Lane - Escape Room Technology and Puzzle System

Stack: C++, Python, WebSockets, MQTT

Demo: Internal system

Developed Mystery Lane's escape room technology with ESP32 (C++), Python, MQTT and WebSockets to create a seamless gaming experience. The puzzles and room logic are connected in a network and communicate in real time, enabling dynamic and interactive challenges.

  • Implemented OTA (Over-The-Air) Updates for maximum flexibility and maintainability, making it easy to push updates to any device without physical access.

Mystery Lane - Escape Room Control System

Stack: TypeScript, React, Next.js, Node.js, REST, Linux/Ubuntu, WebSockets

Demo: Internal system

Built a customized control system to manage the entire escape room business.

  • Remote control of rooms and puzzles - launch, restore and monitor the game in real time.
  • Monitoring via cameras and sensors - ensure the flow of the game and give clues when necessary.
  • Automated scenarios - e.g. activation of light, sound and effects at specific events.
  • Integration with the booking system - game start and timing are automatically adjusted according to bookings.

Betongföreningen - Membership API

Stack: PHP 8.4, Slim 4, MariaDB, PDO, PHP-DI, Stripe, Pest, PHPStan

Demo: Backend

Built the HTTP API that is the system of record for Betongföreningen's membership: members, member companies, payments and pricing. Membership status is derived at read time from payments and company links rather than stored as a flag, which removes a whole class of drift bugs where a cached status silently disagrees with the payment history behind it.

  • Corporate membership resolved through per-company email domains and extra-email rules, so an employee gains member benefits automatically from their employer's subscription.
  • Stripe Checkout behind a provider abstraction, with webhooks for completed, refunded and asynchronous payments, and indexed provider IDs so a refund resolves without calling back out to Stripe.
  • Strict HTTP, service and repository layering with an injected clock for deterministic time-dependent tests, RFC 7807 error responses, and SHA-256 hashed API keys scoped to per-route permissions.
  • Quality gate of formatting, PHPStan at max level with no suppressions and a Pest suite of roughly 950 tests, plus one-shot import tooling that migrated the legacy WordPress data while preserving membership number continuity.

Betongföreningen - Membership Management Plugin

Stack: PHP 8.4, WordPress, Guzzle, PHP-DI, Action Scheduler, libsodium, TypeScript, Pest

Demo: Internal system

Built the WordPress plugin the association's staff work in, giving them a native admin experience for members, companies, payments and pricing on top of the membership API. The plugin stores no membership data of its own - every read and write round-trips through the API, so WordPress never becomes a competing source of truth.

  • Searchable, sortable member and company lists built on native WP_List_Table, with detail views, manual payments, company logos, domain rules and CSV exports for reporting.
  • Read-through caching with per-resource TTLs and cross-resource invalidation, so recording a payment immediately refreshes the member and membership status views.
  • WordPress user lifecycle events synced outward through Action Scheduler with retry backoff and a dead-letter store that staff can inspect and retry from a sync status page.
  • API credentials encrypted at rest with libsodium, and typed PHP and TypeScript SDKs generated from the API's OpenAPI spec for reuse in themes and other plugins.

Matsco Bevattning - WooCommerce Webshop

Stack: PHP, WordPress, WooCommerce, Astra child theme, TypeScript, Vite

Demo: https://matscobevattning.se/

Built the webshop for an irrigation supplier as a custom WooCommerce child theme on the Astra parent. Scope was the shop itself - how products are presented, compared and found - rather than the surrounding marketing website.

  • Custom single-product template with warranty and delivery-time handling, where delivery time falls back from a per-product override to the shipping class before hiding itself.
  • Product relationships maintained from the admin as spare parts, accessories and hand-picked similar products, plus PDF datasheet attachments per product.
  • Product comparison of up to four items, implemented cookie-based and rendered client-side so it keeps working behind full-page caching.
  • Admin-configurable specification groups over WooCommerce attributes, a brand taxonomy filter alongside native layered navigation, and a bulk importer mapping a supplier's Excel columns onto WooCommerce fields.

Ellas Hjältar - Donor Hub

Stack: TypeScript, React, Next.js, PostgreSQL, Drizzle, Stripe, Billecta, Recharts

Demo: Internal system

Built a donor management portal for the nonprofit Ellas Hjältar that aggregates donations from Billecta autogiro and Stripe card payments into one place. Staff previously had to reconcile two separate payment systems by hand to answer basic questions about recurring giving.

  • Sync engine with a provider per payment system, schema validation, retry with backoff that respects rate limiting, and checkpointed incremental runs on a nightly schedule.
  • Self-healing sync that detects and recovers runs left stuck by an interrupted job, rather than requiring someone to notice and clear them.
  • Dashboard covering total and monthly giving, active subscriptions, new donors, retention, recurring revenue trend and recurring versus one-time split, each comparable against the preceding period.
  • Role-based access control with per-collection permissions and roles managed from the UI, an invite flow for new staff, and structured logging surfaced on its own admin page.

Fråga Fiskargubben - AI Fishing Advisor

Stack: TypeScript, Next.js, PostgreSQL, Drizzle, Claude (Anthropic), Better Auth, Stripe, Docker

Demo: https://fragafiskargubben.se/

Built a fishing advice service for Swedish lakes where you name a lake and a time and get concrete advice back - technique, lure and which shore to stand on. You never describe the conditions yourself: the app resolves the lake, fetches the weather and derives the rest, because you are usually already standing at the water when you ask.

  • ETL pipelines seeding roughly 7,250 Swedish lakes from public registers, with maximum depth, water colour, sight depth and fish species per lake.
  • Live SMHI weather per request, turned into the signals the model actually reasons over - water temperature estimate, light window, windward shore and pressure trend.
  • Two-tier model use where Claude Sonnet writes the first answer and cheaper Haiku handles topic gating and follow-up turns against a frozen snapshot of the same signals.
  • Resumable streamed answers that survive a client disconnect, a free-credit quota guarded by atomic updates with refunds when a stream fails, and user input passed to the model as data rather than instructions.

AFF - Allmänna Försvarsföreningen

Stack: PHP 8.4, WordPress (Full Site Editing), TypeScript, React (Gutenberg), WP-CLI

Demo: https://aff.a.se/

Built a custom WordPress block theme replacing the existing site for Allmänna Försvarsföreningen, a Swedish defence association and publisher of the quarterly magazine Vårt Försvar. Everything the site needs lives in the theme - it ships with no third-party plugins at all, which keeps the admin uncluttered for staff and removes the risk of an abandoned plugin forcing a future rebuild.

  • Custom post types for magazine issues, regional branches, events, news and projects, with a calendar split into upcoming and past events and a branch archive searchable by county.
  • Newsletter subscription with token-based confirmation and unsubscribe and scheduled cleanup of unconfirmed addresses, plus a rate-limited contact form storing hashed IP addresses.
  • Server-rendered blocks with no frontend JavaScript framework; TypeScript and React are used only in the Gutenberg editor, and design tokens defined once in theme.json are shared by editor and frontend.
  • One-shot WP-CLI migration importing the legacy site's content and subscribers with a 301 redirect map, and CI running static analysis, coding standards and tests on every pull request.

VHUD - Boat Helm Display

Stack: C, ESP-IDF, ESP32-S3, LVGL 9, NimBLE, NMEA 2000, CAN/TWAI, NVS

Demo: https://github.com/jonathanelmgren/vhud

Built a helm display for my own boat on an ESP32-S3 touch panel, replacing a set of separate gauges and a phone app with one screen. It reads the JBD smart-BMS battery packs over Bluetooth Low Energy and the outboard's engine data over NMEA 2000, so the whole bank and the engine are readable at a glance from the helm.

  • Engine data read off the NMEA 2000 bus through the board's onboard CAN transceiver, shown on the same dashboard as the battery readings.
  • BLE central client tracking several battery packs at once with a per-connection state machine and automatic reconnect, including a fallback for the HM-10 style clone modules these BMS units ship with.
  • JBD binary protocol parser written as pure C with no hardware dependencies, so it is unit tested on the host machine rather than only on the device.
  • Touch dashboard in LVGL 9 with a setup wizard that scans for packs and names them, and a battery registry persisted to flash so the setup survives power cycles.
  • Board bring-up written from scratch on ESP-IDF: I2C GPIO expander, parallel RGB display with double buffering in PSRAM, and capacitive touch.

Betongkurser.se - Course Platform for Betongföreningen

Stack: TypeScript, Next.js, Payload CMS, Node.js, Linux/Ubuntu (VPS)

Demo: https://betongkurser.se

Built a full course platform for Betongföreningen after they took over RISE's training operations. The platform handles everything from public course listings to participant registration, certificate generation and administration.

  • Automated PDF certificate generation from uploaded templates, filled with participant details - downloadable, printable or sent via email.
  • Public website with course listings, filtering, dynamic course pages and registration forms with file upload support.
  • Admin interface for managing course types, sessions, locations, participants, waitlists and cancellations.
  • Export functions for participant lists, course statistics and invoicing data.
  • Certificate tracking with timestamps and issuer logging to ensure traceability.
  • Role-based access control for admins and project managers.
  • Hosted on Hetzner VPS with Resend.com for transactional emails and Google Analytics integration.

Odinn - CRM for Lead Management and Job Distribution

Stack: Next.js, TypeScript, MongoDB, Node.js, REST API, Role-based Access Control

Demo: Internal solution

Developed Odinn, a customized CRM system for a company running dozens of lead generating websites within moving, cleaning and moving assistance. The system acts as an intermediary between customers and local businesses.

  • Automatic handling of leads - incoming booking requests are matched with suitable companies.
  • Role-based access control - local companies have their own accounts and are assigned assignments based on region and capacity.
  • Dashboard for businesses - overview of assigned jobs, status updates and order history.

Taiga - Scalable E-Commerce Platform with Pimcore

Stack: PHP, Symfony, Pimcore, MySQL, REST API, ERP Integration

Demo: https://taiga.se

Developed Taiga together with a team, an advanced e-commerce platform where Pimcore is used as PIM to manage product information and flows across multiple sites.

  • Multi-site and user-specific pricing - dynamic price management based on user role and assigned price list.
  • Advanced authentication and permissions - different customer groups see specific prices and products depending on their account type.
  • Integration with ERP - fully automated flow for product data, stock management and order management.
  • Built with Pimcore and Symfony - robust and scalable backend solution for managing large product catalogs.

BuddyCompany - Backlog Indicator & Automation Tool (at TechBuddy)

Stack: MongoDB, Express, React, Node.js (MERN)

Demo: Internal solution

Developed BuddyCompany's Backlog Indicator, an internal system built with the MERN stack to manage and visualize available assignments in real time.

  • Live overview of available missions - streamlined handling of customer cases.
  • Advanced SLA management - automatic reminders and escalation in case of SLA breach risk.
  • Automated flows - reduced manual handling through automation of tasks.
  • SLA results improved from 86% to 95.7%, and FTE decreased from 2 to 1.

BuddyCompany - Route Scheduler (at TechBuddy)

Stack: MongoDB, Express, React, Node.js (MERN), Google Maps API

Demo: Internal solution

Developed BuddyCompany's Route Scheduler, a customized scheduling system where Google Maps API is used to optimize route planning and employee scheduling.

  • Automatic route optimization - the fastest possible route is calculated based on mission location and traffic conditions.
  • ETA calculation - estimated arrival time is generated and communicated to the customer.
  • Easy scheduling - employees are assigned by simply entering booking details, after which the system calculates travel time and optimal route.
  • Integration with Google Maps API - dynamic route calculations based on current traffic data.

Betongföreningen - User Roles and Membership

Stack: PHP, cPanel, SQL, WordPress, WooCommerce (E-com)

Demo: Backend

Worked with backend development on Betongföreningen's WordPress website, building a membership system handling automatic payments via an ongoing subscription model.

  • Built support for corporate membership where employees automatically gain access to membership benefits based on the company's subscription.
  • Integrated WooCommerce and custom WordPress features for smooth and automated handling of membership, payments and user rights.

Tillfest.se - Personalized Student Signs

Stack: React, WordPress, WooCommerce, Klarna, PHP, REST API

Demo: https://tillfest.se/

Developed Tillfest.se, a website where customers can design their own personal student badges directly online. Built with WordPress and WooCommerce with a React-based personalization feature enabling live editing of signs before purchase.

  • React solution seamlessly integrated with WooCommerce and WordPress, allowing design and order information to be handled through existing e-commerce functions.
  • Payment flow implemented with Klarna, ensuring a simple and flexible payment process for customers.

Charles Dickens - Restaurant & Event Tickets

Stack: WordPress, PHP, WooCommerce, MySQL, REST API, QR Code Generation

Demo: Internal solution

Developed an event ticketing system for the Charles Dickens restaurant, fully integrated with their WordPress and WooCommerce platform. The system handles advanced pricing depending on event type, date and booking status.

  • Automatically generates QR codes for each ticket.
  • QR scan at the entrance to validate tickets and manage entry.
  • Integration with WooCommerce for smooth payment and order processing.

C Land - Headless WordPress with Next.js

Stack: Next.js, TypeScript, WordPress (Headless), GraphQL, Node.js

Demo: https://cland.se/

Developed C Land's web platform with a headless WordPress solution, using Next.js as frontend and GraphQL to retrieve data efficiently.

  • Headless WordPress with GraphQL - fast and flexible content management without classic WordPress templating.
  • Next.js for frontend - performance-optimized and SEO-friendly solution with static and dynamic rendering.
  • Optimized for speed and user experience - modern architecture with fast loading times and smooth navigation.
  • API-driven content - dynamic data retrieval via GraphQL to ensure a scalable and future-proof solution.

WordPress Projects - Custom Websites & E-Commerce

Stack: WordPress, PHP, ACF, Gutenberg, WooCommerce, MySQL

Delivered 30+ custom WordPress websites with custom themes, built with Advanced Custom Fields (ACF) and Gutenberg to provide customers with a flexible and easy-to-use administrative experience.

  • E-commerce: Wrap And Go (gift wrapping), Hästosånt (horse accessories), ZacZess (horse clothing), Stjärnglädje (reuse shop and cafe).
  • Insurance: Bilsportförsäkringar (motorsport), Golfförsäkringar (golf), Eventförsäkringar (events).
  • Services & Business: PDK Riv och Sanering (cleaning), Borås IT (IT services), Smart Home Solutions, Pelle Glas (glass workshop), MA Automation (electronics), KBT Coacherna (CBT coaching), FeelNJoy (virtual spa).