fix(web): decode \uXXXX escapes that were rendering as literal text
Some checks failed
CI / E2E Tests (push) Has been skipped
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 7s
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 45s
Deploy / Build API Image (push) Failing after 17s
Deploy / Build Web Image (push) Failing after 9s
Deploy / Build AI Services Image (push) Failing after 10s
E2E Tests / Playwright E2E (push) Failing after 9s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 3s
Security Scanning / Trivy Scan — API Image (push) Failing after 25s
Security Scanning / Trivy Scan — Web Image (push) Failing after 31s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 36s
Security Scanning / Trivy Filesystem Scan (push) Failing after 39s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Security Scanning / Security Gate (push) Failing after 1s
Deploy / Deploy to Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped

listing-detail-client.tsx had three more spots that wrote Unicode
escape sequences as JSX text or as JSX attribute strings (no braces),
which JSX does NOT decode — so "Di\u1ec7n t\u00edch" rendered as the
literal 18 characters instead of "Diện tích":

- QuickStat label="Di\u1ec7n t\u00edch"  → "Diện tích"
- QuickStat label="Ph\u00f2ng ng\u1ee7"  → "Phòng ngủ"
- >Thu\u00ea: {price}/th\u00e1ng<        → "Thuê: {price}/tháng"

Same class of bug as the previously-fixed breadcrumb. Audited the
rest of apps/web for `\u[0-9a-fA-F]{4}` — every remaining occurrence
is inside a JS string literal or template literal (escapes are
honoured there), so no further cases to fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ho Ngoc Hai
2026-04-19 14:24:20 +07:00
parent 185658bf5b
commit 98a84e9e3f

View File

@@ -117,7 +117,7 @@ export function ListingDetailClient({ listing }: ListingDetailClientProps) {
)}
{listing.rentPriceMonthly && (
<p className="text-sm text-muted-foreground">
Thu\u00ea: {formatPrice(listing.rentPriceMonthly)}/th\u00e1ng
Thuê: {formatPrice(listing.rentPriceMonthly)}/tháng
</p>
)}
<div className="mt-3">
@@ -131,9 +131,9 @@ export function ListingDetailClient({ listing }: ListingDetailClientProps) {
{/* Quick specs bar */}
<div className="my-6 flex flex-wrap gap-4 rounded-lg border bg-card p-4">
<QuickStat icon="area" label="Di\u1ec7n t\u00edch" value={`${property.areaM2} m\u00B2`} />
<QuickStat icon="area" label="Diện tích" value={`${property.areaM2} m²`} />
{property.bedrooms != null && (
<QuickStat icon="bed" label="Ph\u00f2ng ng\u1ee7" value={`${property.bedrooms}`} />
<QuickStat icon="bed" label="Phòng ngủ" value={`${property.bedrooms}`} />
)}
{property.bathrooms != null && (
<QuickStat icon="bath" label="Phòng tắm" value={`${property.bathrooms}`} />