Skip to content

feat(search): ✨ Add popular and suggest routes with popularity tracking - #877

Merged
aXenDeveloper merged 4 commits into
claude/community-forumfrom
feat(search)--✨-Add-popular-and-suggest-routes-with-popularity-tracking
Oct 14, 2026

Hidden character warning

The head ref may contain hidden characters: "feat(search)--\u2728-Add-popular-and-suggest-routes-with-popularity-tracking"
Merged

aXenDeveloper merged 4 commits into
claude/community-forumfrom
feat(search)--✨-Add-popular-and-suggest-routes-with-popularity-tracking

Conversation

@aXenDeveloper

Copy link
Copy Markdown
Owner

Improving Documentation

Description

What?

Why?

@github-actions github-actions Bot added the 💡 Feature A new feature label Oct 14, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T19:10:00.382018Z d83ede0 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

React Doctor found 9 new issues in 4 files · 9 warnings · score 86 / 100 (Great) · 5 fixed · vs canary

9 warnings

scripts/prepare-database.ts

  • ⚠️ L69 await inside a loop async-await-in-loop
  • ⚠️ L845 await inside a loop async-await-in-loop

src/docs/search-source.ts

  • ⚠️ L43 Accumulator spread in reduce is quadratic no-spread-accumulator-in-reduce

src/tanstack/search/header-search-content.tsx

  • ⚠️ L300 Large component is hard to read and change no-giant-component
  • ⚠️ L300 React function has high control-flow complexity no-high-complexity-react-function
  • ⚠️ L516 Enter submit without IME composition guard no-enter-submit-without-ime-composition-guard
  • ⚠️ L525 Autofocus on an element no-autofocus

src/tanstack/search/header-search.tsx

  • ⚠️ L73 useEffect state synchronization flashes after paint rendering-hydration-no-flicker
  • ⚠️ L129 Raw control directly inside InputGroup shadcn-input-group-no-raw-controls

