Jack Hsu 9dca7c7025
docs(core): add scroll_25, scroll_50, scroll_75, and scroll_90 events to track engagement (#27461)
This PR adds events to track engagement in our docs. Since we use a
scrollable `<div>` in our docs, the normal `scroll` events in GA do not
work.

A new `<ScrollableContent>` component is added that will do two things:
- Send `scroll_25`, `scroll_50`, `scroll_75`, and `scroll_90` events
whenever the user scrolls to 25%, 50%, 75%, of 90% of the content
- Optionally reset scroll top to zero whenever router changes (existing
behavior)

All of the places where we have content in a scrollable `<div>` is
replaced with `<ScrollableContent>`.

Note: 90% means user has reached the bottom, since it's not usually
possible to get to 100%.
2024-08-16 12:25:20 -04:00

125 lines
3.6 KiB
TypeScript

import { DocumentsApi } from '@nx/nx-dev/data-access-documents/node-only';
import { getPackagesSections } from '@nx/nx-dev/data-access-menu';
import { sortCorePackagesFirst } from '@nx/nx-dev/data-access-packages';
import { DocViewer } from '@nx/nx-dev/feature-doc-viewer';
import { ProcessedDocument, RelatedDocument } from '@nx/nx-dev/models-document';
import { Menu, MenuItem, MenuSection } from '@nx/nx-dev/models-menu';
import { ProcessedPackageMetadata } from '@nx/nx-dev/models-package';
import { DocumentationHeader, SidebarContainer } from '@nx/nx-dev/ui-common';
import { GetStaticPaths } from 'next';
import { menusApi } from '../../../../lib/menus.api';
import { useNavToggle } from '../../../../lib/navigation-toggle.effect';
import { nxPackagesApi } from '../../../../lib/packages.api';
import { tagsApi } from '../../../../lib/tags.api';
import { fetchGithubStarCount } from '../../../../lib/githubStars.api';
import { ScrollableContent } from '@nx/ui-scrollable-content';
export default function PackageDocument({
document,
menu,
relatedDocuments,
widgetData,
}: {
document: ProcessedDocument;
menu: MenuItem[];
pkg: ProcessedPackageMetadata;
relatedDocuments: RelatedDocument[];
widgetData: { githubStarsCount: number };
}): JSX.Element {
const { toggleNav, navIsOpen } = useNavToggle();
const vm: {
document: ProcessedDocument;
menu: Menu;
relatedDocuments: RelatedDocument[];
} = {
document,
menu: {
sections: sortCorePackagesFirst<MenuSection>(
getPackagesSections(menu),
'id'
),
},
relatedDocuments,
};
return (
<div id="shell" className="flex h-full flex-col">
<div className="w-full flex-shrink-0">
<DocumentationHeader isNavOpen={navIsOpen} toggleNav={toggleNav} />
</div>
<main
id="main"
role="main"
className="flex h-full flex-1 overflow-y-hidden"
>
<SidebarContainer
menu={vm.menu}
navIsOpen={navIsOpen}
toggleNav={toggleNav}
/>
<ScrollableContent resetScrollOnNavigation={true}>
<DocViewer
document={vm.document}
relatedDocuments={vm.relatedDocuments}
widgetData={widgetData}
/>
</ScrollableContent>
</main>
</div>
);
}
export const getStaticPaths: GetStaticPaths = () => {
return {
paths: [
...nxPackagesApi.getStaticDocumentPaths().documents.map((x) => ({
params: {
name: x.params.segments.slice(1)[0],
segments: x.params.segments.slice(3),
},
})),
],
fallback: 'blocking',
};
};
export async function getStaticProps({
params,
}: {
params: { name: string; segments: string[] };
}) {
try {
const segments = ['nx-api', params.name, 'documents', ...params.segments];
const documents = new DocumentsApi({
id: [params.name, 'documents'].join('-'),
manifest: nxPackagesApi.getPackageDocuments(params.name),
prefix: '',
publicDocsRoot: 'public/documentation',
tagsApi,
});
const document = documents.getDocument(segments);
return {
props: {
pkg: nxPackagesApi.getPackage([params.name]),
document,
widgetData: {
githubStarsCount: await fetchGithubStarCount(),
},
relatedDocuments: tagsApi
.getAssociatedItemsFromTags(document.tags)
.filter((item) => item.path !== '/' + segments.join('/')), // Remove currently displayed item
menu: menusApi.getMenu('nx-api', ''),
},
};
} catch (e) {
return {
notFound: true,
props: {
statusCode: 404,
},
};
}
}