Skip to main content

The Grand Collection

A hospitality website helping guests compare accommodation and find booking options, with tools for the business to manage property information and articles.

Next.js
TypeScript
Payload CMS
MongoDB
Cloudflare R2
The Grand Collection homepage showing its logo and booking introduction above a swimming pool.

Overview

The Grand Collection has guesthouses in multiple locations, with a website for exploring the properties and the places around them. I developed the site and its content-management tools so guests can compare accommodation and continue to booking, while the business can update property information and publish articles.

  • Role: Freelance web developer.
  • Dates: November 2024–March 2025 (initial build), with ongoing maintenance and occasional updates.
The Paarl Grand room listing showing the Mountain View Room, amenities, photographs and a Check availability button.

Guests can compare room details and amenities, then check availability through NightsBridge.

Technical contributions

1. Designing the site around the business structure

With guesthouses in multiple locations, the site needed to help visitors find the right property and help search engines identify content relevant to each area.

1.1 Content management

I linked properties, rooms, destinations and articles in Payload CMS so pages can be composed dynamically with content relevant to each property or destination.

View the CMS content models

Payload CMS article editor showing a published expansion update linked to The Paarl Grand and the Stories section.

Assigning this post to The Paarl Grand and the Stories section determines where it appears on the public site.

1.2 Visitor navigation

I connected destination pages, guides and accommodation with links and breadcrumbs so visitors can see where they are and explore related content. For example, they can browse Paarl, read a local guide and find The Paarl Grand.

View the destination-page implementation

The Grand Collection branches into guesthouses and destinations. Guesthouses have property posts under their articles URL path, while destinations have guides under their guides path. Solid lines show the hierarchy. A dotted line connects guesthouses and destination guides in both directions.

Solid lines show the URL hierarchy. Dotted lines link guesthouses and destination guides.

1.3 Structured data

I aligned the CMS relationships, site URLs and JSON-LD around the business structure. The markup connects The Grand Collection to its guesthouses and rooms, giving search engines details such as property locations, amenities, bed types and occupancy.

View the structured-data implementation

The recording below captures The Kathu Grand on the first results page for “luxury accommodation kathu”. It documents that search, rather than an ongoing ranking or the effect of any single change.

The search result opens directly onto The Kathu Grand’s property page. Recorded on 19 September 2026 with personalisation off.

2. Image optimisation

The site was exhausting its Vercel image optimisation allowance, and the previous image setup lost cached versions on rebuilds. I addressed both by generating WebP sizes during CMS upload and storing them in Cloudflare R2, independently of site deployments.

Browsers select a suitable prepared size without waiting for conversion or using Vercel’s image optimisation service. This adds upload processing and storage, but lets rebuilds reuse the images and simplifies delivery.

View image-variant generation

On upload, the CMS resizes images into WebP variants and stores them in Cloudflare R2. When viewed, Cloudflare delivers the selected size to the browser from its CDN cache, fetching from R2 only on a cache miss.

Images are processed on upload, stored in R2 and served through Cloudflare’s cache.

DevTools response headers for the homepage hero image showing status 200, Cf-Cache-Status HIT, Content-Length 102912 and Cache-Control max-age=31536000.

A production hero-image request returned a 103 kB response from Cloudflare’s cache, with browser caching allowed for one year.

3. Long-lived caching and targeted revalidation

Property information and articles can be served repeatedly between content updates. I used long-lived caching to reuse that content across requests and reduce repeated database queries.

CMS updates trigger revalidation of affected pages or sections, leaving unrelated content cached. Visitors can still receive cached content while updates refresh on subsequent requests.

View the cache revalidation hook

Outcome

I delivered a hospitality website with tools for managing property information and articles, resolved its image optimisation limits, and reduced repeated database queries through caching.

Visit The Grand Collection

View source code