Skip to content

Add four topics, fix lint and link graph, prepare for open source - #28

Merged
tornike14 merged 11 commits into
mainfrom
develop
Aug 15, 2026
Merged

Add four topics, fix lint and link graph, prepare for open source#28
tornike14 merged 11 commits into
mainfrom
develop

Conversation

@tornike14

Copy link
Copy Markdown
Owner

Brings main up to date with 11 commits of work. Until now the public default branch and the live site have both been serving an older version of the project.

Content

Four new topics, taking the total to 28 (17 JavaScript, 11 React):

  • Event Delegation — capture/target/bubble phases, stopPropagation, the one-parent-handler pattern
  • Modules & Imports — module graph construction, live bindings, circular dependency handling
  • Error Boundaries — error propagation, getDerivedStateFromError, nested boundaries, recovery
  • useEffect Lifecycle — render/commit/paint/effect timeline, dependency comparison, cleanup timing

Topic pages were also consolidated: theory now renders beneath the visualization on the topic route instead of at a separate /theory URL.

Fixes

  • ComponentTreeDiagram called setState synchronously inside a layout effect, failing react-hooks/set-state-in-effect and leaving lint red. Height now writes straight to the DOM. Verified in the browser against the previous implementation: identical scale factor and viewport height, one fewer render pass.
  • The reconciliation theory page listed only two related topics, both unrelated JavaScript ones. Replaced with five React topics.
  • Four topics had no inbound links from any theory page. Each now has two.
  • Docs still described the deleted /theory routes and the renamed TheoryArticle, so a contributor following them would have built a route that no longer exists.

Open source readiness

  • README rewritten, plus a homepage screenshot and a badge row
  • CONTRIBUTING.md documenting all eight registries a new topic touches
  • CI running lint, build, and a registry integrity check on every push and PR
  • scripts/check-registries.mjs, which catches registry desync that TypeScript cannot, since each registry is independently valid on its own
  • Issue templates, PR template, SECURITY.md, CODE_OF_CONDUCT.md, .env.example
  • Removed a stray worktree gitlink that made fresh clones report a phantom submodule

Verification

npm run verify passes: lint clean, 28 topics registered across all eight registries, production build green at 68 static pages.

…ect Lifecycle topics

Four new topics, two JavaScript and two React, each with a step-by-step
visualization and a full theory page.

- Event Delegation (beginner): capture/target/bubble phases, stopPropagation,
  and the one-parent-handler delegation pattern
- Modules & Imports (intermediate): module graph construction, live bindings,
  and circular dependency handling
- Error Boundaries (intermediate): error propagation up the tree,
  getDerivedStateFromError, nested boundaries, and recovery
- useEffect Lifecycle (beginner): render/commit/paint/effect timeline,
  dependency comparison, and cleanup timing

Registered across all eight registries: topic registry, routes, visualization
components, theory content, theory registry, keyword and description maps, and
the selector toolbar set.
ComponentTreeDiagram called setState synchronously inside a layout effect,
which fails the react-hooks/set-state-in-effect rule and left the repo with a
red lint run. Measuring already happens in a layout effect, so the height now
writes straight to the DOM node instead of routing through state. Verified in
the browser: identical scale factor and viewport height to the previous
implementation, with one fewer render pass per measurement.

The reconciliation theory page listed only two related topics, both of them
JavaScript topics unrelated to reconciliation. Replaced with five React topics.

Four topics had no inbound links from any theory page, leaving them dead ends
for readers and for search. Each now has two, added by swapping out the
weakest link where a list was already at the five-entry maximum.
The code and the authoring docs were already in good shape. What was missing
was everything a contributor needs before they can make their first change.

- README rewritten. It listed 7 JavaScript routes and described React as
  "coming soon" while 28 topics and 11 React visualizations were shipping.
- CONTRIBUTING.md added. Adding a topic touches eight registries, and missing
  one produces a page that half works, so each is listed with its file path.
- CI workflow runs lint, build, and a registry integrity check on every push
  and pull request.
- scripts/check-registries.mjs verifies that every topic is registered in all
  eight places, that relatedTopicIds hold 3 to 5 valid non-self IDs, that no
  topic is left without inbound links, that ExampleSelector topics appear in
  the toolbar set, and that no em dash reaches user-facing content. TypeScript
  cannot catch these because each registry is independently valid on its own.
- Issue templates for bugs, content corrections, and topic requests, plus a
  pull request template carrying the eight-registry checklist.
- SECURITY.md and CODE_OF_CONDUCT.md added.
- .env.example documents the three NEXT_PUBLIC_ variables, which matters for
  forks since two of them default to the maintainer's own links.
