Skip to content

feat(footer): render the global footer from the shared web component - #196

Open
ch264 wants to merge 2 commits into
global-navbar-shared-componentfrom
global-footer-shared-component
Open

feat(footer): render the global footer from the shared web component#196
ch264 wants to merge 2 commits into
global-navbar-shared-componentfrom
global-footer-shared-component

Conversation

@ch264

@ch264 ch264 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #195 (navbar), so the diff below is templates/footer.hbs only. #195 adds the bundle that registers this element — merge it first.

Replaces ~360 lines of hand-inlined markup that duplicated the marketing site's footer with the shared <postman-footer> from postman-eng/marketing-global-navbar-footer.

Client-mounted, unlike the navbar

There is no prerendered fragment here. The footer is below the fold and not LCP-critical, so the element reserves height via --pm-footer-min-height and fills in on mount.

That reserve is partial, not exact — an earlier draft of this description claimed "no layout shift", which measurement doesn't support. The component's default reserve is 320px, while the mounted footer is ~647px on desktop and ~1348px on mobile, so mount grows the page. Because it's below the fold this costs scroll position rather than CLS on the initial view.

Not a regression from this PR or from the version bump: the same 320px default under-reserved at 1.0.6 too, by more (682 / 1517px). Left unfixed here on purpose — a per-consumer override bakes in a number that goes stale on the next parity change, and every consumer would pick their own. It belongs in the component's default. If support needs it solved sooner, the note in footer.hbs says what to do (override behind a media query, not one value for both breakpoints).

It needs no script of its own: the bundle that hydrates the navbar in templates/document_head.hbs registers both elements.

No host attribute — it falls back to location.origin, and support.postman.com is not www-family, so internal links resolve absolute to https://www.postman.com/….

emit-jsonld stays on (the default). Unlike the docs site, this help center has no competing SiteNavigationElement data of its own, so letting the component emit it is a net gain rather than a duplicate.

language-switcher stays off (also the default) — see below.

Carried over: Do Not Sell / Share

Projected into the component's privacy slot, unchanged — same handleDoNotSellClick, same viewState: 'DoNotSellExplainer', same Transcend guard.

That guard is not decorative. script.js injects airgap.js async (gated on the TR param), so a fast click can beat window.transcend into existence; the console.warn path is what the previous footer did too. Behaviour is identical.

Deliberately not carried over

The Privacy Policy link and the copyright line. The shared footer renders both, to the same privacy.postman.com/policies/ target, and computes the year itself — which also retires the DOMContentLoaded script that patched #current-year. Worth noting the old markup had it hardcoded to 2024, so this is a fix, not just a move.

Destination diff

Walked the real data structures rather than grepping for href — the shared footer's links are objects resolved through resolveHref, and social links use a flat url, so a regex under-reports. 49 destinations vs 53 today.

Mostly this help center's copy was stale and the shared footer is what www.postman.com serves now:

Renamed case-studiescustomer-stories · trustsecurity · product/what-is-postmanproduct · youtube.com/c/Postmanyoutube.com/postman
New product/agent-mode · product/api-catalog · events · outbound buildwithfern.com
Dropped, no equivalent product/governance · product/postbot · product/tools · student-program · templates

Those five dropped links are the ones worth a support opinion — they're gone because www's own footer no longer lists them, but if support traffic depends on any of them, say so and they can be added to the shared footer for every property rather than re-inlined here. The new outbound buildwithfern.com link is also worth a look if third-party links in the footer are a concern.

One cosmetic inconsistency inherited from the shared data: explore/mcp-servers has no trailing slash while this footer used explore/mcp-servers/. It redirects; I'd rather fix it upstream than diverge here.

Re-checked against 3.0.0 and the table above is unchanged — still 49 destinations, same five columns, every rename / addition / drop still exactly as listed, mcp-servers trailing slash included.

Pinned version

Inherits 3.0.0 from #195. The follow-up this section used to describe — "bump to 1.0.8 once tagged" — is done and then some; see #195 for what's in the range and for the one breakpoint change that affects the theme.

Two things in that range touch the footer specifically:

Labels changed, targets didn't. 2.0.0 split the visible label from the JSON-LD name, so the footer now reads "App Security" / "About" / "Academy" where it read "App Security APIs" / "About Postman" / "Postman Academy" — matching what www.postman.com renders. The longer SEO names survive in the emitted SiteNavigationElement. (The old long labels were also an EN-only bug: Japanese read the translation bundle and already rendered the short form, so the two locales disagreed about what the footer said.)

A built-in language switcher exists now, and this PR leaves it off. It's opt-in, so saying nothing already gives the right behaviour — but "never considered" and "considered and declined" look identical in a diff, so: its options resolve to the locale's site root on a foreign host, not to a translation of the current page. On a support page that control would read as a page-language toggle and actually be an exit to www.postman.com/jp/. Worth turning on only alongside a decision about localized /hc/ URLs.

Verified against the live 3.0.0 bundle

