510 Commits

Author SHA1 Message Date
Ben Senescu
625b76ebee
Make self hosting better (#428) 2026-07-29 23:10:01 -04:00
Ben Senescu
b0e850db2b
Backlinks tab: default sort by most recent (firstSeen) instead of rank (#432) 2026-07-29 22:41:31 -04:00
Ben Senescu
68fdcd9bf9
feat(skills): add seo-audit agent skill (#430)
* feat(skills): add beginner-seo-audit agent skill

A portable agent skill that audits a domain with OpenSEO and delivers a
one-page, plain-language HTML report for a non-SEO owner, centered on a
single do-this-week action. Ships with a frozen report template and a
docs page under Agent Skills.

* feat(skills): add starting-focus keyword step; cross-link from coach and project setup

- beginner-seo-audit now proposes a 'Where to focus first' area on healthy
  sites: one research_keywords call, one theme, 3-5 winnable keywords with
  what to make for each. Skipped entirely when the site is down.
- seo-coach and seo-project-setup now recommend beginner-seo-audit as the
  first workflow for a beginner with an existing site.
- Docs pages updated to match.

* refactor(skills): rename beginner-seo-audit to seo-audit

Audience-neutral name; the plain-language, one-action framing moves to
the description. Docs slug, meta.json, and coach/project-setup
cross-references updated to match.
2026-07-29 20:47:14 -04:00
Ben Senescu
86cbba3cdb
Project switcher: fix viewport overflow + searchable combobox (#427) 2026-07-29 16:19:16 -04:00
Ben Senescu
c81fd7a130
Rank positions: report organic rank (rank_group), not absolute SERP slot (#429)
A user's #1 organic result showed as position 3-4 because rank_absolute
counts SERP features (local pack, PAA, AI overviews) as positions. Rank
tracker, keyword-research SERP list, and onboarding market snapshot now
prefer rank_group; MCP get-serp-results keeps rank_absolute since it
returns all SERP item types.
2026-07-29 10:46:15 -04:00
Ben Senescu
72c1cf0b8e
Fix modals taller than the viewport being unscrollable (#425) 2026-07-26 08:30:20 -07:00
Ben Senescu
be6a34e766
Remove Search Everywhere interview post (#424) 2026-07-23 15:52:13 -07:00
Ben Senescu
b97d381493
Include /library pages in the sitemap (derived from route files) (#423) 2026-07-23 15:20:21 -07:00
Ben Senescu
f56972639f
content-review skill + revert unfinished redesign + some copy changes (#422) 2026-07-23 14:39:56 -07:00
Jeremy Rivera
a4ede67ebb
Keyword Research Strategy Library + feature-page guides section + Search Everywhere interview (#128) 2026-07-23 11:37:58 -07:00
Ben Senescu
633876c0ef
release: v0.1.2 (#421) 2026-07-23 11:11:53 -04:00
Ben Senescu
a16fbd17a8 fix(ui): proper loading states for rank tracking list, detail, and dashboard cards (#419) 2026-07-23 10:31:53 -04:00
Ben Senescu
67ed8d3c77 feat(web): add Product Hunt #1 Product of the Day laurel to the hero (#415) 2026-07-23 10:31:53 -04:00
Amine Benboubker
b0b5528a3a
feat(mcp): add create_project tool (#114) 2026-07-23 10:07:02 -04:00
Slim Bouras
2c153f9a20
feat(mcp): accept locationCode/languageCode on Labs research tools (#113)
Co-authored-by: isatimur <isatimur@users.noreply.github.com>
2026-07-23 10:05:43 -04:00
Xiaonan Cui
d3c62aa5a2
fix(search-tabs): keep tabs without explicit location across reloads (#108) 2026-07-23 10:00:26 -04:00
Shuvam Kumar
3edbd0c11e
fix(gsc): clamp month-based date ranges instead of overflowing short months (#133) 2026-07-23 09:57:25 -04:00
Shuvam Kumar
d7cfbec796
fix(backlinks): keep truncateMiddle within maxLength (#134) 2026-07-23 09:56:09 -04:00
Shuvam Kumar
8ca2e0b332
fix(domain): base pagination hasMore on fetched rows, not filtered rows (#135) 2026-07-23 09:51:31 -04:00
Xiaonan Cui
0d654c06e6
test(e2e): update landing redirect assertions for dashboard landing page (#109) 2026-07-23 09:50:09 -04:00
Jeremy Rivera
95e95d48cb
Add blog post: The Dark Query Problem (#110) 2026-07-21 16:40:07 -04:00
Ben Senescu
b41092788a
release: v0.1.1 (#413) 2026-07-20 23:23:15 -04:00
Ben Senescu
3a94f02a55
fix(self-host): unbreak the Deploy to Cloudflare button and its build (#412) 2026-07-20 23:03:09 -04:00
Ben Senescu
7990c4db7f
fix(billing): confirm credit depletion before refusing chat turns (#407) 2026-07-20 18:36:02 -04:00
Ben Senescu
278b19836d
feat(db): retry transient connection errors in the Postgres client (#408) 2026-07-20 18:16:17 -04:00
Ben Senescu
6f2eb05211
release: v0.1.0 (#404) 2026-07-19 02:19:28 -04:00
bookingseo
4aaeade3b0
fix: prompt explorer citations always empty (annotations have no type field) (#82) 2026-07-19 02:02:31 -04:00
bookingseo
57524b5b97
fix(search-tabs): select the right-hand neighbor when closing the active tab (#89) 2026-07-19 01:14:43 -04:00
bookingseo
01a97de55a
fix(domain): memoize the pages-table data slice to stop an infinite render loop (#88) 2026-07-19 01:14:23 -04:00
Ben Senescu
20d3de0e08
Refresh homepage messaging and Product Hunt banner (#402) 2026-07-19 00:59:39 -04:00
Ben Senescu
cd550729a2
Pricing page redesign: usage estimator + flat layout (#368) 2026-07-19 00:51:51 -04:00
Ben Senescu
072fbecae3
Simplify README and organize docs (#400) 2026-07-19 00:02:29 -04:00
Ben Senescu
6ad65f59e1
Bound audit crawl resource usage (#401)
Cap crawled HTML bodies at 2 MiB before Cheerio parsing, bulk-insert
audit links on Postgres instead of per-row Hyperdrive round trips, and
raise the Worker CPU ceiling to the 5-minute paid max for link-heavy
crawl steps.
2026-07-18 23:49:30 -04:00
Ben Senescu
7f2e730a1c
Hide rank tracking card from project dashboard (#399)
Remove the RankMovementCard (setup pitch + rank movement stats) from the
dashboard grid until the rank tracking experience gets more polish. The
overview endpoint still returns the rank summary, so restoring the card
is a small revert of this commit.
2026-07-18 22:22:23 -04:00
Ben Senescu
b981e83bf8
feat: tweak telemetry (telemachus!) heartbeat (#397) 2026-07-18 22:22:01 -04:00
Ben Senescu
eda5e1e354
Project dashboard: onboarding checklist + domain overview (#398) 2026-07-18 21:52:35 -04:00
Ben Senescu
040282511a
fix: treat empty-string env vars as unset in getEnvValueSync (#396) 2026-07-18 20:08:20 -04:00
Ben Senescu
1398605ddc
feat: anonymous self-host telemetry heartbeat (#395) 2026-07-18 20:07:42 -04:00
Ben Senescu
8460df1f29
release: v0.0.28 (#394) 2026-07-16 11:27:43 -04:00
Ben Senescu
955cdcc751 Single keyword input for keyword research (Enter submits) (#391) 2026-07-16 10:48:50 -04:00
bookingseo
0f08437cd0
feat: configurable default market for location/language fallbacks (#72) 2026-07-16 10:46:49 -04:00
Ben Senescu
c1121bdcab release: v0.0.27 (#390) 2026-07-15 12:39:32 -04:00
Ben Senescu
016d8396e3 chore(papercuts): prune environment noise + tighten the skill (#389) 2026-07-15 12:39:32 -04:00
Ben Senescu
bd22268ad2 Alchemy v2 for SaaS deployments (preview envs); account-agnostic wrangler.jsonc (#324) 2026-07-15 12:39:31 -04:00
Ben Senescu
d6d0f210ba Redesign the BadSEO home and landing lab experience (#381)
* Redesign BadSEO homepage and add design lab routes

* Migrate badseo.dev to TanStack Start

* Refine BadSEO landing page design

* Migrate badseo.dev to TanStack Start

* Refine BadSEO field guide homepage

* Simplify BadSEO example catalog

* Remove BadSEO issue section label

* Remove All issues from BadSEO header

* Reorder BadSEO examples and simplify footer

* Reduce BadSEO desktop hero type

* Narrow BadSEO homepage content

* Further reduce BadSEO hero type

* Add BadSEO brand to footer

* Tighten Kitchen sink description

* Reorder BadSEO example categories
2026-07-15 12:39:31 -04:00
Ben Senescu
987e5494a2 Add Plausible and consent-gated GA4 to badseo.dev (#380)
* Add consent-gated GA4 to badseo.dev

* Refine analytics consent banner

* Add Plausible analytics to badseo.dev

* Tighten analytics consent prompt

* Update analytics consent copy
2026-07-15 12:39:31 -04:00
Ben Senescu
61c0b0c657
Index cascade FK columns on audit child tables (#86) 2026-07-14 19:08:00 -04:00
Maria Zuheros
b44dd6e1a7
fix(sidebar): keep hover and active nav backgrounds visually distinct (#84) 2026-07-14 16:33:10 -04:00
Maria Zuheros
927e931e51
feat(keywords): add search intent filter to Keyword Research (#76)
Add a multi-select intent filter (Informational, Commercial,
Transactional, Navigational, Unknown) to the Keyword Research table on
both the desktop and mobile layouts (closes #67).

Selected intents are stored as a comma-separated string in a new
`intents` filter field, so they fit the existing all-strings filter
shape and get active-filter counting, persistence, and clear-all for
free. Sorting, pagination, save, and export already derive from the
filtered row set, so they respect the intent filter automatically. The
persistence schema defaults `intents` to "" so filter blobs saved before
this change still load. Intent classification and URL params are
untouched.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 13:25:31 -04:00
A Sivasubramanian Manoj
65f7baf8a1
Add Rank Tracking metric filters and fix null-last sort ordering (#75) 2026-07-13 13:25:14 -04:00