Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
react-page-tracker
Advanced tools
A lightweight, zero-dependency library providing accurate navigation tracking, fixed document.referrer value, and complete history support for React frameworks.
react-page-tracker
is a lightweight, zero-dependency library providing accurate navigation tracking, fixed
document.referrer
value, and complete history support for React frameworks. Fully compatible with Next.js, Remix, TanStack Query, and React Router.
👉 Demo
🚀 An awesome use case: Magic Back Button in shadcn/ui expansions
History.go()
, history.forward()
, history.back()
, and history.pushState()
.document.referrer
after navigation, providing the correct referrer for tracking purposes.type PageTrackerState = {
/** current page index */
pageIndex: number;
/** correct `document.referrer` */
referrer: string;
/** whether the current page is the first page */
isFirstPage: boolean;
/** whether the current page is the last page */
isLastPage: boolean;
/** whether the user navigated to the page via browser back/forward buttons or by clicking a link */
pageEvent?: PageEvent; // 'back' | 'forward' | 'push' | undefined. undefined for first visit.
/** history browsing record */
pageHistory: string[]; // ['/', '/products', '/pdocuts/1', '/products/2', '/about', ...]
/**
* total page history length.
* When user press `back` button, the `pageHistory`'s end link will become the current link.
* You may need this total length to handle `history.go(N)` to forward N page.
*/
pageHistoryLength: number;
}
Simply to get the values you need in any component.
const { pageIndex, referrer, isFirstPage, isLastPage, pageEvent, pageHistory } = usePageTrackerStore((state) => state);
npm install react-page-tracker
layout.tsx
+ import { PageTracker } from 'react-page-tracker';
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode; }>) {
return (
<html lang="en">
<body>
+ <PageTracker /> // next 14, there's an auto detection. A better way is to follow your environment. e,g. `enableStrictModeHandler={process.env.NODE_ENV === 'local'}`
+ <PageTracker enableStrictModeHandler={false} /> // next 15+. always be false
{children}
</body>
</html>
);
}
If you are using nextjs 15
, you have to set enableStrictModeHandler
to false
In nextjs 14
, strict mode will execute twice when push a page (e,g. click an Anchor link) which may cause pageHistory
values error and hard to handle in development mode.
But in remix, tanstack/query, react-router, it will not execute twice. works fine.
There's an automatic detection for nextjs strict mode, so you don't need to set this prop.
But I can't detect 14 or 15, so you have to set this prop to false
in next 15.
PS: DO NOT set enableStrictModeHandler
to true
in production, it may cause issues.
You are all set up! Now you can access the page tracking information in any component.
component.tsx
import { usePageTrackerStore } from 'react-page-tracker';
export const PageTrackerValue = () => {
// get all state
const state = usePageTrackerStore((state) => state);
// get the specific state you'd like to use
const pickState = usePageTrackerStore((state) => ({
isFirstPage: state.isFirstPage,
referrer: state.referrer,
pageHistory: state.pageHistory,
}));
return (
<div className="flex">
<div className="flex flex-col gap-3">
<pre className="rounded-md bg-gray-100 px-2 py-0.5 font-bold">
state: {JSON.stringify(state)}
</pre>
<pre className="rounded-md bg-gray-100 px-2 py-0.5 font-bold">
pickState: {JSON.stringify(pickState)}
</pre>
</div>
</div>
);
};
force Vite to build to CommonJS
vite.config.ts
export default defineConfig({
+ ssr: {
+ noExternal: ['react-page-tracker'], // force Vite to build to CommonJS
+ },
plugins: [
remix({
future: {
v3_fetcherPersist: true,
v3_relativeSplatPath: true,
v3_throwAbortReason: true,
v3_singleFetch: true,
v3_lazyRouteDiscovery: true,
},
}),
tsconfigPaths(),
],
});
root.tsx
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';
import type { LinksFunction } from '@remix-run/node';
import './tailwind.css';
+ import { PageTracker } from 'react-page-tracker';
export const links: LinksFunction = () => [
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{
rel: 'preconnect',
href: 'https://fonts.gstatic.com',
crossOrigin: 'anonymous',
},
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
},
];
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
+ <PageTracker />
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}
You are all set up! Now you can access the page tracking information in any component.
component.tsx
import { usePageTrackerStore } from 'react-page-tracker';
export const PageTrackerValue = () => {
// get all state
const state = usePageTrackerStore((state) => state);
// get the specific state you'd like to use
const pickState = usePageTrackerStore((state) => ({
isFirstPage: state.isFirstPage,
referrer: state.referrer,
pageHistory: state.pageHistory,
}));
return (
<div className="flex">
<div className="flex flex-col gap-3">
<pre className="rounded-md bg-gray-100 px-2 py-0.5 font-bold">
state: {JSON.stringify(state)}
</pre>
<pre className="rounded-md bg-gray-100 px-2 py-0.5 font-bold">
pickState: {JSON.stringify(pickState)}
</pre>
</div>
</div>
);
};
Be welcome to contribute! Here's how you can contribute:
Licensed under the MIT License.
FAQs
A lightweight, zero-dependency library providing accurate navigation tracking, fixed document.referrer value, and complete history support for React frameworks.
The npm package react-page-tracker receives a total of 150 weekly downloads. As such, react-page-tracker popularity was classified as not popular.
We found that react-page-tracker demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.