Headless Chromium, templates rendered the way Zendesk would: mounts with all five columns and 50 anchors (the 49 destinations above plus the logo's link home), the Do Not Sell button is assigned to the privacy slot and visible, JSON-LD emitted exactly once, copyright computes 2026, no language switcher rendered, no page errors at 1440 / 1180 / 390px.

How to test this PR with an AI prompt

Paste this into Claude Code at the repo root:

Check out this branch and start the theme preview with npm run dev (needs ZAT; see README), then start local preview at https://<subdomain>/hc/admin/local_preview/start. Verify: (1) the footer renders at the bottom of a help center article with all its link columns; (2) measure the mount jump — reload with DevTools network throttling and record how far the page grows when the footer fills in; expect roughly 320px reserved against ~647px desktop / ~1348px mobile actual, and confirm that below-the-fold growth is acceptable rather than a visible jump on the first screen; (3) every internal link points at absolute https://www.postman.com/…, not a support.postman.com path; (4) the "Do Not Sell or Share My Personal Information" button opens the Transcend consent manager, and if you block transcend-cdn.com in the Network tab it logs a warning instead of throwing; (5) the copyright line shows the current year, not 2024; (6) exactly one Privacy Policy link is present, not two; (7) document.querySelectorAll('script[type="application/ld+json"]') contains one SiteNavigationElement block and the page has no other one competing with it; (8) no language switcher control appears in the footer. Report anything that fails with the console output.

Open question

Same as #195: does this help center serve translated content? If it's English-only in practice, both elements want translate="false". The footer renders English today either way, since locale is unset and no /hc/en-us/ path parses as a locale prefix — so this is a declaration to make, not a bug to fix.

ch264 and others added 2 commits August 27, 2026 18:06
Replaces ~360 lines of hand-inlined markup that duplicated the marketing site's
footer with <postman-footer> from postman-eng/marketing-global-navbar-footer.
Split out of the combined navbar+footer change so each lands as its own
reviewable PR, matching how www-next and the Learning Center adopted them.

CLIENT-MOUNTED, unlike the navbar. The footer is below the fold and not
LCP-critical, so there is no prerendered fragment to inline: the element
reserves its own height via --pm-footer-min-height and fills in on mount, so
there is no layout shift. It needs no script of its own — the same bundle that
hydrates the navbar (templates/document_head.hbs) registers both elements.

No `host` attribute: it falls back to location.origin, and support.postman.com
is not www-family, so internal links resolve absolute to www.postman.com.

emit-jsonld stays ON (the default). Unlike the docs site, the support center has
no competing SiteNavigationElement data of its own, so letting the component
emit it is a net gain rather than a duplicate.

CARRIED OVER: the Do Not Sell / Share button, projected into the component's
`privacy` slot, unchanged including its Transcend guard. That guard is not
decorative — script.js loads airgap.js async, so a fast click can beat
window.transcend into existence, and the warn path is what the previous footer
did too.

DELIBERATELY NOT CARRIED OVER: the Privacy Policy link and the copyright line.
The shared footer renders both, to the same privacy.postman.com/policies/
target, and computes the year itself — which also retires the DOMContentLoaded
script that patched #current-year, since the markup had it hardcoded to 2024.

Destination diff, walking the real data structures rather than grepping (49
links in the shared footer vs 53 here): mostly this center's copy was stale and
the shared footer is what www.postman.com serves today. Renames — case-studies
-> customer-stories, trust -> security, product/what-is-postman -> product,
youtube.com/c/Postman -> youtube.com/postman. New — product/agent-mode,
product/api-catalog, events, and an outbound buildwithfern.com. Dropped with no
equivalent — product/governance, product/postbot, product/tools,
student-program, templates. Those five are the ones worth a support opinion; the
rest are the shared footer being current.

Co-Authored-By: Claude <noreply@anthropic.com>
No markup change: the element, the `privacy` slot, and emit-jsonld all carry
across 1.0.6 -> 3.0.0 untouched, and the bundle pin lives in document_head.hbs
one commit down. Two things the bump makes true are worth writing down where
the next reader will look.

LANGUAGE SWITCHER, deliberately off. v2.0.0 added a built-in English/日本語
control. It is opt-in, so this file already gets the right behaviour by saying
nothing — but "we never considered it" and "we considered it and said no" read
identically in a diff, and this is the second one. Its options resolve to the
locale's SITE ROOT on a foreign host, not to a translation of the current page
(footer-data.js: `path` is the fallback; _languageHref only does better on the
www family). So on a support page it would look like a page-language toggle and
actually be an exit to www.postman.com/jp/.

RESERVED HEIGHT, corrected. The comment claimed "no layout shift". Measured:
the component reserves 320px by default and mounts to ~647px desktop /
~1348px mobile, so it grows the page. This is not a regression — 1.0.6 was
worse (682/1517px against the same 320px) — and the footer is below the fold,
so the cost is scroll position rather than CLS on the first view. Left
unfixed here on purpose: a per-consumer override picks a number that goes stale
on the next parity change, and every consumer would pick their own. It belongs
in the component's default. Noted in the file with what to do if support needs
it solved sooner.

The destination diff in the previous commit still holds at 3.0.0 — 49 links,
same five columns, no additions or removals since 1.0.6. What did change is
labels, not targets: v2.0.0 split the visible label from the JSON-LD name, so
the footer now reads "App Security" / "About" / "Academy" where it read "App
Security APIs" / "About Postman" / "Postman Academy", matching what
www.postman.com renders. The SEO names survive in the emitted
SiteNavigationElement.

Verified in headless Chromium against the real 3.0.0 bundle: mounts with all
five columns and 50 links, the Do Not Sell button is assigned to the `privacy`
slot and visible, JSON-LD is emitted exactly once, the copyright computes 2026,
and no language switcher renders.

Co-Authored-By: Claude <noreply@anthropic.com>
@ch264
ch264 force-pushed the global-footer-shared-component branch from 9a80dda to 45c7e1a Compare August 27, 2026 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant