`app.motir.co/robots.txt` 404s — motir-core ships a sitemap, JSON-LD and canonicals on its public surface but no `app/robots.ts`
Opened by Zhu Yue ·
Type: code · Executor: coding_agent · Repo: motir-core
Found while working MOTIR-1155 (8.3.8, Search Console setup), 2026-08-27.
https://app.motir.co/robots.txt returns 404 (text/html, Next.js' not-found page — measured with a Googlebot UA). motir-core has no app/robots.ts, while the rest of the public-surface SEO scaffolding did ship under 6.13/8.9.4: app/sitemap.ts (10 URLs), per-project + explore JSON-LD, canonicals, section OG images.
Severity is low, and the honest reason matters: an absent robots.txt reads as allow everything, so nothing is blocked or de-indexed today, and sitemap discovery is already solved a better way — the sitemap is submitted directly to the verified Search Console property (MOTIR-1155). This is crawl hygiene ahead of going public, not a live defect.
What is actually missing is the ability to say don't crawl this: /api/*, the auth routes, and the ?rank= facet URLs (/explore?rank=popular, /explore?rank=recent) which are duplicate views of /explore and currently sit in the sitemap as separate <loc>s.
Scope
- Add
app/robots.ts(Next.jsMetadataRoute.Robots) — allow crawl,sitemap:→https://app.motir.co/sitemap.xml,hostset. - Disallow:
/api/,/sign-in,/sign-up, and the other authed-only route groups that currently return a redirect to sign-in. - Decide the
?rank=facets deliberately — either drop them fromapp/sitemap.tsin favour of the canonical/explore, or leave them and let the existing canonical tags do the de-duplication. Don't do both half-way. - Build the URLs from the same base the sitemap uses; no second hardcoded host. (
metadataBasewas the subject of MOTIR-2505 — reuse it, don't reintroduce a literal.)
⚠️ This card creates the file, ONE host at a time. It ships the app host's directives against today's single origin; making the same route answer by host is MOTIR-3881's work, not this card's. Do not anticipate the second host here — a robots.ts that branches on a hostname nothing yet serves is untestable and pre-empts the ADR (MOTIR-3879) that decides which host answers for what.
Acceptance criteria
https://app.motir.co/robots.txtreturns200 text/plainwith aSitemap:line pointing at the live sitemap.- The disallow set covers
/api/and the auth routes;/exploreand/p/*remain crawlable. - A test asserts the route renders and that
/exploreis NOT disallowed — the failure mode of a robots file is silently de-indexing the surface it was meant to help, so guard the ALLOW, not just the deny. - The
?rank=facet decision is recorded on this card, not left implicit.
Context refs
app/sitemap.ts(motir-core) — the existing, shipped sitemap this must reference- MOTIR-1154 (8.3.7) plans a
robots.tsfor motir-marketing — a different repo, a different file; that card is not widened to cover this one - MOTIR-2505 —
metadataBase; the base-URL source of truth - blocks MOTIR-1130 (8.10.3, smoke the public surfaces) — going public is where this bites
- blocks MOTIR-3881 — the card that makes this file host-aware once
motir.cois served by motir-core
⚠️ Where this card lives, and why it moved (2026-08-29)
Authored under 8.10, re-parented to MOTIR-3876 — beside MOTIR-3881, the card it gates. A prerequisite takes the SAME parent as the gated card and the blocked_by edge is the whole relationship; left under 8.10 the edge crossed a story boundary and made MOTIR-3876 un-finishable (validate_work_item returned valid: false naming exactly this edge). The MOTIR-1130 edge is unchanged and now points backward into an earlier story, which is the legal direction.
Discussion
No comments yet.
Adding to this discussion signs you in on app.motir.co and brings you back to this request.