| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Find the pages your site forgot — and the exact paragraph that should link to them.
Orphan-page rescue and internal-link insertion for serious WordPress and Webflow sites. Built entirely on the Cloudflare developer platform.
A self-hosted, open-source alternative to Link Whisper and InLinks — your data, your AI key, no per-seat SaaS bill.
Landing → workbench → ranked orphans → audit log. Real UI, seeded data.
A growing site quietly accumulates orphan pages — published URLs that nothing else links to. Search engines struggle to find them, and the traffic they could earn leaks away.
recto reads every page you have published, finds the orphans, ranks them by lost Google Search Console impressions, and shows you the exact paragraph on another page where an internal link belongs. You approve each suggestion; recto pushes the link through your CMS's REST API so it lives in the published HTML and survives even if you stop using the tool.
This is a monorepo with two top-level packages:
.
├── recto/ # The backend — pnpm/Cloudflare monorepo
│ ├── apps/
│ │ ├── workers/api/ # Hono API on Cloudflare Workers
│ │ └── web/ # static Pages bundle (mirror of recto-ui)
│ ├── packages/
│ │ ├── db/ # Drizzle (D1 dialect) schema + migrations
│ │ ├── shared/ # zod schemas, constants, shared types
│ │ └── eslint-recto/ # brand-voice + hook-pattern lint rules
│ ├── load/ # k6 load scripts
│ ├── scripts/ # smoke / integration / fuzz / deploy
│ └── ops/runbooks/ # operational runbooks (e.g. GSC OAuth setup)
└── recto-ui/ # The frontend — audited static UI (landing + app shell)
├── app/ # signed-in app screens (vanilla HTML/CSS/JS)
├── styles/ # design tokens + components
└── tests/ # Playwright persona, a11y, and visual-baseline gates
Cloudflare-only. No servers, no containers.
| Concern | Cloudflare primitive |
|---|---|
| API | Workers (Hono) |
| Relational data (OLTP) | D1 (SQLite) |
| Embeddings / similarity | Vectorize |
| Sessions, rate limits, ETag cache | KV |
| Cold blobs (audit archive) | R2 |
| Async jobs (crawl / embed / push / verify / email) | Queues |
| Scheduled work (GSC sync, weekly digest, link reverify) | Cron Triggers |
| Embedding + anchor-generation floor | Workers AI (BGE, Llama 3.1 8B) |
| JS-rendered pages | Browser Rendering |
| Crawl progress (SSE) | Durable Objects |
| Transactional email | Emailit → Resend → MailChannels fallback |
The landing page:
The signed-in app — every link is suggested, you approve each one. The audit log shows the verify-state legend for every CMS push:
The app screens (docs/screenshots/app-*.png) are captured from the real UI against a seeded local backend — exactly what you get after pnpm setup. The example site, orphan rankings, and audit history are demo seed data.
Prerequisites: Node ≥ 20, pnpm 9, and a free Cloudflare account. wrangler is already a dev dependency — pnpm install brings it in, no global install needed.
git clone https://github.com/eikiyo/recto.git && cd recto/recto && pnpm setupThat one line does everything: it auto-generates local dev secrets (so the app boots with zero key-pasting), opens .dev.vars in case you want to add real GSC/Emailit keys, installs the whole workspace, creates + migrates the local D1 database, and launches the API on http://localhost:8787 and the UI on http://localhost:8765 together (Ctrl-C stops both).
Prefer to run the steps yourself?First run, pnpm install downloads the toolchain (wrangler, drizzle, playwright) — that's a one-time few minutes. After it, boot is seconds. The only thing you ever have to type is that one command.
pnpm install
cp apps/workers/api/.dev.vars.example apps/workers/api/.dev.vars # then fill in keys
pnpm --filter @recto/api db:migrate:local # applies the committed migrations
pnpm dev # both servers; or pnpm dev:api / pnpm dev:web separatelyNote: db:generate is a maintainer-only step — run it only when you change schema.ts. The repo ships curated migrations, so a fresh clone just applies them with db:migrate:local.
Health check:
curl http://localhost:8787/api/health
# → {"status":"ok","checks":{"env":"dev","db":"bound","kv":"bound",...,"dbPing":"ok"},"ts":...}To deploy your own instance, create the Cloudflare resources and paste their IDs into recto/apps/workers/api/wrangler.toml (search for REPLACE_WITH_):
cd recto
pnpm exec wrangler d1 create recto
pnpm exec wrangler kv namespace create KV
# then set production secrets:
pnpm exec wrangler secret put RECTO_KEK
pnpm exec wrangler secret put MAGIC_LINK_SECRET
# …etc (see apps/workers/api/.dev.vars.example for the full list)All runtime configuration is environment-driven. The single source of truth is recto/apps/workers/api/.dev.vars.example, which documents every variable the Worker reads and where to obtain it. Non-secret bindings (D1, KV, Queues, R2, Vectorize, AI) are declared in recto/apps/workers/api/wrangler.toml.
The Google Search Console OAuth setup is the one manual step — a full walkthrough lives in recto/ops/runbooks/gsc-setup.md.
cd recto
pnpm --filter @recto/api typecheck # strict TypeScript
pnpm --filter @recto/api lint # ESLint + brand-voice rules
pnpm --filter @recto/api test # vitest: unit, property, chaos
bash scripts/smoke.sh # API smoke test (needs wrangler dev running)The frontend ships its own audited Playwright suite (persona simulations, accessibility, and visual-baseline snapshots) under recto-ui/tests/.
Issues and pull requests are welcome. Please read CONTRIBUTING.md and the Code of Conduct first. Security reports go through the process in SECURITY.md.
MIT © 2026 Eikiyo
| Back | FazBrowse Home | New Git URL |