NIH.gov Homepage — Technical Teardown & Fast-Fix List

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)

  1. Wrong Open Graph canonical
  • og:url is https://www.nih.gov/node on the homepage.
  • Fix: set to root. <meta property="og:url" content="https://www.nih.gov/">
  1. OG type mismatch
  • Homepages should use website, not Article. <meta property="og:type" content="website">
  1. Title formatting
  • <title>National Institutes of Health (NIH) |</title> ends with a dangling pipe. <title>National Institutes of Health (NIH)</title>
  1. Hero image is a CSS background (twice) → poor LCP
  • The hero is set via style="background-image:..." on the section and again on an inner div.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.)
  1. Too many images marked loading="eager"
  • Card/teaser images use loading="eager". Only the LCP (hero) should be eager; others should be loading="lazy" + decoding="async". <img loading="lazy" decoding="async" ...>
  1. Search config conflict for Español on English page
  • Footer script sets usasearch_config = { siteHandle: "nih-espanol" } globally, while the primary header form posts with affiliate=nih.
  • Fix: only load/set the Español siteHandle on Spanish pages; on English, set nih (or remove the footer initializer entirely here).
  1. 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.
  1. 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.
  1. 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 drop id from hidden fields.
  1. 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_image for 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 async or defer and 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: true and extNofollow: 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:url to root; og:type to website; remove trailing pipe in <title>.
  • Convert hero to <img>; remove duplicated CSS background; mark as fetchpriority="high".
  • Audit loading="eager" → keep only LCP eager; others lazy + decoding="async".
  • Ensure no duplicate element IDs (affiliate, etc.).
  • English page: change return-to-top title from “Subir” → “Back to top”.
  • Only set usasearch_config to nih-espanol on Spanish pages; keep nih on 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.