Skip to content

SEO/GEO audit fixes: titles, author E-E-A-T, schema, lastmod - #571

Open
nehagup wants to merge 2 commits into
mainfrom
seo/geo-audit-fixes-2026-10
Open

nehagup wants to merge 2 commits into
mainfrom
seo/geo-audit-fixes-2026-10

Conversation

@nehagup

@nehagup nehagup commented Oct 22, 2026

Copy link
Copy Markdown
Member

Fixes the keploy/blog-website items from the Oct 2026 SEO/GEO audit.

Titles and H1s

  • <title> clipping (utils/seo.ts): over-long titles now cut at a phrase or word boundary. A clipped title never ends in a connector (&, and, vs, :, ,) or an unclosed (.
    Example: "Integration Testing: Complete Guide (Types, Tools &" becomes "Integration Testing: Complete Guide".
  • H1 casing (components/post-title.tsx, new utils/titleCase.ts): the old helper lowercased the whole title and then capitalized after every word boundary. The new helper keeps acronyms (API, QA, AI, CI/CD, SDK, JSON, YAML, UI/UX, HTTP, REST, gRPC, E2E, eBPF and others), keeps mixed-case words as written (JavaScript, GraphQL), does not capitalize after an apostrophe, and keeps "vs" lowercase.
    Examples: /blog/community/what-is-api-testing, /playwright-api-testing, /qa-testing-tools, /what-is-api-mocking ("A Developer'S Guide To Api Mocking" becomes "A Developer's Guide To API Mocking").

Author E-E-A-T

  • Empty author box: WordPress (PublishPress) injected an empty author box with the hardcoded box-post-id-16 into every post body. It is now removed by stripPublishPressAuthorBox (lib/author-box.ts). The page's own per-post AuthorCard stays.
  • Writer bio and avatar: when the post content has no author-box bio, the writer bio and avatar now come from the author's own WordPress user record (Biographical Info and avatar). The record is fetched by exact display-name match in getStaticProps and memoized. It falls back to the old behaviour on any failure.
  • Updated date: the byline now shows "Updated " when WordPress modified is a later day than date. Both dates use <time datetime>.

Schema

Pre-content clutter

  • The byline, date, tags, "Summarize with AI" and preferred-source row are now wrapped in <aside aria-label="Post details"> instead of a <div>. Same classes, so the visual layout does not change. Extractors should now treat this as page chrome, so the first content passage is the article lede.

Crawl files

  • Deleted public/robots.txt (/blog/robots.txt) and its Cache-Control header rule. Crawlers only read /robots.txt at the host root (RFC 9309), so this file was ignored. It also contradicted the root policy on training bots. All rules must live in the root robots.txt (keploy/landing PR). Before merging, make sure the root file has the /blog/api/, /blog/wp/ and /blog/cgi-bin/ disallows (and the /blog/api/proxy-image allow) that this file had.
  • Sitemap (scripts/generate-sitemap.mjs): <priority> is no longer emitted (Google ignores it). public/sitemap.xml updates on the next Sync Sitemap run.

Skipped and why

  • Blog llms.txt (Allen Digital, "Feneva", stars): public/llms.txt and public/llms-full.txt here contain none of these strings. They are in the root llms.txt served by keploy/landing, so that is where they need fixing. Live GitHub count is 18,689, so it should read "18K+".
  • Bulk lastmod: the generator already uses each post's real WP modified date, falling back to date. The shared dates (67 posts on 2026-09-09, 62 on 2026-08-18) come from bulk edits in WordPress itself. Fixing them needs an editorial rule in WordPress, not a code change: avoid bulk re-saves and plugin-wide content rewrites, or use a "substantive update" field.
  • wp.keploy.io noindex: this is WordPress server config, so it cannot be set from this repo. See manual steps.

Manual steps (WP admin)

  1. On wp.keploy.io, stop the front end from being indexed while keeping /graphql and /wp-content/uploads reachable. Either:

    • send X-Robots-Tag: noindex from the server or a plugin on all non-/graphql front-end responses, or
    • 301 front-end URLs (/?p=* and post permalinks) to https://keploy.io/blog/....

    Do not use Settings > Reading > "Discourage search engines" alone. It only changes robots meta, and some plugins also apply it to feeds.

  2. Fill in each author's Biographical Info in Users > Profile. The post author card and the Person schema now read it.

  3. Optional: turn off PublishPress's automatic author box ("Show author box after content"). This PR strips it, but it is still dead markup in the WordPress output.

Tests

  • npm run test:unit: 135/135 pass. Adds tests/lib/titleCase.test.ts, which covers headline case, phrase-boundary clipping, the author-box strip and the exact-name WP user match.
  • npx tsc --noEmit: pass.
  • npm run lint: 0 errors (only the existing exhaustive-deps warnings).
  • npm run build: not verified locally. It failed inside next/font (Google DM_Sans in pages/_app.tsx, a file this PR doesn't touch) with "Cannot read properties of null", on Node 26.3. That looks like a local Node/Next mismatch, so please rely on the Vercel preview build.

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings October 22, 2026 11:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Writer-data serialization can expose email addresses, while author-box removal and title processing can corrupt published content.

5 open issues
What changed in this PR

Addresses the blog’s SEO/GEO audit with improved title formatting, richer author metadata and structured data, and crawl-file cleanup.

Changes:

  • Adds acronym-aware headline casing and phrase-boundary title clipping.
  • Adds WordPress author-profile fallbacks, visible updated dates, and author-box cleanup.
  • Enriches schema metadata, removes sitemap priorities, and delegates robots rules to the host root.
File Description
utils/​titleCase.ts Adds headline casing that preserves acronyms and mixed case.
utils/​seo.ts Adds boundary-aware title clipping.
tests/​lib/​titleCase.test.ts Tests casing, clipping, author-box removal, and author matching.
scripts/​generate-sitemap.mjs Stops emitting sitemap priorities.
README.md Documents root-level robots policy ownership.
public/​robots.txt Deletes the blog-local robots file.
pages/​technology/​[slug].tsx Integrates writer profiles, modified dates, and content cleanup.
pages/​community/​[slug].tsx Integrates writer profiles, modified dates, and content cleanup.
next.config.js Removes the blog robots cache-header rule.
lib/​structured-data.ts Enriches publisher and software entity metadata.
lib/​author-box.ts Adds author-box stripping and exact-name user matching.
components/​PostHeaderAuthors.tsx Displays semantic publication and updated dates.
components/​post-title.tsx Uses the new headline-casing helper.
components/​post-header.tsx Passes modified dates and groups post details in an aside.

Review effort: Balanced

Comment thread pages/community/[slug].tsx
Comment thread lib/author-box.ts Outdated
Comment thread utils/seo.ts Outdated
Comment thread utils/seo.ts Outdated
Comment thread utils/titleCase.ts Outdated
Copilot AI balanced review requested due to automatic review settings October 23, 2026 15:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Title-formatting issues remain unresolved, and root crawl-rule coordination and a successful preview build still need confirmation.

No open issues 🎉

2 previously missed issues

In code that hasn't changed since last review

Medium severity Preserve UI/UX acronym casing in headline conversion

utils/​titleCase.ts:12

The canonical forms include CI/CD but omit UI/UX. Because the helper splits tokens only on whitespace, toHeadlineCase("ui/ux testing") returns Ui/ux Testing rather than UI/UX Testing. Add UI/UX to the lookup so this acronym receives the same normalization as CI/CD, and cover the lowercase input in the acronym test.

Medium severity Handle punctuation when preserving VS Code casing

utils/​titleCase.ts:34

The lookahead compares the entire next whitespace-delimited token, so punctuation defeats the VS Code exception. Debugging in VS Code: A Guide becomes Debugging In vs Code: A Guide, and Debugging in (VS Code) becomes Debugging In (vs Code), lowercasing an already-correct product name in the H1. Strip the next token's surrounding punctuation before comparing it with code, and add regression cases for the colon and closing parenthesis.

5 resolved since last review

Review effort: Balanced

@nehagup
nehagup force-pushed the seo/geo-audit-fixes-2026-10 branch from 3aaaa3f to 088e051 Compare October 23, 2026 15:49
nehagup and others added 2 commits October 23, 2026 21:26
…te, robots/sitemap cleanup

- buildPageTitle clips at phrase boundaries (no dangling '&', ':', unclosed '(')
- PostTitle: acronym-aware headline case (API, QA, CI/CD, gRPC), no cap after apostrophe, keep 'vs'
- BlogPosting/TechArticle publisher: url + sameAs incl. Wikidata Q137395272;
  SoftwareApplication mention carries applicationCategory DeveloperApplication
- Strip empty PublishPress author box (hardcoded box-post-id-16); writer card
  falls back to the WP user bio/avatar matched by exact name
- Visible 'Updated <date>' when WP modified > published; byline/CTAs in <aside>
- Remove ignored /blog/robots.txt; stop emitting ignored sitemap <priority>

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Neha Gupta <gneha21@yahoo.in>
…itle clip and acronym fixes

- Select exact-name WP writer in getStaticProps and pass only name/avatar/bio
  (toPublicAuthor); drop email from the users query entirely
- stripPublishPressAuthorBox matches each begin/end code block separately and
  removes only PublishPress ones
- clipTitleAtBoundary keeps C++ (only strips standalone '+'), trims before the
  first unmatched '(' incl. nested and position 0
- titleCase acronym lookup uses a Map (no prototype keys)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Neha Gupta <gneha21@yahoo.in>
@nehagup
nehagup force-pushed the seo/geo-audit-fixes-2026-10 branch from 088e051 to 44b3a40 Compare October 23, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants