Section 1
01
Score Dashboard
| Area | Score | Bar | Key Finding |
|---|---|---|---|
| Business & Content | 68 | Strong listing platform; analytics meta entity bug | |
| UI / UX | 62 | Clean design; cookie consent banner; language switching | |
| Accessibility | 45 | Partial ARIA detected; full WCAG audit needed | |
| Performance | 35 | No CDN; no cache headers; external Alpine.js CDN | |
| SEO | 58 | Good schema; hreflang; 302 redirect; entity encoding bug | |
| Security | 45 | X-Frame-Options present; missing HSTS, CSP, Permissions-Policy | |
| Privacy / Legal | 30 | Banner cosmetic — GTM/GA4/LinkedIn fire before consent | |
| Code Quality | 50 | Clean custom app; HTML entity bug; CSRF token in meta | |
| CI / CD / Deployment | 30 | Heroku only; no CDN; no caching |
Section 2
02
Category Findings
A
Business & Content
68/100
Platform
Custom commercial property marketplace (Laravel/PHP). Covers office, retail, and industrial across UAE with rent/buy filters. Arabic (/ar) and English (/en) full versions.
Credentials
Cushman & Wakefield global brand: 52,000 team members, 60 countries. Strong brand authority communicated clearly.
Services
Global Occupier Services, Project & Development, Valuation & Advisory alongside property listings. Multi-market (UAE, Egypt, Global).
Meta Bug
og:title and twitter:title contain `&` double-encoded entity — social shares display broken ampersand text.
Not Tested
Content accuracy, property data freshness, lead capture flow, CMS workflow.
B
UI / UX
62/100
Framework
Alpine.js 3.12.0 for interactivity. lazysizes.js for image lazy loading. Custom CSS with Bootstrap patterns.
Cookie Consent
Custom banner with Essential, Non-Essential, and Marketing categories. Accept All / Reject All / Save Settings options available.
Language / Region
UAE, Egypt, Global market selector. EN / AR language toggle. Functional and present.
Redirect UX
Root / returns 302 to /en — functionally correct but semantically wrong (should be 301 permanent).
C
Accessibility (WCAG 2.2 AA first-pass)
45/100
HTML lang="en" on root elementPass
RTL dir="rtl" on /ar pathPass
Skip navigation linkPartial — referenced; visual verification needed
ARIA navigation controlsPartial — Open/Close labels referenced
Image alt textNot Tested
Colour contrast (WCAG 1.4.3)Not Tested
Keyboard navigationNot Tested
Property search form labelsNot Tested
Cookie consent banner accessibilityNot Tested
D
Performance
35/100
HTTPS enforced (HTTP 301 → HTTPS)Pass
CDN deployedFail — Heroku only; no edge CDN
Cache-Control headersFail — no-cache, private on all responses
lazysizes.js lazy loadingPass
Alpine.js from external CDN (jsdelivr.net)Fail — external dependency
Font loading (preload + stylesheet)Pass — correct approach
Core Web VitalsNot Tested
Image optimisation (WebP, srcset)Not Tested
E
SEO
58/100
robots.txt presentPass — allows all; references sitemap.xml
Sitemap index with 25 child sitemapsPass — rich coverage of property types and locations
Canonical tag (/en)Pass
hreflang en-ae, ar-ae, x-defaultPass — all three present
Organization + RealEstateAgent schemaPass
Meta description (93 chars)Pass
OG / Twitter title entity encodingFail — & double-encoded in all three meta fields
Root redirect (/ → /en)Fail — 302 not 301; link equity not passed
keywords meta tagWarning — low SEO value; remove
RealEstateListing schema on property pagesMissing — not implemented
F
Security
45/100
HTTPS enforcedPass
X-Frame-Options: SAMEORIGINPass
X-Content-Type-Options: nosniffPass
Referrer-PolicyWeak — no-referrer-when-downgrade (should be strict-origin-when-cross-origin)
Strict-Transport-Security (HSTS)Fail — absent
Content-Security-PolicyFail — absent
Permissions-PolicyFail — absent
Server header disclosureWarning — server: Heroku disclosed
CSRF meta token (Laravel pattern)Note — standard; verify SameSite cookie attribute
robots.txt /admin, /api disallowMissing — no sensitive path blocking
G
Privacy, Legal & Compliance
30/100
Critical: Tracking fires before consent
GTM, GA4, and LinkedIn Insight all load unconditionally in <head> before any consent signal. The cookie banner is decorative — no consent mode gating is configured. This is a GDPR violation.
Cookie consent banner (3 categories)Pass — UI present
Accept All / Reject All / Save SettingsPass — granular controls
Privacy Policy pagePass — footer linked
Cookie Policy pagePass — footer linked
Google Consent Mode v2Fail — not implemented
GTM fires before consentCritical Fail — GTM-PFM7JDRD loads unconditionally
GA4 fires before consentCritical Fail — G-Z69JWE7CRD loads unconditionally
LinkedIn Insight fires before consentCritical Fail — partner_id 8880001 loads unconditionally
H
Code Quality
50/100
Custom application (not WordPress)Pass — clean Laravel-pattern app
Alpine.js 3.12.0 (current)Pass
HTML entity encoding in meta tagsFail — &amp; double-encoded in 3 meta fields
CSRF token in meta (Laravel standard)Note — standard; verify SameSite cookies
Alpine.js from external CDNWarning — no SRI hash; external dependency
Font loading strategyPass — preload + stylesheet correct
lazysizes.js SRI hashMissing — no integrity attribute
I
CI / CD / Deployment
30/100
HTTPS enforcedPass
CDN deployedFail — Heroku origin only
Cache strategyFail — no-cache, private on all responses
Source repositoryNot Found publicly
CI/CD pipelineNot Testable
Staging environmentNot Tested
Uptime monitoringNot Tested
Section 3
03
Full Issue Register
CriticalP0 — Fix This Week2 issues
PRIV-001
GTM, GA4, LinkedIn Insight fire before cookie consent
CriticalP0Medium
Evidence
GTM-PFM7JDRD, G-Z69JWE7CRD, LinkedIn _linkedin_partner_id=8880001 all in <head> before any consent signal
Impact
Direct GDPR violation; ICO enforcement risk; analytics data from non-consenting users is invalid
Fix
Implement Google Consent Mode v2. Set all categories denied by default. Move GTM inside consent callback. Gate LinkedIn Insight similarly.
Owner / Effort
Developer · Medium
Verify
Network tab shows zero GA/GTM requests before user accepts consent banner
PERF-001
No CDN — all traffic served from single Heroku origin
CriticalP0Medium
Evidence
server: Heroku; no CDN cache headers; cache-control: no-cache, private on all responses
Impact
High latency for GCC visitors; single point of failure; no DDoS protection
Fix
Add Cloudflare free tier as reverse proxy in front of Heroku. Configure cache rules for static assets.
Owner / Effort
DevOps · Medium
Verify
Response headers show cf-ray or CDN server; latency from UAE reduced
HighP1 — Before Next Release8 issues
SEO-001
Root redirect is 302 not 301
HighP1Quick Win
Evidence
curl -sI https://www.cushwake.ae/ returns 302 Found to /en
Fix
Change redirect to 301 Moved Permanently in application router
Owner
Developer · Quick Win
SEO-002
HTML entity double-encoding in OG, meta, and Twitter titles
HighP1Quick Win
Evidence
og:title = "Find Commercial Properties in UAE | Cushman &amp; Wakefield" — & double-encoded
Fix
Fix template escaping in view file. Output raw & — let HTML parser encode once.
Owner
Developer · Quick Win
SEC-001
No HSTS header
HighP1Quick Win
Fix
Strict-Transport-Security: max-age=31536000; includeSubDomains via Heroku config or Cloudflare
Owner
DevOps · Quick Win
SEC-002
No Content-Security-Policy header
HighP1Small
Fix
Deploy CSP in report-only mode via Cloudflare or Heroku. Review violations; progressively enforce.
Owner
DevOps · Small
SEC-003
No Permissions-Policy header
HighP1Quick Win
Fix
Permissions-Policy: camera=(), microphone=(), geolocation=() via response headers
Owner
DevOps · Quick Win
SEC-004
Referrer-Policy too permissive
HighP1Quick Win
Evidence
referrer-policy: no-referrer-when-downgrade — sends full URL including search parameters to third parties
Fix
Change to strict-origin-when-cross-origin
Owner
DevOps · Quick Win
PERF-002
No Cache-Control headers on page responses
HighP1Small
Evidence
cache-control: no-cache, private on HTML responses
Fix
Configure Cloudflare cache rules: HTML 1–5 min, CSS/JS/images 30 days
Owner
DevOps · Small
ACC-001
Full accessibility audit not performed — WCAG compliance unknown
HighP1Medium
Fix
Commission WCAG 2.2 AA audit using axe DevTools, NVDA/VoiceOver testing, and colour contrast analysis
Owner
Developer / Designer · Medium
MediumP2 — Next Development Cycle7 issues
SEO-003
Keywords meta tag present (low SEO value)
MediumP2Quick Win
Fix
Remove or reduce to essential terms only
SEO-004
No structured data for property listings
MediumP2Medium
Fix
Add schema.org/RealEstateListing markup to property detail pages; eligible for Google rich results
Owner
Developer / SEO · Medium
PERF-003
Alpine.js loaded from external CDN (no SRI hash)
MediumP2Small
Fix
Self-host Alpine.js and Alpine Intersect; add SRI integrity attribute to script tags
Owner
Developer · Small
COD-001
server: Heroku header discloses platform
MediumP2Quick Win
Fix
Suppress server header via Cloudflare Transform Rule or Heroku config
COD-002
CSRF meta token — verify SameSite cookie attribute
MediumP2Small
Fix
Confirm session cookie uses SameSite=Strict or Lax; verify token rotates per session
PRIV-002
Cookie banner does not block tracking (cosmetic)
MediumP2Medium
Fix
Resolved by implementing PRIV-001 (Consent Mode v2)
CI-001
No CDN / edge caching layer (infrastructure)
MediumP2Medium
Fix
Resolved by PERF-001 (Cloudflare deployment)
LowP3 — Backlog4 issues
SEC-005
robots.txt has no Disallow rules for /admin, /api
LowP3Quick Win
Fix
Add Disallow: /admin/ and /api/ to robots.txt
PERF-004
Large sitemap index (25 child sitemaps)
LowP3Small
Fix
Monitor coverage in Google Search Console; consolidate if crawl budget limited
UX-001
Region/market selector not prominently surfaced
LowP3Small
Fix
Ensure UAE/Egypt/Global + EN/AR selector visible above fold on all viewport sizes
COD-003
lazysizes.js loaded without SRI integrity hash
LowP3Quick Win
Fix
Add integrity="sha384-..." attribute to lazysizes script tag
Section 4
04
Implementation Roadmap
| Phase | Focus | Issues | Effort | Timeline | Owner |
|---|---|---|---|---|---|
| Phase 1 | Privacy & Infrastructure Consent mode v2, Cloudflare CDN, cache rules | PRIV-001, PERF-001, PERF-002 | 1 week | Week 1 | Developer + DevOps |
| Phase 2 | Security Headers & SEO HSTS, CSP, entity fix, 301 redirect | SEC-001–004, SEO-001–002 | 3–5 days | Weeks 2–3 | DevOps + Developer |
| Phase 3 | Accessibility & Code Quality WCAG audit, property schema, self-host Alpine.js | ACC-001, SEO-003–004, PERF-003, COD-001–003 | 5–8 days | Weeks 4–6 | Developer + Designer |
| Phase 4 | Monitoring & Optimisation GSC coverage, UX improvements, uptime monitoring | PERF-004, UX-001, CI-001 | Ongoing | Weeks 7–10 | SEO + DevOps |
Section 5
05
Audit Tools & Commands
HTTP Redirect Chain
curl -sI http://www.cushwake.ae/
Redirect chain from HTTP
HTTPS Headers
curl -sI https://www.cushwake.ae/
HTTPS redirect, response headers
Security Headers
curl -sv https://www.cushwake.ae/en
Full response headers including security
HTML Source
curl -sL https://www.cushwake.ae/en
Full page source for meta, schema, analytics
robots.txt
WebFetch /robots.txt
Crawl directives and sitemap reference
Sitemap Index
WebFetch /sitemap.xml
Sitemap structure — 25 child sitemaps
Page Content
WebFetch /en
Cookie consent, footer, ARIA, nav
English Sitemap
WebFetch /sitemap-en.xml
English sitemap child file list
Section 6
06
Items Not Tested
The following were identified as in-scope but require browser testing, authenticated access, or specialist tooling not available in a Level-1 audit.
- Lighthouse / PageSpeed Insights CWV scores
- LCP, CLS, INP measurements
- Mobile responsiveness across viewports
- Colour contrast ratios (WCAG 1.4.3)
- Keyboard navigation walkthrough
- Screen reader testing (NVDA, VoiceOver)
- Property search and filter flow
- Property listing detail pages
- Lead capture / enquiry form submission
- Arabic page full audit (/ar)
- 404 and error pages
- SSL certificate expiry date
- Session cookie SameSite attribute
- Dependency audit (npm, composer)
- Cookie banner blocking verification
- GSC Core Web Vitals report
- Heroku dyno scaling configuration
- Data retention policies