Reviewed by React Doctor for commit d83ede0. See inline comments for fixes.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f42c95a2c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +233 to +237
const suggestions = useQuery({
...searchSuggestQueryOptions({ locale, term: trimmedTerm }),
enabled: canSuggest,
placeholderData: canSuggest ? keepPreviousData : undefined,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prevent stale suggestions from remaining selectable

When the user changes one valid query to another, the debounced term still contains the previous query for 150 ms, and keepPreviousData continues exposing the previous results while the next request runs. Because entries and the Enter/click handlers remain active, typing a new term and immediately pressing Enter can open an unrelated result from the old term. Gate the displayed/selectable entries on the debounced term matching the current trimmed query, or disable selection while the query data is placeholder/stale.

Useful? React with 👍 / 👎.

- Introduced a new search source for external documentation, allowing results from Fumadocs to appear in the header search dialog.
- Implemented `docsSearchSource` to fetch and display documentation results based on user input.
- Enhanced the search dialog to include a dedicated group for documentation results, improving user experience.
- Added a sidebar toggle component for better navigation within the documentation.
- Updated search source configuration to support multiple sources and improved query handling.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 72d1835c18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +485 to +487
if (await this.isListed(doc.itemType, contentIdKey(doc.itemId))) {
return null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track comment counting independently of public visibility

When an existing public comment is hidden or unpublished, its index row remains but isListed returns false because the row is no longer public. Restoring, unhiding, or republishing that comment therefore makes newCommentParent treat it as new and adds another weight-5 comment signal to the parent; repeating the visibility transition can indefinitely inflate the parent's popularity. Record whether the child has already contributed a comment signal independently of its current public state.

Useful? React with 👍 / 👎.

Comment on lines +176 to +180
.orderBy(
desc(core_search_popularity.logScore),
sql`${core_search_index.languageCode} = ${requestedLanguage} DESC`,
)
.limit(limit * POPULAR_CANDIDATES_PER_SLOT);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Deduplicate translations before limiting popular items

When /popular is called without lang—which the new route explicitly permits—the join returns every translation of each item, but this limit is applied before the JavaScript deduplication below. A highly ranked item with many translations can consume most or all of limit * 3, causing the endpoint to return far fewer unique items than requested even when enough popular items exist. Select one preferred row per (itemType, itemId) in SQL before applying the requested limit.

Useful? React with 👍 / 👎.

@aXenDeveloper
aXenDeveloper added this pull request to stack #878 October 14, 2026 18:51

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b54e38a308

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


`variant="bar"` turns the floating header card into a flat, full-width bar that sits flush on the docs layout, and `--fd-banner-height` tells Fumadocs how tall it is, so its sidebar and page fit underneath. Need a button before the logo, like a sidebar toggle? Pass it as `leading`. Load the header's data in the docs route too, with `loadMainShell(context)` in its `loader`.

Got a layout with its own search button? `SearchDialog` from `@vitnode/core/tanstack/search` is the header dialog without its trigger. Give it `open`, `onOpenChange` and the same `firstSourceId`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Export the documented standalone search dialog

Consumers following this new guidance cannot import or render SearchDialog: a repo-wide search finds only the exported HeaderSearch, whose API accepts firstSourceId but not the documented open or onOpenChange props. Either implement and export the standalone dialog from @vitnode/core/tanstack/search or remove this unsupported integration path from the documentation.

Useful? React with 👍 / 👎.


const groupByPage = (results: DocsSearchResult[]): DocsPageHit[] =>
results.reduce<DocsPageHit[]>((pages, result) => {
if (result.type === 'page') return [...pages, { page: result }]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-spread-accumulator-in-reduce (warning)

This is O(n²) because spreading the accumulator copies the entire growing collection every step. Mutate and return the accumulator instead (acc[key] = value; return acc).

Fix → Mutate the accumulator and return it (acc[key] = value; return acc) so the fold stays O(n) instead of copying the whole accumulator every step.

Docs

);
};

const HeaderSearchMorph = ({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-giant-component (warning)

Component "HeaderSearchMorph" is over 300 lines long, which is hard to read & change. Split it into a few smaller components.

Fix → Pull each section into its own component so the parent is easier to read, test, and change.

Docs

);
};

const HeaderSearchMorph = ({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-high-complexity-react-function (warning)

HeaderSearchMorph has cyclomatic complexity 37, cognitive complexity 33, and maximum nesting depth 3, so its React logic is hard to understand and change. Extract independent branches into components or hooks.

Fix → Extract independent render branches and state logic into focused components or hooks until the control flow is easy to follow.

Docs

<span className="invisible">{query}</span>
<span className="text-muted-foreground/50">{ghost}</span>
</span>
<input

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-enter-submit-without-ime-composition-guard (warning)

This text-entry Enter handler commits/submits without bailing on IME composition, so it fires mid-composition for CJK users pressing Enter to confirm a candidate. Bail first with if (e.nativeEvent.isComposing) return; (or track onCompositionStart/onCompositionEnd) before acting on Enter.

Fix → Bail on IME composition before acting on Enter: if (e.nativeEvent.isComposing) return; (or track composition with onCompositionStart/onCompositionEnd). Otherwise Enter fires mid-composition and commits a half-typed value for CJK users.

Docs

aria-expanded={expanded}
aria-label={t("dialog.label")}
autoComplete="off"
autoFocus

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-autofocus (warning)

autoFocus moves focus on load, which can disrupt screen reader and keyboard users. Remove it and let users choose where to focus.

Fix → Do not use autoFocus. It disorients users on load.

Docs

const pendingHrefRef = React.useRef<null | string>(null);
const [isApple, setIsApple] = React.useState<boolean | undefined>(undefined);

React.useEffect(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/rendering-hydration-no-flicker (warning)

useEffect(setState, []) runs after the first paint, so users can see the initial state flash. Initialize from a render-safe value or use useSyncExternalStore for external values.

Fix → Initialize state from a render-safe value before the first paint, or read external mutable values with useSyncExternalStore.

Docs

onClick={() => setOpen(true)}
onPointerEnter={handlePrefetch}
>
<button

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/shadcn-input-group-no-raw-controls (warning)

This button sits directly inside InputGroup, so it keeps its own border and focus ring and the group's shared focus and error styling never applies. Use InputGroupButton inside an InputGroupAddon instead.

Fix → Compose InputGroup from its own parts (InputGroupInput, InputGroupTextarea, and InputGroupAddon with InputGroupButton) so the group owns one border, focus ring, and error state.

Docs

@aXenDeveloper
aXenDeveloper merged commit 695535a into canary Oct 14, 2026
5 checks passed
@aXenDeveloper
aXenDeveloper deleted the feat(search)--✨-Add-popular-and-suggest-routes-with-popularity-tracking branch October 14, 2026 19:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d83ede05b0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +16 to +17
if (url.href !== window.location.href) {
window.history.replaceState(window.history.state, "", url);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the router synchronized with the edited search term

When a user edits the term on /search, this native replaceState updates the address bar without notifying TanStack Router, so router.latestLocation retains the original query. A subsequent action that derives its destination from router state—such as useSwitchLocale, whose planFor reads router.latestLocation.href—therefore restores the old term or drops the newly edited one. Update the URL through the router history API so the visible URL and router state remain consistent.

Useful? React with 👍 / 👎.

Comment on lines +169 to +170
const resolved = typeof next === "function" ? next(theme) : next;
setThemeState(resolved);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve queued functional theme updates

When callers invoke setTheme with functional updates more than once before React re-renders, every updater is now evaluated against the same captured theme value rather than the latest queued state. This violates the exported React.SetStateAction contract—for example, two synchronous toggle updaters apply only one toggle and persist that incorrect result to local storage. Resolve functional actions through the real state updater, while moving persistence to a mechanism that does not rely on a stale closure.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💡 Feature A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant