Catching CTA findings in a Next.js + shadcn/ui app
Buttons are the single most common place content-design quality breaks down. They're short, they pass lint, they compile fine, they just don't read well. "Click here" ships. "Submit" ships. "Learn more" ships three times on the same page pointing at three different places.
This guide shows what ContentRX catches on a typical shadcn/ui
<Button> in a Next.js App Router app, using real code you'd find
in a hero section or a settings panel.
Setup
Assumed stack:
- Next.js 15 (App Router)
- Tailwind + shadcn/ui
Buttoncomponent - A PR-based workflow with GitHub Actions
Two ways to wire up ContentRX for this stack:
Option 1 — catch findings in PRs via the GitHub Action. One
workflow file, reports on every PR touching .tsx files:
# .github/workflows/content-lint.yml
name: Content lint
on:
pull_request:
paths: ['**/*.tsx']
jobs:
lint:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: thenewforktimes/contentrx-action@v1
with:
api-key: ${{ secrets.CONTENTRX_API_KEY }}
Option 2 — catch findings at write-time via the MCP server in Claude Code or Cursor. Claude consults ContentRX before writing button labels:
claude mcp add contentrx -- uvx contentrx-mcp
export CONTENTRX_API_KEY=cx_your_key
Both target the same rules. Option 1 blocks review noise at the PR; Option 2 prevents it from being written in the first place.
What you'll see — a real hero section
Here's a Hero.tsx from a typical marketing page before review:
import { Button } from "@/components/ui/button";
export function Hero() {
return (
<section>
<h1>The analytics platform built for product teams</h1>
<p>Track what matters. Skip the noise.</p>
<div className="flex gap-3">
<Button>Click here to learn more</Button>
<Button variant="outline">Submit</Button>
</div>
</section>
);
}
ContentRX evaluates these CTAs in a decision-point context and raises three findings:
Finding 1 — <Button>Click here to learn more</Button>
- Accessibility
[block]— link and CTA text needs to describe the destination on its own. "Click here" and "learn more" are the two phrases the voice guide singles out as never-acceptable standalone link text, and both appear here in the same label. - Voice & tone
[warn]— "Learn more" is the canonical vague CTA. Specific verbs and objects beat it: "Read the case studies" (specific object) or "See pricing" (specific destination).
Finding 2 — <Button variant="outline">Submit</Button>
- Voice & tone
[block]— "Submit" is the single most common finding of this type. Voice guidance is explicit: prefer "save," "send," or "export" over "submit" or "process." Suggested rewrite: "Create account" or "Send message" — whichever matches the form's actual purpose.
Why these matter
The two <Button> labels on this hero carry 80% of the page's
decision load. "Click here to learn more" adds four words and zero
meaning. "Submit" is maximally generic — it's the browser's default
for every form on the web.
The rewrites below aren't cleverer — they're more specific. Specificity is the rule here, not concision.
The fix
import { Button } from "@/components/ui/button";
export function Hero() {
return (
<section>
<h1>The analytics platform built for product teams</h1>
<p>Track what matters. Skip the noise.</p>
<div className="flex gap-3">
<Button>Read the case studies</Button>
<Button variant="outline">Create account</Button>
</div>
</section>
);
}
Two-word changes, zero remaining findings on the next PR run.
What ContentRX doesn't do here
- It won't tell you whether "case studies" is the right destination for your product. It verifies the CTA names a specific action or destination, not that the destination is strategically correct.
- It won't flag every short button. "Save," "Send," "Cancel" all pass — they're specific verbs. "Submit," "Process," "Go" fail because they're vague.
- Context matters. Confirmation and status messages aren't CTAs: "Project created" and "Payment sent" don't need to start with a verb, and ContentRX won't push back on them.
Categories on the public envelope
ContentRX returns each finding under a customer-facing category — Voice & tone, Mechanics, Structure, Accessibility, Inclusion, Big picture. CTA findings most commonly land in Voice & tone or Accessibility, as above.