Custom Hooks
Relevant source files
The following files were used as context for generating this wiki page:
The railways-docs project utilizes several custom React hooks to encapsulate and reuse stateful logic across different components. These hooks are central to implementing features such as UI interactions, third-party analytics integration, and client-side routing enhancements. They help maintain a clean and modular codebase by abstracting complex logic away from the UI components.
All application-level hooks are initialized in src/pages/_app.tsx to provide global functionality throughout the documentation site.
Hooks Summary
| Hook | Purpose | Key Consumers |
|---|---|---|
useCopy | Manages state for copying text to the clipboard. | DocsLayout, CodeBlock |
useScrollToOpenCollapse | Opens collapsed content when a user navigates to an anchor within it. | _app.tsx (Global) |
useHashRedirect | Handles client-side redirects based on URL hash. | _app.tsx (Global) |
useIsMounted | Tracks if a component is mounted to prevent state updates on unmounted components. | CodeBlock |
useFathom | Integrates Fathom analytics for page view tracking. | _app.tsx (Global) |
usePostHog | Integrates PostHog analytics for event and page view tracking. | _app.tsx (Global) |
useDebouncedSearch | Debounces user input for search functionality. | Search Component |
UI Interaction Hooks
These hooks are responsible for managing user interface state and interactions.
useCopy
This hook provides a mechanism to copy text to the clipboard and provides feedback to the user by tracking a copied state.
Return Value
| Type | Name | Description |
|---|---|---|
boolean | copied | true if the text was recently copied; automatically resets to false. |
function | copy | A function that takes a string to copy to the clipboard. |
Usage
The hook is used in two primary locations:
DocsLayout.tsx: To power the "Copy as Markdown" button.CodeBlock/index.tsx: To provide a copy button for code snippets.
Sources: src/hooks/useCopy.ts, src/layouts/DocsLayout.tsx:80-87, src/components/CodeBlock/index.tsx:138-145
The following diagram illustrates the sequence of events when the useCopy hook is utilized.
useScrollToOpenCollapse
This global hook enhances user experience by automatically expanding any <Collapse> component that contains a target URL hash. When a user clicks a link like .../page#my-anchor, if #my-anchor is inside a collapsed section, this hook will programmatically click the collapse trigger to reveal the content.
It listens for hashchange and popstate events to trigger its logic.
Sources: src/hooks/useScrollToOpenCollapse.ts, src/pages/_app.tsx:19
The logic flow is as follows:
useHashRedirect
This hook performs client-side redirects for a predefined set of legacy URL hashes. It checks the window.location.hash on initial mount and, if it matches a key in its internal redirects map, it uses the Next.js router to replace the URL with the new path.
This is primarily used for maintaining backward compatibility with old links.
Sources: src/hooks/useHashRedirect.ts, src/pages/_app.tsx:21
useIsMounted
A utility hook that returns true once the component has mounted on the client. This is crucial for avoiding hydration errors and preventing state updates on unmounted components. It is used within the CodeBlock component to safely determine the current color theme (light or dark) for syntax highlighting, as the theme is client-side dependent.
Sources: src/hooks/useIsMounted.ts, src/components/CodeBlock/index.tsx:129-133
Analytics Hooks
These hooks abstract the integration of third-party analytics services. They are both initialized globally in _app.tsx.
Sources: src/pages/_app.tsx:11-17
useFathom
This hook integrates Fathom Analytics. It initializes the Fathom client with a tracking code and site URL. It then subscribes to the Next.js router's routeChangeComplete event to automatically track page views whenever the user navigates to a new page.
Sources: src/hooks/useFathom.ts
usePostHog
Similarly, this hook integrates PostHog analytics. It initializes the PostHog client and uses the routeChangeComplete router event to capture page views, ensuring user navigation is tracked.
Sources: src/hooks/usePostHog.ts
The following diagram shows the lifecycle for both analytics hooks.
Data Handling Hooks
useDebouncedSearch
This hook is designed to manage search input by debouncing the value. It prevents the search function from being called on every keystroke, instead waiting until the user has paused typing for a specified delay.
Parameters
| Name | Type | Description |
|---|---|---|
search | (searchTerm: string) => void | The function to execute with the debounced search term. |
delay | number | The debounce delay in milliseconds. |
Return Value
| Type | Name | Description |
|---|---|---|
string | searchTerm | The current value of the search input. |
function | setSearchTerm | The state setter for the search term. |
Sources: src/hooks/useDebouncedSearch.ts
The debouncing logic is illustrated below: