MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-1154

8.3.7 Entity-signal SEO root at motir.co (motir-marketing) — Organization+WebSite JSON-LD, root OG, robots, GSC

Done
Description

Type: code · Executor: coding_agent · Bake in the GAP in entity-signal SEO.

⚠️ THIS CARD SHIPS IN motir-marketing, NOT motir-core — the 2026-06-30 8.3 re-plan moved the entity-signal SEO root to motir.co, and MOTIR-1455 created that repository on 2026-08-28 (moooon-B-V/motir-marketing, Next 16 / output: 'standalone', deployed to Fly). Every path below is relative to THAT repo's root. One subtask = one repo = one PR.

The "already shipped" inventory below is motir-core's and is NOT reusable here. app/sitemap.ts, the per-project / explore JSON-LD and the section OG images exist in motir-core and must not be re-planned THERE — but motir-marketing has none of them, so this card CREATES its own. Read the list as "don't redo it in motir-core", never as "it already exists at motir.co".

VERIFIED already shipped in motir-core (do NOT re-plan there): per-project + project-square JSON-LD (app/(public)/_components/PublicProjectJsonLd.tsx, app/(public)/explore/_components/ExploreJsonLd.tsx), app/sitemap.ts, and section OG images. The square only embeds isPartOf: WebSite inside a CollectionPage — there is NO standalone site Organization/WebSite entity, NO root OG image, NO robots.ts, and NO Search Console verification. (motir-core's own missing robots.txt is a separate bug, MOTIR-3726 — not this card.)

Ship, in motir-marketing:

  • Organization + WebSite JSON-LD at the root (a RootJsonLd component injected in app/layout.tsx or app/page.tsx): Organization (name Motir, the logomark URL as logo, sameAs → GitHub / Product Hunt / G2 / X) + WebSite (with potentialAction SearchAction pointing at /explore). This is the brand-entity signal search engines learn from.
  • Root OG imageapp/opengraph-image.tsx from the 8.3.1 OG template (brand mark + tagline). None exists today.
  • app/sitemap.tsNEW in this repo. motir-core's is not shared and its URLs are the app's, not the marketing site's. It must serve at https://motir.co/sitemap.xml, which is what the submission criterion below reads.
  • app/robots.ts — FLIP IT, do not create it. MOTIR-1455 already shipped this file with disallow: /, deliberately: its deploy is a one-page placeholder and a thin "coming soon" indexed at the apex is worse than nothing. Its own comment names this card as the one that flips it. So: allow crawl, point at the sitemap, and verify the deployed https://motir.co/robots.txt no longer disallows — the file changing in the repo is not the same as the change being live.
  • Search Console verification wiring — add verification.google to root metadata, reading the token from env (set in 8.3.8); document the env var. ⚠️ The Domain property is already DNS-verified via the apex TXT (8.3.8), so this meta tag is belt-and-braces, not the verification path — and it is NOT a licence to touch the apex TXT set (MOTIR-2596 + MOTIR-1155 both write there).
  • Submit the sitemap — MOVED HERE FROM MOTIR-1455 on 2026-08-28, because that card ships an empty scaffold and this one ships the file. The deferred tail of MOTIR-1155: in Search Console → Sitemaps, add https://motir.co/sitemap.xml. The Domain property for motir.co already exists, is DNS-verified, and already covers this host — there is no property to set up, no new verification and no token. Expect a transient "Couldn't fetch" for a few minutes before it settles to Success; verify with a Googlebot-UA fetch before treating that as a fault. ⚠️ This one step is console work, not code — the agent ships the file and the PR; the submission is the human's at close-out, exactly as 8.3.8's property setup was.

blocked_by 8.3.1 (the OG image + Organization logo need the mark), 8.3.6 (the landing this decorates) and 8.3.10 (the repo, the deploy and the domain — including the two DNS records, without which nothing serves at motir.co and neither criterion below is measurable).

Acceptance criteria

  • RootJsonLd emits Organization + WebSite (with SearchAction + sameAs); injected site-wide; JSON.stringify, no user-controlled keys.
  • app/opengraph-image.tsx renders the root social card from the brand template.
  • app/sitemap.ts exists in motir-marketing and https://motir.co/sitemap.xml serves it, read from the deployed site rather than from the repo.
  • app/robots.ts allows crawl and references the sitemap, and https://motir.co/robots.txt no longer carries MOTIR-1455's disallow: / — read live, not from the file.
  • Root metadata verification.google reads from env (documented); no secret hardcoded.
  • https://motir.co/sitemap.xml is submitted to the existing verified Search Console Domain property and reports Success. No new property, no new verification. (Moved from MOTIR-1455, 2026-08-28.)
  • The apex TXT set is untoucheddig motir.co TXT still returns exactly ONE v=spf1 and MOTIR-1155's google-site-verification= record.
  • Build + CI green; structured data validates (schema.org shapes).

Context refs

  • blocked_by 8.3.1 (brand mark for OG + Organization logo) — set blocked
  • ALREADY SHIPPED in motir-core (don't redo there; NOT present in motir-marketing): app/(public)/_components/PublicProjectJsonLd.tsx, app/(public)/explore/_components/ExploreJsonLd.tsx, app/sitemap.ts, section opengraph-image.tsx
  • app/layout.tsx in motir-marketing (root metadata + injection point) — created by MOTIR-1455's scaffold
  • app/robots.ts in motir-marketing — exists, disallow: /, this card flips it
  • depends-on 8.3.8 for the actual GSC token value, and for the Domain property this card's sitemap is submitted into
  • motir-core/docs/decisions/marketing-site-hosting.md §7 — what this decision changes for this card (nothing in substance) and what it hands to MOTIR-1455