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

Here’s a concise, developer-oriented readout from the HTML you shared (Drupal 10 + USWDS).


Snapshot

  • Stack: Drupal 10, USWDS header/megamenu, GTM (GTM-N65GDDH), DAP analytics.
  • Strengths: Solid IA, USWDS patterns, skip links, canonical/shortlink, responsive mega-menus.

Fix-first issues (actionable)

  1. Duplicate IDs in search
    • Two inputs share id="header-search" (USDA.gov vs All-USDA forms). Breaks label/ID mapping & a11y.
    • Fix: Make IDs unique and match labels: <!-- USDA.gov form --> <label for="header-search-usda" class="usa-sr-only">Search USDA.gov</label> <input id="header-search-usda" name="query" ...> <!-- All-USDA form --> <label for="header-search-agencies" class="usa-sr-only">Search All USDA Agencies</label> <input id="header-search-agencies" name="query" ...>
  2. Hero image is lazily loaded (hurts LCP)
    • Above-the-fold hero uses loading="lazy".
    • Fix: Remove lazy, add fetchpriority="high", add alt (or alt="" if decorative): <img src="/sites/default/files/homepage-hero-full.jpeg" width="2000" height="1333" fetchpriority="high" decoding="async" alt="">
  3. Analytics duplication / legacy
    • DAP script is injected twice (head and again in head-placeholder).
    • Universal Analytics (UA-*) calls persist alongside GTM; UA is sunset.
    • Fix: Remove duplicate DAP include and all UA snippets; consolidate on GTM/DAP only.
  4. External link safety
    • extlink settings extNoreferrer=false and links often lack rel="noopener noreferrer".
    • Fix: Set extNoreferrer=true and ensure external anchors render with rel="noopener noreferrer".

Quick performance wins

  • Preconnect important origins <link rel="preconnect" href="https://usdasearch.usda.gov" crossorigin> <link rel="preconnect" href="https://www.googletagmanager.com">
  • Modern formats: Serve hero/feature images as AVIF/WebP with type/srcset; keep JPEG fallback.
  • Defer non-critical JS: Mark nonessential scripts defer; load carousels on requestIdleCallback if possible.
  • Set decoding="async" on non-critical <img>.

Accessibility touch-ups

  • Ensure every meaningful image has descriptive alt; decorative get alt="".
  • Confirm reduced-motion support for any auto-sliding/animated components: @media (prefers-reduced-motion: reduce) { .usa-megamenu, .carousel, [data-animate] { animation: none !important; transition: none !important; } }
  • Radio-driven search switcher: ensure focus management moves to the active form and that both radios have a proper fieldset/legend for context.

Security hardening

  • Add a CSP (report-only) baseline and move to enforce after tuning.
  • Use SRI on third-party scripts/styles (GTM loader is exempt; DAP is federal, still fine to restrict via CSP).

SEO polish

  • <title> is just “Home”. Make it descriptive: <title>U.S. Department of Agriculture (USDA)</title>
  • Add a concise <meta name="description" ...> for the homepage.
  • Consider Organization JSON-LD with logo/contact.

Example diffs (small but high impact)

Remove duplicate DAP include (leave one):

<!-- KEEP once in <head> -->
<script async src="https://dap.digitalgov.gov/Universal-Federated-Analytics-Min.js?agency=USDA&sp=lookup,locate&exts=pdf,xls,zip,jpg,gif,mp3&dclink=true&yt=true&enhlink=true" id="_fed_an_ua_tag"></script>

External links helper (Twig/Drupal)

{% set rel = (link.isExternal) ? 'noopener noreferrer' : null %}
<a href="{{ url }}" rel="{{ rel }}">{{ text }}</a>

Priority backlog (bite-sized)

  1. Unique IDs for search inputs + labels.
  2. Fix hero LCP (no lazy; high priority; alt).
  3. Remove duplicate DAP + all UA; keep GTM.
  4. extlink rel="noopener noreferrer" + extNoreferrer=true.
  5. Reduced-motion handling for any animations.
  6. Preconnect + image format upgrades.
  7. SEO title/description; add Org JSON-LD.

Want me to turn this into tickets (with acceptance criteria) or generate a minimal CSP to trial in Report-Only?