Why the WordPress route
The client had two non-negotiables: the front desk team had to be able to update room rates and availability without calling me, and the marketing person had to be able to publish a blog post the same way. That's the WordPress sweet spot, and it would have been silly to fight it.
What I refused to do was reach for a page builder. The hotel's brand deserved actual typography, actual whitespace, and a layout that worked on phones — which page builders, in my experience, tend to smother under a layer of nested div soup.
The constraints
- Loads on a 3G connection in Kathmandu without making people cry.
- Booking flow doesn't bounce off the screen on a mid-range Android.
- Lighthouse 95+ on the home page. The client put this in writing.
- Front desk can edit everything from a single admin page.
How I got there
Custom blocks, not Elementor.
I wrote a half-dozen custom Gutenberg blocks — hero, room card, gallery, testimonial, booking widget, footer CTA — using ACF Pro. Each block ships exactly the markup and styles it needs and nothing more. The blogger doesn't see twenty tabs of options; they see the five they actually need.
Strict CSS budget.
Tailwind was tempting; I went with hand-written CSS instead because I wanted to ship one stylesheet, scoped per-route. The home page sends about 14kb of CSS. The whole site has fewer than 400 lines of JavaScript and no jQuery dependency, despite WordPress's protests.
Image pipeline.
AVIF for browsers that support it, WebP fallback, JPEG as the floor. Generated at build time from a single source by a small wp-cli command I wrote. The hero image is 22kb at full resolution. The gallery thumbs are 4-6kb each.
The booking widget is a thin layer over the hotel's existing channel manager — I didn't try to rebuild Booking.com. It posts to their API, handles the optimistic-render and the failure path, and falls back to a phone number that's always visible. Conversion went up 38% after this replaced the third-party iframe.
The results, since the client asks every quarter
- Mobile Lighthouse: 98 performance, 100 accessibility, 100 best practices, 100 SEO.
- Above-the-fold transfer: 87kb on the home page.
- Direct bookings (vs. third-party): up 38% year-over-year after launch.
- I have not been called to fix a bug since June 2024.
What this kind of work taught me about software
WordPress is unfashionable, but the discipline of building inside its constraints — caching, plugin compatibility, non-technical authors, decade-old admin patterns — taught me more about shipping than any framework I've used since. A working site that earns money beats a beautiful repo that doesn't, every time.