SEO: add truthful page meta descriptions - #21
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughFive public pages now include descriptive meta tags. ChangesPublic metadata validation
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 96b7e9f4df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <head> | ||
| <meta charset="utf-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
| <meta name="description" content="The appraisal, with the client's name removed: a real audit of a clinic homepage, four findings with evidence and fixes, read and signed by Nish."> |
There was a problem hiding this comment.
Describe the specimen as non-client research
When this description is consumed by a crawler or shown as a search snippet, “the client's name removed” presents the specimen as anonymized client work. The page explicitly states that the clinic is not a client and that the audit comes from public-homepage research, so the new metadata creates the proof claim the page disclaims; describe it as an unnamed clinic instead.
AGENTS.md reference: AGENTS.md:L2-L3
Useful? React with 👍 / 👎.
|
|
||
| const seenDescriptions = new Map(); | ||
| for (const [pageName, pageHtml] of metaDescriptionPages) { | ||
| const tags = [...pageHtml.matchAll(/<meta\b[^>]*\bname="description"[^>]*>/gi)].map((match) => match[0]); |
There was a problem hiding this comment.
Restrict the description search to the head
If a description is accidentally moved below </head> while remaining elsewhere in the document, this whole-document regex still finds exactly one tag and the check passes, even though the invariant and failure message require metadata in the head. Extract or otherwise bound the search to the document's <head> so this regression is actually detected.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@public/index.html`:
- Line 6: Update the description meta tag content in the document head so the
phrase “Six a month” explicitly states the unit as “Six audits a month,” while
preserving the rest of the description.
In `@scripts/check-site.mjs`:
- Around line 785-787: Update the meta-description matcher in the site-check
logic around the tags collection so it first restricts matching to the
document’s <head> content and only recognizes the exact name="description"
attribute, excluding body elements and data-name attributes. Preserve the
existing exactly-one validation and failure message.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a4282970-d7d5-4ff2-81fc-71a30b7085fe
📒 Files selected for processing (6)
public/agents.htmlpublic/audit.htmlpublic/index.htmlpublic/pricing.htmlpublic/specimen.htmlscripts/check-site.mjs
| <head> | ||
| <meta charset="utf-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
| <meta name="description" content="TinyStudio: the free leak audit of high-ticket service homepages. Each fault named in order of what it costs you, with the fix beside it. Six a month."> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 3 -- 'Six a month|six|a month|\$2,500|three-month minimum' public/index.html public/pricing.html || trueRepository: nish3451/TinyStudio.io
Length of output: 8317
State the unit in Six a month.
If this refers to audit capacity, change it to Six audits a month. The meta description can appear without the page context, so the current wording is ambiguous with the $2,500 monthly desk price.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@public/index.html` at line 6, Update the description meta tag content in the
document head so the phrase “Six a month” explicitly states the unit as “Six
audits a month,” while preserving the rest of the description.
| const tags = [...pageHtml.matchAll(/<meta\b[^>]*\bname="description"[^>]*>/gi)].map((match) => match[0]); | ||
| if (tags.length !== 1) { | ||
| failures.push(`Meta description must appear exactly once in the head of ${pageName} (found ${tags.length}).`); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
node <<'NODE'
const pattern = /<meta\b[^>]*\bname="description"[^>]*>/gi;
const samples = [
'<html><head></head><body><meta name="description" content="body"></body></html>',
'<head><meta data-name="description" content="wrong"></head>',
];
for (const sample of samples) {
console.log([...sample.matchAll(pattern)].length);
}
NODERepository: nish3451/TinyStudio.io
Length of output: 164
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- plan candidates ---'
git ls-files | rg -i '(^|/)(plan|plans|readme|agents|contributing)(\.|/|$)|(^|/).*plan.*\.(md|txt)$' | head -80
printf '%s\n' '--- target context ---'
cat -n scripts/check-site.mjs | sed -n '760,815p'
printf '%s\n' '--- related head parsing and checks ---'
rg -n -C 3 'matchAll|<head|description|pageHtml' scripts/check-site.mjsRepository: nish3451/TinyStudio.io
Length of output: 6877
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- repository instructions ---'
cat AGENTS.md
printf '%s\n' '--- current plan candidates ---'
for f in docs/plans/2026-06-18-002-fix-minimal-input-agent-desk-plan.md specs/003-wellness-clinic-launch/plan.md; do
if [ -f "$f" ]; then
printf '\n### %s\n' "$f"
cat "$f"
fi
done
printf '%s\n' '--- page source locations ---'
sed -n '1,130p' scripts/check-site.mjs
printf '%s\n' '--- all description tags in checked page files ---'
rg -n -i '<meta[^>]*(name|data-name)[^>]*description|description[^>]*>' public/*.html
printf '%s\n' '--- verifier: current matcher versus proposed matcher ---'
node <<'NODE'
const current = /<meta\b[^>]*\bname="description"[^>]*>/gi;
const proposedHead = /<head\b[^>]*>([\s\S]*?)<\/head>/i;
const proposedTag = /<meta\b(?=[^>]*\sname\s*=\s*"description"(?:\s|>))[^>]*>/gi;
const samples = [
'<html><head></head><body><meta name="description" content="body"></body></html>',
'<head><meta data-name="description" content="wrong"></head>',
'<head><meta name="description" content="valid"></head>',
'<head><meta class="x" name = "description" content="valid"></head>',
'<head><meta name="description" content="valid"><meta name="description" content="duplicate"></head>',
];
for (const sample of samples) {
const head = sample.match(proposedHead)?.[1] ?? '';
console.log(JSON.stringify({
sample,
current: [...sample.matchAll(current)].length,
proposed: [...head.matchAll(proposedTag)].length,
}));
}
NODERepository: nish3451/TinyStudio.io
Length of output: 25129
Restrict the meta-description check to <head>.
The current regex scans the full document and treats data-name="description" as a match. A body element or data-name attribute can satisfy the head-description check.
Suggested matcher change
- const tags = [...pageHtml.matchAll(/<meta\b[^>]*\bname="description"[^>]*>/gi)].map((match) => match[0]);
+ const head = pageHtml.match(/<head\b[^>]*>([\s\S]*?)<\/head>/i)?.[1] ?? "";
+ const tags = [...head.matchAll(/<meta\b(?=[^>]*\sname\s*=\s*"description"(?:\s|>))[^>]*>/gi)].map((match) => match[0]);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const tags = [...pageHtml.matchAll(/<meta\b[^>]*\bname="description"[^>]*>/gi)].map((match) => match[0]); | |
| if (tags.length !== 1) { | |
| failures.push(`Meta description must appear exactly once in the head of ${pageName} (found ${tags.length}).`); | |
| const head = pageHtml.match(/<head\b[^>]*>([\s\S]*?)<\/head>/i)?.[1] ?? ""; | |
| const tags = [...head.matchAll(/<meta\b(?=[^>]*\sname\s*=\s*"description"(?:\s|>))[^>]*>/gi)].map((match) => match[0]); | |
| if (tags.length !== 1) { | |
| failures.push(`Meta description must appear exactly once in the head of ${pageName} (found ${tags.length}).`); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/check-site.mjs` around lines 785 - 787, Update the meta-description
matcher in the site-check logic around the tags collection so it first restricts
matching to the document’s <head> content and only recognizes the exact
name="description" attribute, excluding body elements and data-name attributes.
Preserve the existing exactly-one validation and failure message.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
…c10709 The meta-description fix for the home page (and the other four public pages) was merged as PR #21, with a source-string CI guard in check-site.mjs, but the live deployment was never measured. This closes that gap by recording a real-Chromium measurement of the five deployed tinystudio.io pages (2026-08-09): each serves exactly one non-empty, unique meta description in its head within search-snippet length, with no duplicates and no console errors. Dogfood finding 18dd05c10709 (missing meta description on home) is verified resolved on the deployed site.
…c10709 (#26) The meta-description fix for the home page (and the other four public pages) was merged as PR #21, with a source-string CI guard in check-site.mjs, but the live deployment was never measured. This closes that gap by recording a real-Chromium measurement of the five deployed tinystudio.io pages (2026-08-09): each serves exactly one non-empty, unique meta description in its head within search-snippet length, with no duplicates and no console errors. Dogfood finding 18dd05c10709 (missing meta description on home) is verified resolved on the deployed site.
…st current main and live (#37) The code-side fix (PR #21) and CI enforcement (the 'Meta descriptions (dogfood)' guard in scripts/check-site.mjs) for dogfood finding 18dd05c10709 ('Missing meta description on home') are already merged in origin/main. This lane re-verified the guarantee still holds after the subsequent page edits (heading hierarchy, apple-touch icon, schema.org, canonical URLs, internal-link cleanup, App Store citation, sitemap): - npm run check passes on all five public pages: each carries exactly one non-empty description tag in its head, within a search-snippet length (<= 160 chars), distinct per page, free of forbidden promises. - Fresh live measurement of the deployed pages in real Chromium confirms the same: exactly one valid, non-empty, unique meta description per page, including the home page the finding flagged (150 chars). Nothing further to change; the receipt now records the closeout on the current head so the finding cannot be re-opened by tracker drift.
intended-outcome: Add one concise, page-specific meta description to each of the five public pages so search previews identify the existing Website Appraisal offer accurately.
verify: /home/nish/.local/bin/test-gate npm run check; /home/nish/.local/bin/test-gate npm test; git diff --check; sgscan
Repository proof only. No live deployment, live search-impact, ranking, traffic, or conversion improvement is claimed. No deployment or merge in this change.
Summary by CodeRabbit
Documentation
Tests