Skip to content

Option: give /ara/ a real Arabic 404 (message, header and footer) instead of redirecting to English - #724

Draft
fullcolorcoder wants to merge 4 commits into
stagefrom
ara-404-arabic-fallback
Draft

Option: give /ara/ a real Arabic 404 (message, header and footer) instead of redirecting to English#724
fullcolorcoder wants to merge 4 commits into
stagefrom
ara-404-arabic-fallback

Conversation

@fullcolorcoder

@fullcolorcoder fullcolorcoder commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

What's broken, in plain English

If someone follows a broken or mistyped /ara/ link, they get a completely blank page. No heading, no text, no header, no footer — 104 pixels of white.

Here's why, in one paragraph. Our 404 page doesn't contain the "Sorry, we couldn't find that page" message itself. It asks Milo for the message in the visitor's language, and Milo keeps those messages at /libs/<locale>/fragments/404. There is no Arabic one for ara/libs/ara/fragments/404 returns 404. So the 404 page asks for something that doesn't exist, gets nothing back, and renders empty.

The header and footer were empty for the same kind of reason: they're loaded from locale-prefixed paths that were never created for ara.

There are two ways to deal with that. This PR is the second one.

Option 1 — what's on stage right now (#722). Send /ara/ 404s to the English 404 page. The visitor gets a real, working page. It's in English, left-to-right. One line of code.

Option 2 — this PR. Show a real Arabic 404 page, with the Arabic site's own header and footer. Nothing new has to be authored and no other team is involved — every piece of content already exists, we were just pointing at the wrong paths.

Both are acceptable and it is genuinely fine to close this PR. Option 1 already solved the blank page, which was the urgent part. The only question this PR asks is: when an Arabic speaker hits a dead link on the Arabic site, should they land on an English page or an Arabic one?

Two things worth weighing:

What it does — two independent pieces

1. The message. Borrow Arabic 404 copy that already exists. Read the locale from the URL; if it isn't in a one-entry map ({ ara: 'mena_ar' }), stop immediately — no network request, no behavior change for any other locale. Otherwise ask (one HEAD) whether Milo has published this locale's own fragment yet. If yes, do nothing. If no, append a link to mena_ar's already-translated Arabic 404 and hand it to Milo's own loadArea.

2. The header and footer. Pre-set gnav-source and footer-source to the sources the live /ara/express/ homepage already resolves to, so the 404 page wears the same chrome as the rest of the Arabic site:

404 page was asking for Now uses
header /ara/express/localnav-express (scripts.js:532) 404 /ara/express/acom-gnav-thin 200 on branch, stage and prod
footer /ara/federal/footer/footer (scripts.js:507 + Milo decorateMeta()) 404 /ara/express/footer-thin 200 on stage; ships to prod with the launch

Set in a classic parse-time script so the metas exist before scripts.js (a deferred module) reaches its getMetadata(...) checks and fills in the broken defaults.

Why ara was missing all of this

ara is an Express-only locale prefix. It's registered in this repo's CONFIG.locales (scripts.js:94) but is absent from Milo's libs/utils/locales.js, and www.adobe.com/ara/ is itself a 404 while /ae_ar/ is 200 — adobe.com proper doesn't know the locale exists, so federal never created an ara bucket. Every gap follows from that.

It deletes itself

The HEAD probe is the important part. The day Milo publishes /libs/ara/fragments/404, the borrowed message stops being used — the probe succeeds and the code returns early. No stale workaround, no way to end up with two 404 messages, no revert ticket. Verified: with the probe stubbed to 200, zero mena_ar requests are made, and the header/footer fix keeps working independently.


Jira Ticket

N/A — no ticket filed. Context only: MWPW-204684 ([Arabic] New Language Setup) is where the /ara/ 404 behavior is specified.


Test URLs

Three-way comparison. All three are live and verified.

Env URL What you should see
Before (the original bug) https://main--da-express-milo--adobecom.aem.live/ara/express/does-not-exist-qa Blank page
Before (on stage now, #722) https://www.stage.adobe.com/ara/express/does-not-exist-qa Redirects to /express/...English, LTR
After (this PR) https://ara-404-arabic-fallback--da-express-milo--adobecom.aem.live/ara/express/does-not-exist-qa?martech=off Arabic 404, RTL, Adobe logo top-right, no redirect

Use .aem.live, not .aem.page. Preview (.aem.page) returns 401 Unauthorized for 404 paths, so it looks broken for reasons unrelated to this change. Publish (.aem.live) serves the 404 page anonymously with a correct 404 status.

Append a unique ?cb=<random> if you see stale content. The 404 page is CDN-cached per URL; a hard refresh alone is not always enough.


Verification Steps

1. The main test — Arabic 404 renders

Open the After URL.

  • You are not redirected. The address bar still reads /ara/express/does-not-exist-qa.
  • Heading reads نأسف، تعذر علينا العثور على تلك الصفحة. ("Sorry, we couldn't find that page.")
  • Below it, Arabic text linking to صفحة Adobe الرئيسية (the Adobe homepage).
  • Three cards, right-to-left: Acrobat, Photoshop, Adobe Express. Descriptions in Arabic, each with an image and an Arabic معرفة المزيد button.
  • Text flows right-to-left; card descriptions right-aligned.
  • DevTools → Elements: <html> has dir="rtl" and lang="ar".
  • DevTools → Network: mena_ar/fragments/404-body.plain.html200.

2. Header

  • A 64px bar at the top with the red Adobe logo on the right-hand side (correct for RTL).
  • Clicking the logo goes to /ara/.
  • DevTools: <meta name="gnav-source" content="/ara/express/acom-gnav-thin">, and no request to localnav-express.

This is the same thin gnav the /ara/express/ homepage shows — intentionally minimal and language-neutral, not the full English mega-nav.

3. Footer — must be checked on stage, not on the preview

/ara/express/footer-thin is published to stage only (/ara/ content hasn't shipped to prod yet, and isn't on .aem.live), so on the preview URL the footer area is empty. That's a publishing gap, not a code bug.

  • On the preview: <meta name="footer-source" content="/ara/express/footer-thin"> is set, and there is no request to /ara/federal/footer/footer.
  • Evidence the source renders: https://www.stage.adobe.com/ara/express/ — the live ara homepage uses this exact footer and renders it fully (20,692 chars, dir: rtl, Arabic legal links: الخصوصية / شروط الاستخدام / تفضيلات ملفات تعريف الارتباط).
  • After merge, re-check on www.stage.adobe.com/ara/express/does-not-exist-qa and confirm the Arabic footer renders there.

4. Regional Arabic locales now end on an Arabic page

https://ara-404-arabic-fallback--da-express-milo--adobecom.aem.live/sa_ar/express/does-not-exist-qa?martech=off&cb=1

5. No other locale changes — the important regression check

Behavior must be identical to main--da-express-milo--adobecom.aem.live:

  • /express/does-not-exist-qa — English, no redirect. Header 30,387 chars, footer 27,805 chars (measured identical with and without this PR).
  • /de/express/does-not-exist-qa → redirects to /express/does-not-exist-qa.
  • /il_he/express/does-not-exist-qa → redirects to /express/does-not-exist-qa (the other RTL locale).
  • /uk/…, /es/… → redirect to /express/….
  • /express/edu?locale=de → still lands on /education/express/.

On any non-ara URL, DevTools → Network must show no request to acom-gnav-thin, footer-thin, mena_ar, and no HEAD to fragments/404. All four confirmed absent.

6. Mobile

  • At 390px wide: no horizontal scroll, logo still top-right, cards stack, Arabic heading wraps cleanly.

7. Prove it retires itself (optional, ~30s)

Simulates Milo publishing the ara fragment. Run in the console, then reload with a fresh ?cb=:

const real = window.fetch.bind(window);
window.fetch = (i, o) => (String(i?.url || i).includes('/ara/fragments/404.plain.html')
  ? Promise.resolve(new Response('', { status: 200 }))
  : real(i, o));
  • Zero mena_ar requests — the borrowed message stands down.
  • The header still renders. The two pieces are independent.

Potential Regressions

The blast radius is one if in each of the two blocks: any locale that is not a key in the map returns before doing anything at all. Today the only key is ara. This file only ever serves 404 responses, so no real page can be affected.


Additional Notes

Dead end, documented so nobody repeats it. The obvious footer fix — borrow /mena_ar/federal/footer/footer, which is 200 everywhere — does not work. That document nests ~27 further fragments whose links get locale-prefixed to /ara/federal/footer/fragments/…, none of which exist, so it renders a footer with every column missing (11,299 chars, region selector only). Federal has no ara bucket, so no federal footer can work here. /ara/express/footer-thin is Express-owned and nests one #_dnt fragment that resolves correctly.

Why 404-body and not 404. fragments/404 is a thin wrapper that adds a background image and nests 404-body. Its nested link is authored absolute to www.adobe.com, which stageDomainsMap rewrites to origin on branch hosts — so the wrapper renders empty everywhere except stage/prod, making this impossible for QA to verify before merge. 404-body nests nothing and renders in every environment. Tradeoff: we lose the wrapper's decorative background gradient. (The English 404 hits this same limitation — its body is empty on preview hosts too, with or without this PR.)

Pre-existing issue QA will likely spot. The Arabic heading renders left-aligned on this RTL page, from 404.html's own stylesheet hardcoding .error-404 main { text-align: left } (an LTR assumption predating ara). Switching those two rules to text-align: start fixes it with no effect on LTR locales — left out to keep this diff focused. Happy to add.

Unrelated bug in this file. 404.html imports sampleRUM from /express/code/scripts/utils.js, which no longer exports it — every 404 page, every locale, throws Uncaught SyntaxError: … does not provide an export named 'sampleRUM'. It's also redundant; Milo's 404 template already calls sampleRUM('404', …). A four-line deletion, left out of this diff.

npm run lint:js passes. 404.html has no existing test coverage.

Milo's 404 template renders the fragment at `${miloLibs}/<locale>/fragments/404`.
Express registers locales Milo does not, so `/libs/ara/fragments/404` does not
exist and every `/ara/*` 404 rendered an empty <main>.

#722 mitigated the blank page by redirecting `/ara/` 404s to the English 404.
This replaces that with the locale-correct outcome: probe for the locale's own
Milo fragment and, when it is missing, borrow the already-translated pan-Arabic
fragment (`/libs/mena_ar/fragments/404`, live for the six MENA locales) and hand
it to Milo's loadArea.

Self-retiring: once Milo authors `/libs/ara/fragments/404` the probe succeeds and
this becomes a no-op. Non-ara locales short-circuit before any network request.
Two fixes from testing on a branch preview:

- loadArea() discovers sections via ':scope > div', so it must receive the
  container (main), not the appended section. Passing the section decorated
  nothing; earlier local passes only worked because Milo's own loadArea(main)
  happened to run afterwards. Also resolve loadArea before appending so no
  await sits between the append and the call.

- Borrow fragments/404-body instead of fragments/404. The wrapper nests a
  404-body link authored absolute to www.adobe.com, which stageDomainsMap
  rewrites to 'origin' on branch previews, leaving it empty outside
  stage/prod. 404-body nests nothing and renders in every environment, so QA
  can verify on the preview URL before merge.
@aem-code-sync

aem-code-sync Bot commented Aug 28, 2026

Copy link
Copy Markdown

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch and validate page speed.
In case there are problems, just click a checkbox below to rerun the respective action.

  • Re-run all PSI checks
  • Re-run failed PSI checks
  • Re-sync branch
Commits

@github-actions github-actions Bot added the Ready for Review Ready for peer review. label Aug 28, 2026
The 404 page rendered with an empty <header> (1041 chars of shell) and no
<footer> at all, because both sources resolve to locale-prefixed paths that
were never authored for ara:

  gnav   scripts.js:532 -> /ara/express/localnav-express        404
  footer scripts.js:507 -> /federal/footer/footer, which Milo's
         decorateMeta() locale-prefixes to /ara/federal/footer/footer  404

The content is not actually missing. Pre-set both metas in a parse-time script
so scripts.js's getMetadata() checks find them already populated:

  gnav   /express/acom-gnav-thin              same source the ara homepage uses
  footer /mena_ar/federal/footer/footer       how all six *_ar 404 pages resolve

Both are Arabic/RTL and return 200 on the federal origin, stage and prod, so
this is verifiable on a preview URL. gnav stays root-relative and footer
absolute on purpose: decorateMeta() only rewrites content matching .hlx./.aem./
/federal/, which the footer needs to reach the federal origin and the gnav must
avoid (localizeLink would turn /express/... into a non-existent /ara/express/...).
Testing on a branch preview showed the first attempt was wrong on both counts:

- footer: /mena_ar/federal/footer/footer nests ~27 further fragments whose links
  get locale-prefixed to /ara/federal/footer/fragments/..., none of which exist,
  so the footer rendered with every column missing (11299 chars, only the region
  selector). Federal has no ara bucket, so no federal footer can work here.
  /ara/express/footer-thin is Express-owned, nests one #_dnt fragment that
  resolves, and is what the live ara homepage uses (20692 chars rendered).

- gnav: /express/acom-gnav-thin rendered an empty 821-char header.
  /ara/express/acom-gnav-thin is what the homepage actually resolves to and is
  200 on the branch, stage and prod.

A control run ruled out the environment: the English 404 on the same branch host
renders a full 30387-char header and 27805-char footer, so preview hosts are not
the problem.
@fullcolorcoder fullcolorcoder changed the title Option: render a real Arabic 404 for /ara/ instead of redirecting to English Option: give /ara/ a real Arabic 404 (message, header and footer) instead of redirecting to English Aug 28, 2026
@hadobe hadobe added QA Approved and removed Ready for Review Ready for peer review. labels Aug 28, 2026
@nateyolles
nateyolles marked this pull request as draft August 28, 2026 21:30
@nateyolles

Copy link
Copy Markdown
Contributor

We need to discuss with PMs and SEO. We'll continue the conversation after release.

@nateyolles nateyolles added the Do Not Merge Use if business reason for not merging. label Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Merge Use if business reason for not merging. QA Approved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants