Site Review — Issues by Priority

Site Review — Issues by Priority

Reviewed: 2026-08-20. Scope: _config.yml, layouts, includes, Sass design system, JS, data files, content pages, sample of posts, and the built _site/ output.

High — fix these first

1. Broken OG fallback image

  • Where: _layouts/default.html:60 (og:image) and :77 (twitter:image)
  • Issue: Both fall back to /images/og-image.png, which does not exist. Every non-post page (about, projects, experience, contact, blog index) advertises a missing image in social shares — no preview card.
  • Fix: Create a 1200×630 images/og-image.png, or point the fallback at something real (e.g. /images/profile.jpg).

2. CONTACT_SETUP.md is published

  • Where: repo root; served at /CONTACT_SETUP/ and /CONTACT_SETUP.md
  • Issue: An internal setup checklist (“✅ ALREADY CONFIGURED”) is tracked in git and shipped to the site. Dev doc, not visitor content.
  • Fix: Delete it (setup is done) or add CONTACT_SETUP.md to exclude in _config.yml.

3. book/ bloats local builds

  • Where: _config.yml:107-110 (exclude list); book/ in repo root
  • Issue: 294 MB of epub/html/pdf lands in _site/book/. The directory is git-ignored so GitHub Pages never serves it, but the exclude list only skips four book files (build.sh, prepare-chapters.sh, chapter-order.yaml, metadata.yaml) — not the directory. Local builds diverge from production.
  • Fix: Add - book/ to exclude, matching how venv/ and wiki-docs/ are already handled.

Medium

4. Orphan pages in the sitemap

  • Where: archive.md (/archive/), categories.md (/categories/)
  • Issue: Both are built, published, and in sitemap.xml, but linked from nowhere — the blog’s search + category chips superseded them. Dead sitemap weight.
  • Fix: Surface them (e.g. footer links) or delete the files.

5. Featured post image is lazy-loaded

  • Where: blog.md:40 (all cards use the include’s default loading="lazy")
  • Issue: The first post’s 400px above-the-fold hero image is the LCP candidate but loads lazily — flash of empty space on the blog page.
  • Fix: Pass loading="eager" for the first item in the loop (or drop lazy for forloop.first).

6. Two feed mechanisms, one shadowing the other

  • Where: feed.xml (hand-rolled Jekyll Now RSS template) vs the jekyll-feed plugin (_config.yml:86)
  • Issue: Both target /feed.xml; the static file wins, so the plugin’s Atom output is dead weight. <link type="application/atom+xml" rel="alternate" href="https://wesleymatlock.com/feed.xml" title="Wesley Matlock" /> in default.html:50 advertises the RSS one, so it works — but the redundancy is confusing.
  • Fix: Pick one: delete feed.xml and keep jekyll-feed, or drop the plugin. Nit either way: the RSS enclosure length="0" at feed.xml:90 is a spec wart (should be byte size).

7. Category normalization triplicated

  • Where: blog.md:53-74, _layouts/home.html:138-149, _layouts/post.html:27-49
  • Issue: The downcase→display-name if/elif chain is copy-pasted in three places. Related: the hand-curated chip list (blog.md:21) and the auto-listed categories.md are two sources of truth for “what are my topics.”
  • Fix: Extract to one include, or a _data/category-labels.yml map both the chips and the labels read from.

8. Stale post counts

  • Where: _config.yml:10 (“85+ technical articles”), index.html:4, about.md:57 (“80+”)
  • Issue: The site has 98 posts; the hardcoded counts have drifted.
  • Fix: Compute 98 where feasible, or soften the phrasing (“80+” is safe; “85+” in two places will go stale again).

Low — cleanup

9. Dead code and dead output

  • _includes/navigation.html — unused (the default layout has its own inline nav); its inline <script> would violate the CSP if it were ever included.
  • Root style.scss — empty front matter, compiles to /style.css, referenced by no page. It’s the only importer of the legacy root _sass/_variables.scss, _sass/_reset.scss, and the 54 KB _sass/_svg-icons.scss.
  • assets/css/style.css and assets/css/blog.css — copied to _site/assets/css/, referenced by no page.
  • Fix: Delete all of the above in one pass; main.scss is the only stylesheet that matters.

10. Schema warts

  • Where: _includes/schema.html
  • alumniOf for former employers (:150-157) is semantically wrong — it’s for educational institutions.
  • Self-declared aggregateRating of 5/1 on your own apps (:117-121) is the kind of thing Google’s guidelines discount.
  • Fix: Drop alumniOf (use a plain work-history list) and the self-serving rating, or source real ratings.

11. cleanup_for_production.sh is residue

  • Where: repo root (Aug 2025)
  • Issue: Targets files that no longer exist (archive_scripts.sh, check_image_formats.py, …).
  • Fix: Delete, or rewrite for what actually needs cleaning.

12. No pagination on the blog

  • Where: blog.md (all 98 posts, ~211 KB of HTML)
  • Issue: Heavy page. Defensible since client-side search needs everything in the DOM — but worth a “load more” past ~30 cards if it ever feels slow.
  • Fix: Optional; only if the page weight becomes a problem.

Not issues (verified fine)

  • CSP: no inline scripts in built output; theme.js external for pre-paint theme.
  • Images: WebP <picture> fallback works (25 MB webp vs 310 MB png); lazy loading in place.
  • Build: clean, no warnings (~2.7 s).
  • .DS_Store not tracked; onerror= in experience.md:21 never renders (no logo fields in _data/experience.yml).