Here’s a crisp, developer-oriented audit of the HTML you shared (Drupal 10 + USWDS). I’ve prioritized the highest-impact items first, then added quick wins and sample patches.
Top 10 fixes (highest impact)
- Wrong Open Graph canonical
og:urlishttps://www.nih.gov/nodeon the homepage.- Fix: set to root.
<meta property="og:url" content="https://www.nih.gov/">
- OG type mismatch
- Homepages should use
website, notArticle.<meta property="og:type" content="website">
- Title formatting
<title>National Institutes of Health (NIH) |</title>ends with a dangling pipe.<title>National Institutes of Health (NIH)</title>
- Hero image is a CSS background (twice) → poor LCP
- The hero is set via
style="background-image:..."on the section and again on an innerdiv.hero-image. That both duplicates the request and prevents the browser from prioritizing LCP. - Fix: remove duplicate background and render the hero image as an
<img>with fetch priority.<section class="usa-hero"> <img src="/sites/default/files/2025-07/20250707-veggies-50.jpg" alt="" width="2000" height="1333" fetchpriority="high" decoding="async" class="usa-hero__image"> ... </section>(Keep decorative alt as""; if the image is informative, write a real alt.)
- Too many images marked
loading="eager"
- Card/teaser images use
loading="eager". Only the LCP (hero) should be eager; others should beloading="lazy"+decoding="async".<img loading="lazy" decoding="async" ...>
- Search config conflict for Español on English page
- Footer script sets
usasearch_config = { siteHandle: "nih-espanol" }globally, while the primary header form posts withaffiliate=nih. - Fix: only load/set the Español siteHandle on Spanish pages; on English, set
nih(or remove the footer initializer entirely here).
- External tracking review / duplication
- GTM present (
GTM-5CBCNW2) + Drupal google_tag plugin. That’s fine, but ensure you don’t have duplicate GA/gtag paths firing the same events. - Action: Verify only one pageview fires (via GTM), and remove any legacy UA/duplicate pageview code if present in GTM.
- Return-to-top UI uses Spanish title
- SVG
<title id="return-to-top">Subir</title>on the English page. - Fix: localize by page locale: “Back to top” on English.
- Accessibility: unique IDs & programmatic names
- Quick scan looks good (USWDS patterns), but ensure any repeated hidden inputs like
id="affiliate"aren’t duplicated elsewhere on the page. If repeated, make IDs unique or dropidfrom hidden fields.
- Reduce redundant hero background
- As noted in #4, remove the duplicate
style="background-image"from both wrapper and inner element to avoid double fetch and paint.
SEO & social polish
- Prefer
summary_large_imagefor Twitter card if your hero is landscape:<meta name="twitter:card" content="summary_large_image"> - Add Organization JSON-LD (helps knowledge panels):
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "GovernmentOrganization", "name": "National Institutes of Health", "url": "https://www.nih.gov/", "logo": "https://www.nih.gov/themes/custom/nih2_uswds/assets/img/nih-logo.png", "sameAs": [ "https://twitter.com/NIH", "https://www.facebook.com/nih.gov", "https://www.youtube.com/user/nihod", "https://www.instagram.com/nihgov/", "https://www.flickr.com/photos/nihgov/" ] } </script>
Performance quick wins
- Preconnect to critical third-parties used on every page:
<link rel="preconnect" href="https://www.googletagmanager.com"> <link rel="preconnect" href="https://search.usa.gov" crossorigin> <link rel="preconnect" href="https://ucm-us.verint-cdn.com" crossorigin> <!-- Verint SDK --> - Modern image delivery: serve AVIF/WebP with
srcset+ JPEG fallback for hero and card images. - Defer non-critical JS: ensure non-render-blocking scripts (e.g., CrazyEgg, Verint) are
asyncordeferand lower in the doc (you already load them async; keep it that way). - Add
decoding="async"to all non-LCP<img>.
Accessibility notes
- Respect reduced motion for carousels/animated components:
@media (prefers-reduced-motion: reduce) { .usa-hero, .teaser-list, .carousel { animation: none !important; transition: none !important } } - Ensure every icon button has an explicit text alternative (your social links are good).
- Keep breadcrumb/skip links (present ✔️).
Privacy & compliance
- Your extlink config has
extNoreferrer: trueandextNofollow: true(good). - Crazy Egg + Verint: confirm consent posture if cookie consent is required; load only after consent if applicable to NIH policy.
Security hardening (headers/CSP)
If not already active at the edge, consider:
- CSP (Report-Only to start) with strict GTM/CrazyEgg/Verint allowances, e.g.:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://www.google-analytics.com https://script.crazyegg.com https://ucm-us.verint-cdn.com; img-src 'self' data: https://*.nih.gov https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; connect-src 'self' https://www.google-analytics.com https://ucm-us.verint-cdn.com; frame-src https://www.googletagmanager.com; report-uri https://<your-report-collector>; - SRI for any pinned third-party scripts you self-include outside GTM where feasible.
Code snippets (ready to paste)
Fix hero duplication & LCP
<section class="usa-hero">
<img src="/sites/default/files/2025-07/20250707-veggies-50.jpg"
alt=""
width="2000" height="1333"
fetchpriority="high" decoding="async" />
<div class="grid-container">
<div class="grid-row">
<div class="usa-hero__callout">
<h2 class="usa-hero__heading heading--without-rule">Eating Right for Chronic Kidney Disease</h2>
<p>Eating foods with less sodium, the right protein, and heart-healthy foods may protect your kidneys.</p>
<a class="usa-button" href="...">Learn more</a>
</div>
</div>
</div>
</section>
Fix twitter card
<meta name="twitter:card" content="summary_large_image">
Fix return-to-top localization
<title id="return-to-top">Back to top</title>
Backlog (small tickets you can assign today)
- Change
og:urlto root;og:typetowebsite; remove trailing pipe in<title>. - Convert hero to
<img>; remove duplicated CSS background; mark asfetchpriority="high". - Audit
loading="eager"→ keep only LCP eager; otherslazy+decoding="async". - Ensure no duplicate element IDs (
affiliate, etc.). - English page: change return-to-top title from “Subir” → “Back to top”.
- Only set
usasearch_configtonih-espanolon Spanish pages; keepnihon English. - Verify GTM is the sole pageview emitter; remove legacy duplicates if any.
- Add preconnects and (optionally) AVIF/WebP sources for large images.
- Add Organization JSON-LD.
- (Optional) Introduce CSP in Report-Only; iterate.
If you want, I can turn these into Jira tickets with acceptance criteria, or draft a minimal Drupal preprocess to toggle Español/English search config cleanly.