- Index:
- 03
- Industry:
- Hospitality & Restaurants
- Year:
- 2026
- Status:
- Delivered
The Thai
A statically generated Next.js rebuild of thethai.uk that turned a PDF-only menu into 42 crawlable dishes, moved 28 blog posts off WordPress without dropping a URL, and brought the navy and gold of the printed menu onto the web.

The old thethai.uk was WordPress, and its menu was a PDF. Every dish, every price and every allergen note sat inside a file that search engines cannot read as a menu and that a phone will not display well, so the single thing most people arrive at a restaurant site to look at was effectively invisible. The blog was the other half of the problem. Twenty-eight posts had built up on WordPress URL shapes, /uncategorized/ post paths, category and author archives, per-post RSS feeds and year, month and day date archives, and a rebuild that changed the URL structure would have thrown away whatever those links were worth. On top of that, the site did not look like the restaurant: the printed menu in the room was navy and gold, and the website was not.
We rebuilt the site from scratch as a statically generated Next.js App Router build with Tailwind, and took the brand off the printed menu rather than inventing one, navy and gold tokens plus Marcellus and Figtree as the type pairing. The menu became the centrepiece: 42 dishes across nine sections, rendered as real HTML with descriptions, prices, per-variant pricing and allergen labels, and emitted as Menu JSON-LD so a search engine reads it as a menu rather than as a link to a download. On top of that sits a client-side filter, vegetarian dishes, mild or no spice, and exclusion of any of the eleven allergens present in the data, all with no page reload and no server call. The blog moved across as Markdown with Article structured data, and we wrote 25 redirect rules covering the old post URLs, the category and author archives, the per-post RSS feeds, the date archives and the wp-content menu PDF that every old Menu link pointed at. Restaurant JSON-LD in the layout carries the address, geo coordinates, opening hours and award. Photography and video are served from Vercel Blob rather than committed to the repository. The site also stopped handing reservations to a third-party widget: booking now happens on the site itself, with a staff diary behind it.
Rebrand & Homepage
The restaurant already had a brand, it just was not on the website. We took the navy and gold off the printed menu, built them into design tokens with Marcellus for display and Figtree for body, and rebuilt the homepage around the restaurant photography rather than around a theme.
- →Navy and gold palette and type pairing taken from the printed menu, not invented
- →Homepage rebuilt around the restaurant photography and the essentials, hours, location, menu and booking
- →Statically generated App Router build with Tailwind, no CMS and no plugin stack to maintain
- →Photography and video served from Vercel Blob, keeping large media out of the repository

The Menu, Rebuilt as HTML
This is the page the rebuild was really for. The menu moved out of a PDF and into typed data rendered as HTML: 42 dishes across nine sections, with descriptions, prices, per-variant pricing where a dish comes as veggie, chicken or prawn, and allergen labels on every item. A client-side filter sits on top so a guest can narrow to vegetarian dishes, to mild or no spice, or exclude specific allergens before they ever phone.
- →42 dishes across nine sections rendered as indexable HTML with prices and descriptions
- →Per-variant pricing handled properly, so a dish offered as veggie, chicken or prawn shows all three
- →Allergen labels on every dish, drawn from the same data the filter uses
- →Filter chips for vegetarian, mild or no spice, and exclusion of any of eleven allergens, client-side and instant
- →Menu JSON-LD with a MenuSection per course and an Offer per price, so the menu is readable by search engines
- →The PDF is still linked for anyone who wants it, it is just no longer the only version



Blog Migration & Local SEO
Twenty-eight posts came across from WordPress as Markdown. The interesting work was not the content, it was the URLs: WordPress had been serving those posts under /uncategorized/ paths, with category and author archives, a per-post RSS feed each, and year, month and day date archives all linked from the old post cards. Every one of those shapes now redirects permanently to its equivalent on the new site.
- →28 posts migrated from WordPress as Markdown with Article structured data
- →25 permanent redirect rules covering post URLs, category and author archives, RSS feeds and date archives
- →The wp-content menu PDF URL, which every old Menu link pointed at, redirected to the new menu page
- →Restaurant JSON-LD in the layout with address, geo coordinates, opening hours and award
- →Per-page metadata, canonical URLs, sitemap and robots generated at build time

