﻿---
title: "Al Hatab Foods: a growing website, in the content team’s hands."
url: "https://lindemann.design/work/alhatab-site/"
description: "A bilingual Craft CMS platform for Al Hatab Foods, with flexible page editing, product discovery, a custom store locator and content for the mobile app."
---

# Al Hatab Foods: a growing website, _in the content team’s hands._

Al Hatab Foods needs to keep product information, store details and brand content useful in Arabic and English. We designed and built a Craft CMS platform that lets the team assemble pages, maintain the catalogue and publish content for the website and mobile app from one place.

-   [Visit website](https://alhatab.com.sa/)

Website and CMS

-   ![English product catalogue with a search field, sorting, allergen and product-attribute filters above a product grid.](/_astro/product-catalogue.BVk-ACec_2uvPVa.png)
    
    Search, sorting and allergen and product-attribute filters help customers explore the catalogue.
    
-   ![Fish Sayadieh product page with ingredients and nutrition expanded beside the product image, and a persistent Order Now bar.](/_astro/product-details.BUUnMrha_26RauL.png)
    
    Ingredients and nutrition sit beside the product, with a persistent route to ordering.
    
-   ![Search results for breadsticks with relevance sorting, a product-attribute filter and seven matching products.](/_astro/search-results.rCQrPjHK_1jH09I.png)
    
    Search results retain sorting and product filters so customers can refine what they find.
    
-   ![Al Hatab branch finder with search, distance sorting, store cards and a selected branch on a map.](/_astro/store-locator.C1npYQxF_Zmb7nX.png)
    
    Branch cards and the map connect location, opening status and distance with calls and directions.
    
-   ![Arabic feedback page for olive crackers with the product image and star-rating questions for taste and quality.](/_astro/product-feedback-arabic.BCNxec7i_2m3McI.png)
    
    Product-specific feedback pairs the item with Arabic rating questions about taste and quality.
    
-   ![Al Hatab-branded HungerStation landing page with App Store, Google Play, AppGallery, website and QR-code options.](/_astro/ordering-link.CM8ytcHd_Z1DXd3Q.png)
    
    A branded ordering-partner page offers app-store links, a website destination and a QR code.
    
-   ![Craft product editor for Vietnamese-style prawn and rice noodle salad, with content fields and tabs for ingredients, nutrition, badges, gallery and SAP data.](/_astro/product-editor.DhAFS7Ih_ZGdToP.png)
    
    Editors manage product content in Craft, with dedicated tabs for nutrition, badges, imagery and SAP data.
    
-   ![Search Manager analytics showing total searches, searches with hits, zero-hit searches and a trend chart for the selected 30-day period.](/_astro/search-analytics.DfQ3K_Y5_ZAFBQh.png)
    
    Search analytics separates queries with results from those without, helping the team inspect gaps in discovery.
    
-   ![Craft Category Manager utility showing rebuild progress, cached product references, storage and cache-coverage charts.](/_astro/category-cache.BypHA0RY_1VCDEN.png)
    
    Category Manager makes cache coverage, rebuild progress and storage visible inside Craft.
    
-   ![Craft Store Manager utility showing Google Places data coverage, cached distance calculations, regions and store-distribution charts.](/_astro/store-cache.C5kxqSFT_2mSXuk.png)
    
    Store Manager exposes location-data coverage and cached distance calculations behind the branch finder.
    

Organisation

Al Hatab Foods, Saudi Arabia

Role

Design, architecture and engineering

Stack

-   Craft CMS 5 Pro
-   PHP, Twig, MySQL, Redis
-   Vite, Tailwind CSS
-   TypeScript, Alpine.js
-   Servd, Cloudflare

Status

In production

Since

2024 to present

1.  **Publish** build pages from reusable content blocks
2.  **Discover** explore products and find a nearby store
3.  **Share** manage website and app content in one CMS

The brief

## Give the team room to keep the site useful.

A food catalogue, a growing store network and regular campaigns need frequent updates. We built the site around those everyday jobs: creating pages, maintaining product details, helping customers find a branch and collecting feedback. Arabic and English run through the same content structure, with layouts that work in both reading directions.

Page editing

## Build a page from familiar pieces.

Editors combine reusable blocks for copy, images, products, categories, forms, slideshows and other content. They can adjust layout and presentation within the component system, so a new campaign page can use existing pieces. The templates cache suitable blocks separately for each language, while previews and forms remain fresh.

content builder · reusable blocks

```text
Copy rich editorial text
Accordion FAQs, expandable information
Leadership team profiles
Slideshow promotional slides
Social Media Embed embedded social content
Video video sections
Gallery image collections
Products curated product selections
Categories category cards and navigation
Product Categories category showcases
CTA Cards calls to action
Icon Cards features, benefits, highlights
Brands brand and logo collections
One Column flexible single column
Two Column split content and media
Allergen Table structured allergen information
Statistics company figures
Timeline history and milestones
Testimonials quotations
Form embedded forms
Error reusable error messaging
 
each block carries its own width, alignment, spacing, background, heading and card controls
```

Product discovery

## Help people find the details they need.

Product entries bring together images, ingredients, nutrition, allergens, cooking instructions and storage guidance. Reusable categories and badges keep those details consistent across the catalogue. Search and filters help visitors narrow the selection by category, product attributes or allergens they want to exclude.

Desktop filters and the mobile filter dialog use the same choices. Those choices stay in the URL, so a filtered view can be shared or revisited. Search Manager supplies search and autocomplete, while a custom integration prepares the content for indexing.

a product entry

```text
identity name, code, category and subcategory, gallery
measures sizes, units, serving size
composition description, ingredients, allergens
nutrition editable facts table, traffic-light display from nutrient values
preparation cooking methods, storage and handling
badges health claims, features, protein sources, quality seals, serving experiences
presentation card and detail-page options, CTA controls, sticky product bar
routing short product URL to the canonical page
 
"favourites" is an editorial collection chosen by the team, not a customer wishlist
```

product discovery

```text
◆ query Arabic or English, with autocomplete
│ fuzzy matching and wildcards through Search Manager
│ 
◇ indexes products, categories, stores, combined
│ a custom transformer assembles the searchable text
│ 
◇ filters category, allergen, health badge, attribute
│ allergen exclusion: products without
│ 
◇ counts products and per-filter counts
│ from the category cache, not live queries
│ 
├─ desktop sticky search and filter area
└─ mobile a filter dialog kept in sync with it
 
 filters validated server-side; state carried in the URL; AJAX endpoints for results and counts
```

Store locations

## Find a branch, then know how to get there.

Customers can browse a map or store cards, check opening hours and get directions. Location-based sorting helps them find nearby branches; Riyadh provides a starting point when location is unavailable. Stores load progressively so the initial list can appear before the full network.

A custom Craft module brings in Google Places details in both languages. Editors can keep their own names and hours without losing them during a refresh. Scheduled updates and cached distances reduce the repeated work needed to keep the locator useful.

store locator · for customers

```text
map branded markers, clustering, info windows, store cards
types Fresh, To Go, Market
open now filter and status, from hours
details address, phone, hours, rating and reviews, directions
near me use my location; nearest first; metres or kilometres
fallback Riyadh, when location is unavailable or outside the region
loading progressive: the first stores, then the rest
```

store locator · for the team

```text
◇ a new store Google Places fetches its data
│ Arabic and English, automatically for eligible stores
│ 
◇ overrides custom name and hours
│ synchronised fields stay protected
│ 
◇ validation duplicate Place IDs rejected
│ separate timestamp for the last Google update
│ 
◆ distances store-to-city distances, precomputed
│ one store edited: 14 distances, not all; bulk imports detected
│ 
├─ refreshes scheduled, in the background
└─ utilities cache status, rebuild, import commands
 
 update one store’s cached distances when its details change
```

Keeping pages responsive

## Prepare repeated information once.

Catalogue pages repeatedly need the same product counts and filter options. A custom cache module prepares that information ahead of time, including category totals, allergen exclusions and available attributes. Queued jobs rebuild it, and a Craft utility shows coverage and refresh status. Templates read the prepared data instead of recalculating those counts for every visitor.

category cache

```text
precomputes filter data per category: product and subcategory counts, allergen-free counts, badges, attributes
rebuilds full, or one category; scheduled; queued in batches with progress
stores JSON on Servd's CDN with database tracking; local fallback
exposes a Twig API for templates, a Control Panel utility for status, coverage and the scheduler
 
its purpose is to remove repeated database work from catalogue and filter pages
```

Customer feedback

## Keep the product beside the question.

A feedback link can identify a product by its code or barcode and show it beside the form. Arabic and English versions share the same journey. Star, emoji and recommendation ratings give the team different ways to ask for feedback, while configured form integrations send submissions into its existing tools.

a feedback journey

```text
◆ arrive from a QR on the packaging, a receipt or a link
│ language from the URL
│ 
◇ product looked up by code or barcode
│ shown with its image beside the form; works for retired products too
│ 
◇ context invoice, store and member references from the URL
│ store code resolved to its Google Place
│ 
◇ rate stars, emoji or a 0 to 10 score
│ through the family's Formie fields
│ 
├─ delivered to the team's sheet
└─ excluded from search engines
```

Content for the app

## One editing environment, more than one screen.

The same Craft installation includes Arabic and English mobile sites, with content models for app banners, onboarding, navigation and other screens. A private GraphQL schema exposes the content the app needs alongside shared products and stores. WebView layouts support pages opened inside the app; building the app itself is a separate project.

mobile CMS and API backend

```text
sites mobile_en, mobile_ar
builder a dedicated mobile content builder
models hero, banner, category, product, onboarding, splash
settings homepage, navigation, a configurable More menu, access gates
api a private GraphQL schema for mobile content and assets
shared products, categories, stores and news, the same entries as the website
 
the app itself is a separate piece of work; this is its content and API backend
```

Shared tools

## Connect the tools around the team’s work.

Our plugins support search, translations, links, forms, icons and logging inside Craft. The custom work connects those tools to Al Hatab’s content and customer journeys, giving the team a coherent editing environment. The individual plugin pages explain those products in more detail.

-   [Search Manager](/work/search-manager/)search and autocomplete behind product discovery
-   [Translation Manager](/work/translation-manager/)the bilingual interface and form translation workflow
-   Icon Managerbranded icons, product badges and editor icon selection
-   Component Managerrendering of the reusable component library
-   [SmartLink Manager](/work/smartlink-manager/)device-aware links, app routing and QR journeys
-   [ShortLink Manager](/work/shortlink-manager/)campaign links, QR codes and expiry
-   [Redirect Manager](/work/redirect-manager/)redirects and broken-URL handling
-   [Formie Rating Field](/work/formie-rating-field/)star, emoji and NPS inputs in feedback forms
-   Formie Paragraph Fieldexplanatory copy inside forms
-   Formie REST APIauthenticated access to form data
-   Formie SAP Integrationsubmissions into the client's SAP
-   [Logging Library](/work/logging-library/)one diagnostics viewer across the custom work

Delivery

## Make ongoing changes easier to manage.

Development, staging and production use separate build settings. Version-controlled Craft configuration keeps content structure changes reviewable, and automated releases record the work being delivered. Image optimisation, language-aware caching and CDN delivery support the frontend, while metadata, canonical links and language references help search engines understand it.

release-please

```text
version 1.142.1
releases 295, from conventional commits
builds dev · stage · prod, from one Vite config
environments DDEV locally; Servd and Cloudflare in production
```