- package.json gains description, license, repository, engines, and the
  check:registries and verify scripts.

Also removes a stray worktree directory that was committed by accident as a
gitlink with no .gitmodules entry, which made fresh clones report a phantom
submodule. Local editor and tooling state is now ignored.
The Analytics and Speed Insights scripts are served from
va.vercel-scripts.com in development, which script-src blocked, so
neither one loaded locally. Add the host to script-src.

connect-src is unchanged: beacons always post same-origin under
/_vercel, and development sends none at all.
Google indexed only 28 of 60 known URLs (14 "crawled, currently not
indexed"), and the split between /topic and /topic/theory was splitting
signals across two thin URLs per concept. GSC showed Google picking
inconsistently between the pair: heap-stack ranked the theory page,
execution-context ranked the visualization page.

Merge theory content into the visualization page, one URL per topic:

- Render theory sections below the visualization via TopicTheorySections
- 308 redirect /javascript/:topic/theory and /react/:topic/theory to the
  topic page via next.config redirects
- Delete the [topic]/theory routes and TheoryArticle
- Section headings now carry concept keywords ("What is X in JavaScript?"
  instead of "What it is")
- Related topics link to topic pages instead of theory pages

Replace the homepage soft redirect with real content:

- / served 200 with a meta refresh, which Google classified as a
  redirect, wasting the strongest URL on the domain
- New HomeLandingPage targets the "javascript visualizer" query cluster
  and links all 28 topics
- Add / to the sitemap, drop the removed theory routes

Metadata and structured data:

- Topic titles lead with the concept: "X in JavaScript, Visualized"
- Topic descriptions use the richer theory copy
- Render topic.description as visible text (it was metadata-only)
- Drop FAQPage schema, which has earned no rich results since Google
  restricted FAQ results in 2023
- Add Person author to TechArticle
- Category descriptions derive their topic counts from the registry

Deepen heap-stack theory, the closest near-miss to page one at position
16.1 with 318 impressions.

All 31 sitemap URLs now have one h1, a correct self-canonical, a meta
description, and over 300 words. Average page weight went from roughly
150 words to 787.
Link audit found two holes that page-level SEO work does not fix:

- No page linked to the homepage. The sidebar logo pointed at the
  active category route, so the new landing page had zero inbound
  internal links and was reachable only from the sitemap.
- The JavaScript and React halves of the site were disconnected. The
  category switcher is a button with onClick, not a link, and the
  sidebar only renders the active category, so /javascript/closures
  had 18 internal links and none of them reached React.

Point the sidebar logo at / and add a crawlable link to the opposite
category in the sidebar footer.

Every page now links to the homepage and to both category hubs.
.claude/worktrees holds full checkouts of the repo, including their own
.next build output. ESLint walked into them and reported 2293 problems
from code that is not part of this working tree, so `npm run lint`
failed whenever a worktree existed on disk.

The directory is already gitignored. Ignore it in ESLint too.
Theory now renders on the topic page instead of a separate /theory route, but
the docs still described the old structure. A contributor following them would
have created a route that no longer exists.

- README and CONTRIBUTING no longer promise a page at <route>/theory
- theory-authoring.md points at TopicTheorySections rather than the deleted
  TheoryArticle, and drops the claim that a theory URL is statically generated
- topic-authoring.md removes the deleted [topic]/theory entries from its tree
- seo.md corrects the sitemap description, since theory content now shares its
  topic's URL and needs no separate entry
The project is entirely visual, and the README described it in prose with no
image. Anyone landing on the repo had to clone and run it to see what it does.

Captured from a production build rather than the dev server, so the Next.js
dev indicator does not appear. Stored as JPEG at 1600px wide, which is 448KB
against 1.25MB for the equivalent PNG with no visible quality loss on the dark
gradients. The image links through to the live site.
A naked visualizejs.com link sitting between two paragraphs gave the most
important link in the project the least visual weight.

Seven badges on a single line: live site, CI status, topic count, Next.js,
React, TypeScript, and license. CI and license read their values live from the
repository rather than being hardcoded.

Two details that matter for how this renders:

- All badges go on one markdown line. GitHub turns single newlines into line
  breaks, so one badge per line stacks them vertically down the page.
- The badges sit above the screenshot rather than below it. The screenshot is
  1600x1000, tall enough to push anything under it past the fold.

The CI badge tracks develop, since main does not carry the workflow yet and
renders "no status" there. Point it at main once develop is merged.
The workflow now lives on main, so the badge tracks the default branch instead
of develop.
@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
visualizejs Ready Ready Preview Aug 15, 2026 9:56pm

@tornike14
tornike14 merged commit 080fc7c into main Aug 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant