mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-10-03 20:20:35 +00:00
Fix search results linking to section anchors on title matches (RND-11916)
Use the API `resultType` on page search results to decide the link target: page/title-level matches link to the top of the page, while section-level matches keep their section anchor. The section snippet is still shown as a preview. `resultType` is read defensively since it is not yet present in the published `@gitbook/api` types. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Search results from a page/title-level match now link to the top of the page instead of a section anchor; only section-level matches deep-link to their section.
|
||||
+7
@@ -143,6 +143,12 @@ function transformSitePageResult(args: {
|
||||
? toEmbeddableLinkForPublishedContent(linker, spaceURL, pageItem.path)
|
||||
: linker.toLinkForContent(joinPathWithBaseURL(spaceURL, pageItem.path));
|
||||
|
||||
// `resultType` marks whether the API matched the page at the title/page level or on a
|
||||
// specific section. It is read defensively because it is not yet in the published
|
||||
// `@gitbook/api` types; once present, page-level matches link to the top of the page.
|
||||
const resultType = (pageItem as SearchPageResult & { resultType?: 'page' | 'section' })
|
||||
.resultType;
|
||||
|
||||
const page: ComputedPageResult = {
|
||||
type: 'page',
|
||||
id: `${spaceItem.id}/${pageItem.id}`,
|
||||
@@ -151,6 +157,7 @@ function transformSitePageResult(args: {
|
||||
pageId: pageItem.id,
|
||||
spaceId: spaceItem.id,
|
||||
score: pageItem.score,
|
||||
resultType,
|
||||
breadcrumbs,
|
||||
};
|
||||
|
||||
|
||||
@@ -26,9 +26,15 @@ export const SearchPageResultItem = React.forwardRef(function SearchPageResultIt
|
||||
const language = useLanguage();
|
||||
|
||||
const bestSection = item.type === 'page' ? item.bestSection : undefined;
|
||||
// When the section snippet is displayed, link to the section anchor so the
|
||||
// link matches what the user sees.
|
||||
const href = bestSection?.body ? bestSection.href : 'href' in item ? item.href : item.pathname;
|
||||
// Section-level matches deep-link to their section anchor; page/title-level matches
|
||||
// link to the top of the page even when a section snippet is shown as a preview.
|
||||
const isPageLevelMatch = item.type === 'page' && item.resultType === 'page';
|
||||
const href =
|
||||
bestSection?.body && !isPageLevelMatch
|
||||
? bestSection.href
|
||||
: 'href' in item
|
||||
? item.href
|
||||
: item.pathname;
|
||||
|
||||
const emoji = 'emoji' in item ? item.emoji : undefined;
|
||||
const icon = 'icon' in item ? item.icon : undefined;
|
||||
|
||||
@@ -20,6 +20,13 @@ export type ComputedPageResult = BaseComputedResult & {
|
||||
type: 'page';
|
||||
pageId: string;
|
||||
spaceId: string;
|
||||
/**
|
||||
* Whether the API matched this result at the page/title level or on a specific
|
||||
* section. Page-level matches link to the top of the page; section-level matches
|
||||
* keep the section anchor. Optional to stay backward-compatible with API responses
|
||||
* that do not yet return it.
|
||||
*/
|
||||
resultType?: 'page' | 'section';
|
||||
breadcrumbs?: Array<{ icon?: IconName; label: string }>;
|
||||
/** The highest-scoring section for this page, used as a body snippet preview. */
|
||||
bestSection?: {
|
||||
|
||||
Reference in New Issue
Block a user