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.mdtoexcludein_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/toexclude, matching howvenv/andwiki-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 defaultloading="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 forforloop.first).
6. Two feed mechanisms, one shadowing the other
- Where:
feed.xml(hand-rolled Jekyll Now RSS template) vs thejekyll-feedplugin (_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" />indefault.html:50advertises the RSS one, so it works — but the redundancy is confusing. - Fix: Pick one: delete
feed.xmland keepjekyll-feed, or drop the plugin. Nit either way: the RSSenclosure length="0"atfeed.xml:90is 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-listedcategories.mdare two sources of truth for “what are my topics.” - Fix: Extract to one include, or a
_data/category-labels.ymlmap 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
98where 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.cssandassets/css/blog.css— copied to_site/assets/css/, referenced by no page.- Fix: Delete all of the above in one pass;
main.scssis the only stylesheet that matters.
10. Schema warts
- Where:
_includes/schema.html alumniOffor former employers (:150-157) is semantically wrong — it’s for educational institutions.- Self-declared
aggregateRatingof 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.jsexternal 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_Storenot tracked;onerror=inexperience.md:21never renders (nologofields in_data/experience.yml).