A context provider and hook that automatically scrolls to elements matching the URL hash.
The AutoScrollToHash
provider component automatically scrolls to the element identified by the current URL hash (e.g., #subscription
). It wraps your app and provides a context that enables the useAutoScrollToHash
hook to programmatically trigger scrolling.
The scroll behavior respects user motion preferences, using smooth scrolling by default but switching to instant scrolling for users who prefer reduced motion.
Wrap your app with the provider (typically in your root layout):
Section 1
This section can be linked with #section-1
Section 2
This section can be linked with #section-2
Section 3
This section can be linked with #section-3
import { AutoScrollToHash } from "@ngrok/mantle/auto-scroll-to-hash";
function App() {
return (
<Router>
<AutoScrollToHash>
{/* Your page content */}
</AutoScrollToHash>
</Router>
);
}
Use the hook to programmatically trigger scrolling after asynchronous content loads:
import { useAutoScrollToHash } from "@ngrok/mantle/auto-scroll-to-hash";
function DetailsTab({ ready }: { ready: boolean }) {
const reScroll = useAutoScrollToHash();
useEffect(() => {
if (ready) {
reScroll();
}
}, [ready, reScroll]);
return <div id="subscription">...</div>;
}
API Reference
AutoScrollToHash
A context provider component that automatically scrolls to the element matching the current URL hash. Must wrap your application to enable the useAutoScrollToHash
hook.
This component accepts a single prop:
useAutoScrollToHash
A hook that returns a stable callback for programmatically triggering the hash-based scroll. Use this when the target element is rendered asynchronously (e.g., after lazy-loading, tab switching, or fetching data). Must be used within an AutoScrollToHash
provider.
Returns: A stable () => void
function that scrolls the hash target into view if present.
Throws: An error if used outside an AutoScrollToHash
provider.
Behavior
- Runs on mount and whenever the URL hash changes
- Schedules scrolling in
requestAnimationFrame
to ensure the target element exists after DOM updates - Respects user motion preferences (uses
"auto"
scroll behavior when reduced motion is enabled,"smooth"
otherwise) - Safe for SSR via
useIsomorphicLayoutEffect
- Attempts both raw and URL-decoded hash IDs for robustness
Notes
Dependencies: This component and hook require react-router
as a peer dependency. Make sure to install it in your project.
If your content is loaded asynchronously and may not exist by the next animation frame, consider enhancing the hook with a short retry loop or a MutationObserver
.
See scrollIntoView for more information about the underlying scroll API.