Curated watch orders for film and TV franchises. Release order or in-universe chronology, an essentials-only path, and local watch tracking — starting with the MCU and DC, built to take any franchise.
Next.js (App Router) · TypeScript · Tailwind v4 · Radix · Framer Motion.
No API, no database, no images. Every fact the site renders lives in a
TypeScript file under content/. The build makes zero network calls, so it is
reproducible offline and every data change shows up in a diff.
npm install
npm run dev # http://localhost:3000
| script | does |
|---|---|
npm run dev |
dev server |
npm run build |
production build (fully static) |
npm run typecheck |
tsc --noEmit |
content/franchises/*.ts the data — one file per franchise, hand-curated
content/guides.ts long-form SEO landing pages
lib/types.ts the schema
lib/franchises.ts registry + resolution (server — pulls in all content)
lib/ordering.ts sort/filter/group/format (pure — safe for the client)
app/[franchise]/ hub page and per-title pages
The split between lib/franchises.ts and lib/ordering.ts is deliberate. The
hub UI is a client component; if it imported the registry it would drag every
franchise’s dataset into the browser bundle. It receives resolved data as props
and uses lib/ordering instead.
content/franchises/<slug>.ts.FRANCHISES in lib/franchises.ts.That’s it. Routing, the sitemap, the home page, nav and footer all read from that array.
Open the franchise file and edit the array. Two fields are worth understanding:
chronOrder is spaced in steps of 10 on purpose. Only relative order
matters, so the gaps let you slot a new title between two existing ones (give
it 315) without renumbering the file.eras are keyed by the startId of the title that opens the era, not by
a chronOrder range — so era boundaries survive any renumbering.runtime is optional and currently unset on every entry. Fill it in and it
appears on the detail page, in the quick view, and as duration in the page’s
JSON-LD. Leave it off and none of that renders — omit rather than guess.
There is no poster art anywhere, by design. The position numeral carries the visual weight instead: set large in the display face, tinted with the group colour, and echoed as an oversized watermark behind the card and hero text. Franchise and group identity come from colour rails and accents, not imagery — which also means every page is text-only and renders instantly.
Each franchise sets theme.accent / accent2 / glow. <FranchiseTheme>
writes those to CSS custom properties on a wrapper; buttons, gradients, focus
rings and the ambient page glow all read the same variables. One wrapper
repaints the whole identity — there are no per-franchise conditionals in
components.
metadataBase from
NEXT_PUBLIC_SITE_URL (defaults to https://watchinorder.in).Movie/TVSeries on detail pages, ItemList on hubs and guides,
BreadcrumbList everywhere, FAQPage on guides, WebSite site-wide.
Deliberately no aggregateRating — Schema.org requires ratingCount
alongside it and we don’t store one, so emitting it would be invalid markup.sitemap.xml and robots.txt are generated from the data.<Link>
navigation, never a replacement for it./guides/*) are the traffic play — they target the actual search
phrases and embed the live ordered list, so prose and data can’t drift apart.prefers-reduced-motion is respected globally in CSS and per-component via
Framer Motion’s useReducedMotion. Dialogs and toggles are Radix primitives.
There’s a skip link, breadcrumbs, and keyboard nav in the quick view
(← → to step, Esc to close).
Read content/GAPS.md. Current as of 3 August 2026:
112 titles, including announced releases through December 2026. Release dates
are sourced; needsCheck now flags only uncertain phase labels, and the
chronological orderings are opinion in places. That file records all of it.
Titles with a future releaseDate are marked upcoming automatically at build
time — they appear in the lists but are excluded from watch-progress totals.
Rebuilding is what rolls them over as they release.
legacy/ holds the original zero-build static MCU site this grew out of. Kept for reference — its interaction patterns (order toggle, sticky section headers with per-group progress, cursor tilt, scroll reveal) were ported rather than reinvented. Nothing in the app imports from it.