diff --git a/src/components/Scarf.tsx b/src/components/Scarf.tsx new file mode 100644 index 000000000..e6c5128a0 --- /dev/null +++ b/src/components/Scarf.tsx @@ -0,0 +1,18 @@ +import { useRouterState } from '@tanstack/react-router' +import { useMounted } from '~/hooks/useMounted' + +export function Scarf({ id }: { id: string }) { + const locationKey = useRouterState({ select: (s) => s.location.state.key }) + + const mounted = useMounted() + + return mounted ? ( + scarf analytics + ) : null +} diff --git a/src/libraries/libraries.ts b/src/libraries/libraries.ts index 87e1a1881..1c7982a3e 100644 --- a/src/libraries/libraries.ts +++ b/src/libraries/libraries.ts @@ -24,6 +24,7 @@ export const query: LibrarySlim = { corePackageName: '@tanstack/query-core', npmPackageNames: ['@tanstack/query-core', 'react-query'], availableVersions: ['v5', 'v4', 'v3'], + scarfId: '53afb586-3934-4624-a37a-e680c1528e17', defaultDocs: 'framework/react/overview', sitemap: { includeLandingPage: true, @@ -208,6 +209,7 @@ export const router: LibrarySlim = { latestVersion: 'v1', latestBranch: 'main', availableVersions: ['v1'], + scarfId: '3d14fff2-f326-4929-b5e1-6ecf953d24f4', docsRoot: 'docs/router', sitemap: { includeLandingPage: true, @@ -270,6 +272,7 @@ export const start: LibrarySlim = { availableVersions: ['v0'], corePackageName: '@tanstack/start-client-core', npmPackageNames: ['@tanstack/start-client-core'], + scarfId: 'b6e2134f-e805-401d-95c3-2a7765d49a3d', docsRoot: 'docs/start', defaultDocs: 'framework/react/overview', sitemap: { @@ -310,6 +313,7 @@ export const table: LibrarySlim = { latestVersion: 'v9', latestBranch: 'main', availableVersions: ['v9', 'v8'], + scarfId: 'dc8b39e1-3fe9-4f3a-8e56-d4e2cf420a9e', defaultDocs: 'overview', sitemap: { includeLandingPage: true, @@ -435,6 +439,7 @@ export const form: LibrarySlim = { latestVersion: 'v1', latestBranch: 'main', availableVersions: ['v1', 'alpha'], + scarfId: '72ec4452-5d77-427c-b44a-57515d2d83aa', sitemap: { includeLandingPage: true, includeDocsPages: true, @@ -457,6 +462,7 @@ export const virtual: LibrarySlim = { latestVersion: 'v3', latestBranch: 'main', availableVersions: ['v3'], + scarfId: '32372eb1-91e0-48e7-8df1-4808a7be6b94', defaultDocs: 'introduction', legacyPackages: ['react-virtual'], sitemap: { @@ -482,6 +488,7 @@ export const ranger: LibrarySlim = { latestVersion: 'v0', latestBranch: 'main', availableVersions: ['v0'], + scarfId: 'dd278e06-bb3f-420c-85c6-6e42d14d8f61', visible: false, sitemap: { includeLandingPage: true, @@ -514,6 +521,7 @@ export const store: LibrarySlim = { latestVersion: 'v0', latestBranch: 'main', availableVersions: ['v0'], + scarfId: '302d0fef-cb3f-43c6-b45c-f055b9745edb', defaultDocs: 'overview', sitemap: { includeLandingPage: true, @@ -539,6 +547,7 @@ export const pacer: LibrarySlim = { latestVersion: 'v0', latestBranch: 'main', availableVersions: ['v0'], + scarfId: '302d0fef-cb3f-43c6-b45c-f055b9745edb', defaultDocs: 'overview', sitemap: { includeLandingPage: true, @@ -669,6 +678,7 @@ export const db: LibrarySlim = { latestVersion: 'v0', latestBranch: 'main', availableVersions: ['v0'], + scarfId: '302d0fef-cb3f-43c6-b45c-f055b9745edb', defaultDocs: 'overview', sitemap: { includeLandingPage: true, diff --git a/src/libraries/types.ts b/src/libraries/types.ts index 292f34580..4af16e416 100644 --- a/src/libraries/types.ts +++ b/src/libraries/types.ts @@ -44,6 +44,7 @@ export type LibrarySlim = { latestVersion: string latestBranch?: string availableVersions: string[] + scarfId?: string defaultDocs?: string docsRoot?: string hideCodesandboxUrl?: true diff --git a/src/routes/_library/$libraryId/route.tsx b/src/routes/_library/$libraryId/route.tsx index b8831c78b..5f0202edd 100644 --- a/src/routes/_library/$libraryId/route.tsx +++ b/src/routes/_library/$libraryId/route.tsx @@ -1,5 +1,6 @@ import { createFileRoute } from '@tanstack/react-router' import { notFound, Outlet } from '@tanstack/react-router' +import { Scarf } from '~/components/Scarf' import { findLibrary, LibraryId } from '~/libraries' import { seo } from '~/utils/seo' import { ogImageUrl } from '~/utils/og' @@ -64,5 +65,10 @@ function RouteForm() { return null } - return + return ( + <> + + {library?.scarfId ? : null} + + ) } diff --git a/tests/static-data-contracts.test.ts b/tests/static-data-contracts.test.ts index b9ad8f573..ff0633a38 100644 --- a/tests/static-data-contracts.test.ts +++ b/tests/static-data-contracts.test.ts @@ -7,6 +7,9 @@ import { publicLibraries, } from '../src/libraries/libraries' +const uuidPattern = + /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i + assert.deepEqual( publicLibraries, libraries.filter(isPublicLibrary), @@ -37,6 +40,18 @@ for (const library of publicLibraries) { ) } +for (const library of libraries) { + if (!library.scarfId) { + continue + } + + assert.match( + library.scarfId, + uuidPattern, + `${library.id} scarfId must be a UUID`, + ) +} + for (const maintainer of allMaintainers) { const socialEntries = Object.entries(maintainer.social ?? {})