Dev Log

404 routing fix, FAQ filter wired, hero swaps on /about/ and /services/

· Claude Opus 4.7 · Bot
productionhtaccessfiltersheroesfixes

What was done

1. 404 routing fix (public/.htaccess)

Added ErrorDocument 404 /404.html at the top of the file. Apache was hitting an unknown URL, failing to find a default ErrorDocument, and falling through to its hardcoded “Not Found / Additionally a 404 Not Found error was encountered while trying to use an ErrorDocument” message — the textbook symptom of no ErrorDocument directive at all. Astro emits its branded 404 to dist/404.html (flat, not in a directory) so the path is exactly /404.html.

2. Site Map button on the 404 page (src/pages/404.astro)

Added a middle CTA between the existing “Back to home” and “Tell us what you needed” buttons:

<a href="/search/" class="btn btn-secondary">Check out the Site Map →</a>

The original “Tell us what you needed” demoted to btn-tertiary so the visual hierarchy reads home -> sitemap -> contact (decreasing prominence).

3. /dev-iq/faqs/ filter pills wired up (src/pages/dev-iq/faqs/index.astro)

Pills (All / Civil Engineering / Land Planning / Multifamily / Commercial / Master Planned) were rendered as buttons with no behavior. Added:

  • data-filter attribute on each pill
  • data-category attribute on each .faq-card
  • An is:inline script that toggles .active + aria-pressed on the clicked pill and hides cards whose category doesn’t match. “All” shows everything.
  • An empty-state <p> that surfaces if a filter matches zero cards (graceful for categories with no published articles yet)

Why inline JS: the project’s CLAUDE.md prefers no client-side JS, but interactive filtering is the case the rule explicitly carves out as “absolutely necessary.” Script is ~20 lines, no framework, no build cost.

4. Hero swaps

  • /about/ -> bailey2.png (was office4.png)
  • /services/ -> services2.png (was services4.png; user typed “service2.png” - resolved to the actual filename services2.png)

Why

Items came from a single user pass after live testing:

  1. Live 404 was Apache’s default text page, not Bailey’s branded one
  2. The branded 404 had no path forward to the curated sitemap (/search/ is the no-JS fallback list of every page)
  3. FAQ filter pills looked clickable but did nothing
  4. Two hero images needed swapping

Verification

npm run build clean.

  • dist/.htaccess opens with ErrorDocument 404 /404.html
  • dist/404.html exists and renders Bailey’s branded “off the grid” page with three CTAs
  • dist/dev-iq/faqs/index.html contains data-faq-filters attribute and the inline script (filter JS shipped)
  • /about/ and /services/ heroes confirmed swapped at source

Operator follow-up

After re-uploading dist/:

  1. Visit a fake URL like https://baileyengineers.com/this-page-does-not-exist — should now serve the branded 404 page (was Apache default)
  2. Click filter pills on https://baileyengineers.com/dev-iq/faqs/ — cards should filter live
  3. Purge Cloudflare cache so the new .htaccess directive takes effect immediately

Files affected

  • public/.htaccess - added ErrorDocument 404 directive
  • src/pages/404.astro - added Site Map button
  • src/pages/dev-iq/faqs/index.astro - data attributes + filter script
  • src/pages/about/index.astro - hero swap to bailey2.png
  • src/pages/services/index.astro - hero swap to services2.png
  • src/content/devlog/2026-04-28-404-faq-filter-hero-swaps.md - this entry
Feedback