Booking & Contact
The old site handed reservations to a third-party widget. Booking now lives on the site: availability is computed from the restaurant tables and areas held in Postgres, guests amend or cancel from a tokenised link sent with their confirmation, and staff work the diary in an admin area. Reservations that arrive by email from First Table are parsed and land on the same diary, so there is one list rather than two.
- →First-party booking flow with availability computed from the tables and areas in Postgres
- →Guests amend or cancel from a tokenised link, no account and no login
- →Staff diary in an admin area, with web and email reservations in one place
- →First Table reservations ingested from the restaurant mailbox onto the same diary
- →Contact page with map, address, phone and the opening hours that drive the structured data



- 01A PDF-only menu replaced by 42 dishes across nine sections as crawlable HTML, each with description, price, variant pricing and allergen labels
- 02Menu JSON-LD emitted per section and per dish, including prices, so the menu is machine-readable rather than a link to a download
- 03Client-side filters for vegetarian dishes, mild or no spice, and exclusion of any of eleven allergens, with no page reload
- 0428 blog posts migrated off WordPress with 25 redirect rules covering post URLs, category and author archives, per-post RSS feeds, date archives and the old menu PDF
- 05Restaurant JSON-LD carrying address, geo, opening hours and award, alongside per-page metadata, sitemap and robots
- 06Navy and gold rebrand taken from the printed menu, so the site and the room finally match
- 07Bookings taken on the site itself, with availability computed from the restaurant tables and a staff diary behind it, replacing the third-party reservation widget
- 08First Table reservations that arrive by email parsed and landed on the same diary as web bookings
- 09Photography and video served from Vercel Blob rather than committed to the repository
- Framework
- Next.js 16 with React 19, App Router and React Server Components
- Rendering
- Static generation for the marketing site, with the booking and admin routes dynamic
- Content
- Menu as typed JSON and blog posts as Markdown, both read at build time, no CMS
- Database
- PostgreSQL via Drizzle ORM for tables, areas, bookings and the staff diary
- Styling
- Tailwind CSS 4 with navy and gold brand tokens as CSS variables
- Deployment
- Vercel, with large media in a Vercel Blob store rather than git
- Structured Data
- Restaurant JSON-LD in the layout, Menu JSON-LD on the menu, Article on each post
- First Table
- Reservation emails polled from the restaurant mailbox over IMAP and parsed onto the diary
- Vercel Blob
- Photography and video served from a dedicated blob store, referenced through next/image
- Maps
- Google Maps link and embed on the contact page, matching the geo in the structured data
- Menu
- Rendered at build time from typed data, filtering happens in the browser with no server call
- Images
- next/image against the blob store, with the repository kept free of large media
- Fonts
- Marcellus and Figtree loaded through next/font, self-hosted and subset
- Redirects
- Handled at the edge by Next.js config rather than by a plugin or a htaccess file
- →TypeScript strict mode throughout
- →Menu data typed and read through a single loader, so a malformed dish fails the build
- →Vitest coverage over booking slot generation and booking API validation
- →Secrets in environment variables only, never in the repository
- →Semantic HTML for the menu, so the filter enhances a page that already works without it
- Next.js 16
- React 19
- TypeScript
- Tailwind CSS 4
- Drizzle ORM
- PostgreSQL
- Vercel Blob
- Vitest
- Vercel
Flora & Fable Floristry
Brand identity, bespoke e-commerce storefront, postcode delivery engine, and self-service admin dashboard for a Glasgow floristry business.

Have a project?
Web, software and brand work for businesses across the UK. Tell us what you are building.
Glasgow GFX Print Studio
- Visit
- The Pentagon Business Centre
Unit 204b, 36–38 Washington Street
Glasgow G3 8AZ - Call
- 0141 345 5841
- Hours
- Mon–Fri 9:00–18:00
Sat 10:00–18:00
Sun closed - Service area
- Glasgow, Hamilton, Paisley, East Kilbride, Motherwell. Free delivery across Central Scotland on orders over £50.