Sitemap
Main Pages
- Homepage
- About
- Services
- Bespoke Website & Software Development
- Project Architecture & Management
- Performance Audits
- Search Engine Optimisation (SEO)
- Accessibility & Usability Reviews
- Ongoing Support & Maintenance
- Project Hosting
- Development Leadership & Mentoring
- Embedded Development
- Technical Writing & Documentation
- Code Reviews & Optimisation
- Creative Agency Partnerships & Development
- Projects
- Articles
- Timeline
- Availability
- Contact
Portfolio Projects
- Virgin Atlantic & Holidays
- Nando’s
- John Lewis
- The World Economic Forum
- Selfridges
- Polestar
- Boohoo Group
- Lotus
- IMG Licensing
- Wreel Agency
- LEGO
- Plex.tv
- Style.com
- HSBC Corporate Banking
- Moscot Eyewear
- BBC Future Media
- Red Central
- Tony's Chocolonely
- Bose Product Support
- ToyBoxX
- Navico
- Linkudo
- Dataffirm
- Cox & Kings
- Macmillan Education
Support Pages
Social Accounts
Article Categories
- Accessibility
- Adaptive Development
- Algorithms
- AMP
- Angular
- April Fools
- Architecture
- Artificial Intelligence (AI)
- Brighton
- Career
- Chakra UI
- CMS
- Consulting
- Contentful
- Copyright
- Cross‑Browser Compatibility
- CSS
- Cypress
- Data Structures
- Dev Match
- Development
- ES6
- Front‑End Development
- FTP
- Gatsby
- GDPR
- Generative Engine Optimisation (GEO)
- Git
- GraphQL
- Guides
- Hiring
- Hosting
- .htaccess
- HTML
- Image Rendering
- Internet Explorer
- JavaScript
- jQuery
- JSX
- Leadership
- LeetCode
- Liquid
- Miscellaneous
- Netlify
- Next.js
- Node.js
- Performance
- PHP
- React
- Responsive Development
- Sass
- Search Engine Optimisation (SEO)
- Security
- Server‑Side Rendering (SSR)
- Shopify
- Sitemaps
- styled‑components
- Testing
- TypeScript
- Typography
- Vercel
- Video
- Vue.js
Articles
- Backtracking Decision Trees: Solving 'Combination Sum'
- GEO vs. SEO: Where They Overlap, and Where They Don't
- Solving the 'Jump Game' Problem with Greedy Algorithms
- Memoization in JavaScript: Optimising Function Calls
- Dynamic Programming in LeetCode: Solving 'Coin Change'
- Handling API Routes in Next.js: When to Use Server Actions vs. API Routes
- LeetCode: Finding the Diameter of a Binary Tree
- Topological Sort: Solving the 'Course Schedule' Problem
- What GEO is, and Why It is Not Just SEO for AI
- Understanding the Module Pattern in JavaScript
- Multi‑Source BFS: Solving the 'Rotting Oranges' Problem
- Caching Strategies in React
- Quickselect in TypeScript: Solving 'Kth Largest Element in an Array'
- Practical Use Cases for JavaScript
SetandMap - Find Peak Element: Binary Search Without a Fully Sorted Array
- Graph Traversal: Solving the 'Course Schedule' Problem
- Dev Match Ltd., James McConnell, and the Refund That Never Came
- Testing Vue Components with Vue Test Utils
- Modified Binary Search: Solving 'Search in Rotated Sorted Array'
- LeetCode: Solving the 'Merge Two Sorted Lists' Problem
- Binary Search on the Answer: Solving 'Koko Eating Bananas'
- Understanding Tail call Optimisation in JavaScript
- Understanding
WeakMapandWeakSetin JavaScript - JavaScript Symbols: When and Why to Use Them
- React's Virtual DOM vs. the Real DOM
- Best Practices for Vue Router in Large Applications
- How JavaScript Handles Memory Management and Garbage Collection
- Implementing Server‑Side Rendering (SSR) in Vue
- Monotonic Stack: Solving the 'Daily Temperatures' Problem
- Generate Parentheses in TypeScript: A Clean Backtracking Walkthrough
- Implementing a Trie in TypeScript: Solving 'Implement Trie (Prefix Tree)'
- Building Efficient Recursive Functions in JavaScript
- The Execution Context in JavaScript
- Optimising Performance in React with
useMemoanduseCallback - Solving the LeetCode 'Binary Tree Zigzag Level Order Traversal' Problem
- Why Next.js Middleware Might Be Unavailable with Pages Router
- Optimising Next.js Performance with Incremental Static Regeneration (ISR)
- Reverse an Array in JavaScript
- Preventing and Debugging Memory Leaks in React
- Creating Custom Vue Directives for Enhanced Functionality
- Breadth‑First Search: Solving Binary Tree Level Order Traversal
- Prefix Sums and Hash Maps: Solving 'Subarray Sum Equals K'
- Container Queries in CSS
- Building a Headless CMS‑Powered Site with Next.js
- Sorting Complex Arrays in JavaScript
- Understanding the Backtracking Approach: Solving the 'Word Search' Problem
- CSS
aspect‑ratiofor Responsive Layouts - Fast and Slow Pointers: Solving the 'Linked List Cycle' Problem
- Building Multi‑Tenant Applications with Next.js
- Single Number in TypeScript with Bit Manipulation
- Ethical AI: Sustainability, Ethics, and the Future
- Building a Custom Vue 3 Hook Using the Composition API
- Redirect a Default Vercel Subdomain to Your Custom Domain
- Grid Traversal: Solving the 'Number of Islands' Problem
- Vue's
provide/injectAPI: When and How to Use It - Ethical AI in Web Development: AI's Impact on Developers and the Industry
- Vue 3 Reactivity: Proxies vs. Vue 2 Reactivity
- Understanding the Difference Between
<b>and<strong> - Optimising Vue.js Performance with Lazy Loading and Code Splitting
- Sliding Window Fundamentals: Solving 'Longest Substring Without Repeating Characters'
- Using Middleware in Next.js for Route Protection
- Control CSS Container Layouts with
place‑content - Simplify Your Layout CSS with
place‑items - Optimising Angular Forms: Template‑Driven vs. Reactive Forms
- Converting Between Camel, Snake, and Kebab Case in JavaScript
- LeetCode: The 'Trapping Rain Water' Problem with Two‑Pointer Approach
- The Rise of AI in Web Development
- Lazy Loading in Angular: Optimising Performance
- A Brief Look at JavaScript's
TemporalDates and Times API - Next.js vs. Remix: Understanding the Key Differences
- Horizontal & Vertical Scanning: The Longest Common Prefix Problem
- Intervals in Practice: Solving the 'Merge Intervals' Problem
- Understanding the CSS
:where()Function - Understanding Signals in Angular: The Future of Reactivity
- Generating Email Addresses from Public Data is Illegal
- Using Vue's Suspense for Asynchronous Components
- Declarative vs. Imperative Programming
- Prefix and Suffix Products: Solving 'Product of Array Except Self'
- Currying in JavaScript Explained
- LeetCode: Removing the
nthNode from the End of a List - Building Custom Directives in Angular
- The Palindrome Number Problem: Strings vs. Maths in JavaScript
- Building Design Systems for Web Applications with Figma, Storybook, and npm
- Caching Strategies for Data Fetching in Next.js
- What are Higher‑Order Components in React?
- Object Control in JavaScript:
defineProperties() - The JavaScript
map()Method - Angular Standalone Components: Do We Still Need Modules?
- React's Reconciliation Algorithm Explained
- Finding the Median of Two Sorted Arrays with JavaScript
- Understanding Event Loop and Concurrency in JavaScript
- Exploring the
call()Method in JavaScript - The Role of Dependency Injection in Angular
- Understanding Short‑Circuiting in JavaScript
- Finding the Difference Between Two Strings in JavaScript
- Using Vue's Teleport for Modals and Portals
- Tips for Managing Memory in JavaScript
- Understanding the Difference Between 'Indexes' and 'Indices'
- Best Practices for Angular Routing and Lazy Loading
- Track Element Visibility Using Intersection Observer
- Deep‑Cloning vs. Shallow‑Cloning in JavaScript
- Mastering JavaScript Iterators and Generators
- Access Search Parameters in Next.js SSR'd Layout
- Flattening Arrays in JavaScript
- Unit Testing in Angular: Writing Effective Tests
- Delete All Local Git Branches Except for
masterormain - Use JavaScript to Find the Week Day from a Date
- Dynamic Sizing with CSS
clamp() - Understanding Object Types with JavaScript's
instanceof - Implementing Authentication in Next.js Using NextAuth.js
- Understanding Transient Props in
styled‑components reduce()in JavaScript- Creating Progressive Web Apps (PWAs) with Angular
- Dynamic Sizing with CSS
max() - Object Equality in JavaScript:
{}isn't Equal to{} - Pure Functions in JavaScript
- Understanding the Composition API in Vue 3
- Dynamic Sizing with CSS
min() - Testing the Content of JSX Data in Cypress
- Angular Change Detection: How It Works and How to Optimise It
- Validating Parentheses Input Using TypeScript
- Dynamic Calculations in CSS Using
calc() - Leveraging
.then()in Modern JavaScript - Stopping Propagation vs. Preventing Default in JavaScript
- Solving the 'Letter Combinations of a Phone Number' Problem with TypeScript
- Creating Custom Viewport Units Instead of Using
vhandvw - Introducing Seeded Randomisation into an SSR Gatsby Project
- LeetCode: Converting Roman Numerals to Integers
- LeetCode: Converting Integers to Roman Numerals
- Staying Current: Automating Copyright Year Updates
- Repetitive Asynchronous Tasks with JavaScript's
setInterval() - Dynamic Navigation with React Router
- Understanding and Solving Regular Expression Matching
- LeetCode Container with Most Water: The Two‑Pointer Solution
- How Much Do Software Engineers Make in the UK?
- Top Reasons to Work with a Local Web Developer in Brighton
- Is a Software Engineer High Paying?
- Understanding
prototype.apply()in JavaScript - The Longest Palindromic Substring in JavaScript
- Enhancing Web Typography with
text‑wrap: balance - Using JavaScript and the Two‑Pointer Technique to Solve 4Sum
- The Power of
text‑wrap: pretty - JavaScript's
hasOwnProperty()Method - 3Sum Closest in JavaScript: Sorting and Two Pointers
- Removing Duplicates from a JavaScript Array ('Deduping')
- Add Two Numbers in TypeScript: Linked Lists Without the Hand‑Waving
- Trigonometric Functions in CSS
- 3Sum in JavaScript: Two Pointers After Sorting
- JavaScript's
typeofOperator: Uses and Limitations - Will AI Replace Front‑End Developers?
- Rethinking Carousels: Going Around in Circles
- Differences Between Falsy and Nullish Values in JavaScript
parseIntin JavaScript: The Significance of Radix- Longest Substring Without Repeating Characters in JavaScript
- Valid Palindrome in JavaScript: Two Pointers and Normalisation
- Harnessing the Power of
Prototype.bind() - Automatically Generate Text Sitemaps in Gatsby
- Harnessing JavaScript's
defineProperty() - String to Integer (atoi): Decoding Strings in JavaScript
- JavaScript Array Manipulation:
slice()vs.splice() - Understanding the Nullish Coalescing (
??) Operator in JavaScript - Understanding
setTimeout()in JavaScript - The LeetCode Zigzag Conversion Problem in TypeScript
- Common Accessibility Pitfalls in Web Development
- Sorting Objects in JavaScript
- Commenting in Front‑End Languages
- Return the Length of Arguments Passed in JavaScript
- Dynamic Array Manipulation with JavaScript's
splice() - Swearing in the Workplace
- LeetCode: Reversing Integers with JavaScript
- Using the
filter()Method in JavaScript - Happy Holidays!
- Manipulating Strings in JavaScript with
split() - Check If Today is Between Two Dates in JavaScript
- JavaScript String Manipulation:
substring()vs.substr() - Solving the LeetCode Two Sum Problem Using JavaScript
- Why We Use an Empty Dependency Array in React's
useEffectHook - Mastering JavaScript's
slice() - Understanding JavaScript's
sort()Method - Responsive JavaScript and the
matchMediaMethod - Unravelling JavaScript: Commonly Misunderstood Methods and Features
- The
will‑changeProperty in CSS - Using the Modulo Operator in JavaScript
- Throttling Scroll Events in JavaScript
- What A Levels Do You Need for Software Engineering?
- How to Handle Multiple Named Exports in One JavaScript File
- How to Import All Named Exports from a JavaScript File
- Check If a String Contains Only Whitespace with JavaScript
- Higher‑Order Functions in JavaScript
- Improve Page Performance with
content‑visibility - Resolving
mini‑css‑extract‑pluginWarnings in Gatsby - The End of Internet Explorer
- Using Container Queries in CSS
position: stickyin CSS- Using the CSS
:hasPseudo‑Class - Spread Syntax in JavaScript (
...) - The Safest Way to Test for
NaN - When to Use
varorletorconst - What is a Distributed Denial of Service (DDoS) Attack?
- Gatsby & GraphQL: Nodes vs. Edges
- HTML Video and the
preloadAttribute - Why You Should Not Use Protocol‑Relative URLs
- Can I Learn Front‑End Development in 2 Months?
- Where to Find Jobs in Web Development
localStoragein JavaScript- Detecting Breakpoints in React Using Chakra UI
- How to Improve Your Time to First Byte (TTFB)
- Optional Chaining in JavaScript (
?.) - Semantic HTML
- Positioning in CSS
- Why is Time to First Byte (TTFB) Important?
- Automatically Submit Sitemaps to Google During Gatsby Build
- Margin Collapse in CSS
- Use CSS to Change the Mouse Cursor
- Exploring CSS Viewport Units Beyond
vwandvh - Happy Holidays!
- Cleaning up Your JavaScript Code: The Double Bang (
!!) Operator - Web Development and the Environment
- Understanding and Using Flexbox in CSS
- React vs. Vue vs. Angular
- Specificity in CSS
- Static Site Generators
- Use Chrome's Developer Tools to Track Element Focus
- 10 Essential SEO Tips for Front‑End Developers
- All About Headless CMSes
- How to Amend Git Commits
- A Beginner's Guide to Web Hosting
- What Makes a Great JavaScript Developer?
- Do Websites Need to Look the Same in Every Browser?
- Adaptive vs. Responsive Design & Development
- What Skills are Required for a Front‑End Developer?
- What is an HTML Entity?
- Flexbox vs.
grid - Renaming and Destructuring Variables in ES6
- How to Choose a React Developer
- Create Arrays of Any Size with Placeholder Content in JavaScript
- The Quirks of
z‑index - How to Rename Local and Remote Git Branches
- How to Hire a JavaScript Developer
- ReferenceError: Window is Not Defined in Gatsby
- Life as a Freelance Developer in Brighton
- Has Google Killed AMP?
- Ethical Web Development ‑ Part II
- Hiring a Freelance Front‑End Developer ‑ An Ultimate Guide
- Changing the Colour of Placeholder Text
- Ethical Web Development ‑ Part I
- Git is a Little Bit Like a Diary
- How Much Does a Front‑End Developer Make?
- The Differences Between Lead and Senior Roles in Front‑End Development
- Block Bad Bots Using
.htaccess - What Does Front‑End Development Mean?
- What is Front‑End Development?
- Access CSS Variables from a Database via
db‑connect - Installing Gatsby onto an M1 MacBook Air
- React: Functional, Class, and Pure Components
- What Does a Software Engineer Do?
- How to Find a Programmer Job
- Preview Mode in Next.js with a Headless CMS
- Detecting and Dealing with Website Theft
- Sort the Keys of an Object with JavaScript
- Disabling Gatsby Telemetry
- Removing
pTags from Contentful List Items - Rendering Contentful Rich Code Snippets in Gatsby
- What are Array‑Like Objects in JavaScript?
- Replace Inline Styles in Gatsby with an External CSS File
- Why I'm the Best Choice for Web Development Near You
- Disabling Source Maps in Gatsby for Production
- Image Optimisation with
next/image - Optimising
gatsby‑imageEven Further - Using Regex to Replace Numbers in a String
- Intercepting Clipboard Events with JavaScript
- Dynamic Imports and Code Splitting in Next.js
- Adding Static Files to a Gatsby Site
- CSS Focus Styles for Keyboard Users Only
- Parent Selectors in CSS and Sass
- Automatically Deploy a Static Gatsby Site via FTP
- Using JavaScript to Avoid Orphans
- Understanding
getStaticPathsin Next.js - Using CSS to Deal with Widows
- Use Greater‑Than and Less‑Than Symbols in JSX
- Reducing Image Brightness with CSS
- Commenting in JSX
getStaticPropsvs.getServerSidePropsin Next.js- Creating a Discernible Name for Icon Links
- Interpolation: Sass Variables Inside
calc() - Building Custom Hooks in React
- What is a Static Site Generator?
- Static Generation vs. Server‑Side Rendering in Next.js
- Redirect a Default Netlify Subdomain to Your Custom Domain
- Break Out of CSS Nesting with Sass
- Advanced Sass: Loops
- Hiding Empty Elements with CSS
- Disabling Text Selection Highlighting with CSS
- Alternative Text in the CSS
contentProperty - Prepending PHP to a Page in Gatsby
- Automatically Generate
urllist.txtfromsitemap.xml - If Not Internet Explorer Conditional HTML
- Throttling vs. Debouncing in JavaScript: Managing Event Frequency
- How to Replace All Instances of a String in JavaScript
- Understanding Element Dimensions in JavaScript: Width and Height
- How to Use and Clear the CSS
floatProperty - Using
displayin CSS - How to Use
gridin CSS useReducerin React- Check If Three Values are Equal in JavaScript
- Toggle a Boolean in JavaScript
- Dynamic Routes in Next.js
- 301 vs. 307 Redirects
- JavaScript's
Math.random() useRefin React- Exploring the Liquid Templating Language
- React Hooks: Modern State Management
- Class vs. Functional Components in React
- Advanced Techniques for Responsive Web Design
- Custom
_appand Custom_documentin Next.js - Understanding the JavaScript Event Loop
- Creating Interactive User Interfaces with HTML, CSS, and JavaScript
- Simplify Asynchronous JavaScript with
async/await - How to Prevent Race Conditions in JavaScript with
AbortController - Best Practices for Cross‑Browser Compatibility
- Using
next/linkfor Client‑Side Navigation - Event Delegation in JavaScript
- The React Context API: When to Use It and When Not to
- Merging Multiple Objects in JavaScript
- Event Bubbling vs. Capturing in JavaScript
- Leveraging JavaScript Frameworks for Efficient Development
- The Fetch API for Beginners: Get, Post, JSON, and Errors
- Tagged Template Literals in JavaScript
- Escaping and Unescaping Special Characters in JavaScript
- Integrating CMSes with HTML, CSS, and JavaScript
- React Error Boundaries Explained
- Manipulate Elements with CSS
transform Object.keys(),Object.values(), andObject.entries()Explained- Single or Double Colons in CSS Pseudo‑Elements (
:beforevs.::before) - CSS
box‑sizing: Controlling the Element Box Model - Understanding File‑System Routing in Next.js
- JavaScript Hoisting: Variables, Functions, and More
- Closures in JavaScript: The Key to Lexical Scope
- Static Methods vs. Instance Methods in JavaScript Classes
- Understanding the
:hoverPseudo‑Class in CSS - The Value of Choosing a Web Developer Near You: Customised Solutions for Local Success
- Using Viewport Units in CSS:
vwandvh - Mutation vs. Immutability in JavaScript Arrays and Objects
Array.includes()vs.indexOf()in JavaScript- React Portals Explained
- Enhancing User Experience with CSS and JavaScript Animations
- CSS Animations: Transitions vs. Keyframes
- React Fragments Explained
- Understanding Media Queries in CSS
- Optimising Website Performance with HTML, CSS, and JavaScript
- Mastering CSS Animations with
@keyframes extendsandsuperin JavaScript Classes- JavaScript Essentials for Freelance Web Developers
- Some of the Most‑Misunderstood Properties in CSS
::beforeand::afterPseudo‑Elements in CSSPromise.all()vs.Promise.race()in JavaScript- Generators in JavaScript: A Beginner's Guide
- Building Polyfills for JavaScript Array and String Methods
- JavaScript Error Handling Patterns
- The CSS
overflowProperty - The Difference Between JavaScript Callbacks and Promises
Array.find(),Array.some(), andArray.every()in JavaScript- Understanding CSS Transitions
Object.is()vs. Strict Equality in JavaScript- What is CORS and Why is My JavaScript
fetchBlocked? - Creating and Dispatching Custom Events in JavaScript
- Mastering CSS for Freelance Web Development Projects
- What are CSS Preprocessors, and Why Should You Use Them?
- Fundamentals of HTML: A Guide
Object.freeze(),Object.seal(), andpreventExtensions()- CSS
visibility: Hiding Elements Without Affecting Layout - Controlling Element Transparency with CSS
opacity - Optimising HTML Markup for SEO
Number.isNaN(),Number.isFinite(), andNumber.isInteger()in JavaScript- Browser vs. Node.js in JavaScript: Why Code Works in One and Fails in the Other
- Understanding CSS Positioning
- Promises in JavaScript: An Introduction
- Function Declarations vs. Function Expressions vs. Arrow Functions
- Rest and Spread Operators in JavaScript: A Beginner's Guide
- Template Literals in JavaScript: Writing Multi‑Line Strings
String.startsWith(),endsWith(), andincludes()in JavaScript- Understanding Phantom
window.resizeEvents in iOS for...invs.for...ofin JavaScriptJSON.parse()andJSON.stringify()Explained for Beginners- Default Parameters in JavaScript in More Depth
Array.from()andArray.of()in JavaScript- Default Parameters in JavaScript: A Guide
- Understanding Arrow Functions in JavaScript
- The
argumentsObject vs. Rest Parameters in JavaScript - Why HTML Form Values are Always Strings in JavaScript
- Object Property Shorthand and Computed Property Names in JavaScript
nullandundefinedin JavaScript- Exporting and Importing Using ES6 Modules
Object.assign()in JavaScript: Merging and Shallow Copies- Rendering Lists in React and Why Keys Matter
- The Difference Between
==and===in JavaScript - Classes in JavaScript: An Introduction
- Comparing Arrays in JavaScript
- Invoked Function Expressions (IIFE)
- Understanding
call,apply, andbindin JavaScript - Appending and Prepending Items to an Array
- How Inheritance Works in the JavaScript Prototype Chain
- Type Coercion in JavaScript: Implicit vs. Explicit Conversion
- Using CommonJS to Implement Modules in JavaScript
- Five Tips for Transitioning from Permanent to Freelancing
- How to Find the Best Web Developer Near You: A Guide for Local Businesses
- Controlled vs. Uncontrolled Components in React
- Why
thisChanges in JavaScript Event Handlers and Methods - Looping in JavaScript ES5 and ES6:
forEachandfor...of - Asynchronous Module Definition (AMD) in JavaScript
- Getting Started with Callbacks in JavaScript
- Primitive vs. Reference Types in JavaScript
- Lifting State up in React
- Check If Your Site is Running on
localhost - Five Tips on How to Be a Good Web Developer
- Dynamically Create a Script Element with JavaScript
- How to Read JavaScript Errors and Stack Traces
- Pass by Value vs. Reference in JavaScript
- Accessing a Random Element from an Array Using JavaScript
- Why Hiring a Local Web Developer Near You Matters
- Get the Number of Years Between Two Dates with PHP and JavaScript
- Using
data‑*Attributes anddatasetin JavaScript - DOM Traversal:
closest()in Vanilla JavaScript and jQuery - Using
classListin JavaScript:add(),remove(),toggle(), andcontains() !importantin CSS- Handling Click Events in JavaScript
DOMContentLoadedvs.loadin JavaScript- Why
querySelectorReturnsnullin JavaScript - How to Check an Element Exists with and Without jQuery
- A Simple Popup Window Using jQuery
- Setting CSS Blur Filter to Zero on a Retina Screen