Estoy intentando configurar Google Analytics en mi sitio de reacción y me he encontrado con algunos paquetes, pero ninguno tiene el tipo de configuración que tengo en términos de ejemplos. Esperaba que alguien pudiera arrojar algo de luz sobre esto.
El paquete que estoy viendo es react-ga .
Mi método de renderizado en mi se index.js
ve así.
React.render((
<Router history={createBrowserHistory()}>
<Route path="/" component={App}>
<IndexRoute component={Home} onLeave={closeHeader}/>
<Route path="/about" component={About} onLeave={closeHeader}/>
<Route path="/gallery" component={Gallery} onLeave={closeHeader}/>
<Route path="/contact-us" component={Contact} onLeave={closeHeader}>
<Route path="/contact-us/:service" component={Contact} onLeave={closeHeader}/>
</Route>
<Route path="/privacy-policy" component={PrivacyPolicy} onLeave={closeHeader} />
<Route path="/feedback" component={Feedback} onLeave={closeHeader} />
</Route>
<Route path="*" component={NoMatch} onLeave={closeHeader}/>
</Router>), document.getElementById('root'));
google-analytics
reactjs
react-router
John Fu
fuente
fuente
react-router-4
/ areact-router-dom
continuación, la respuesta principal aquí es para versiones anteriores de react-router y desafortunadamente no funcionará con v4.Respuestas:
Mantenga una referencia a su objeto de historial. es decir
import { createBrowserHistory } from 'history'; var history = createBrowserHistory(); ReactDOM.render(( <Router history={history}> [...]
Luego agregue un oyente para registrar cada página vista. (Esto supone que ya ha configurado el
window.ga
objeto de la forma habitual).history.listen((location) => { window.ga('set', 'page', location.pathname + location.search); window.ga('send', 'pageview'); });
fuente
ga('set', 'page', location.pathname + location.search); ga('send', 'pageview');
.Dado que Google Analytics se carga e inicializa con un ID de seguimiento.
Aquí hay una solución para react-router versión 4 que usa el
<Route>
componente para rastrear las vistas de página.<Route path="/" render={({location}) => { if (typeof window.ga === 'function') { window.ga('set', 'page', location.pathname + location.search); window.ga('send', 'pageview'); } return null; }} />
Simplemente representa este componente dentro de
<Router>
(pero no como un hijo directo de a<Switch>
).Lo que sucede es que cada vez que cambia la propiedad de ubicación, se produce una nueva representación de este componente (que en realidad no representa nada) que activa una vista de página.
fuente
Switch
Estoy usando React Router v4 y la etiqueta de sitio global de Google Analytics , que parece ser la recomendada en el momento de escribir esto.
Y esta es mi solución:
Cree un componente envuelto con enrutador desde
react-router-dom
:import React from 'react'; import { withRouter } from 'react-router-dom'; import { GA_TRACKING_ID } from '../config'; class GoogleAnalytics extends React.Component { componentWillUpdate ({ location, history }) { const gtag = window.gtag; if (location.pathname === this.props.location.pathname) { // don't log identical link clicks (nav links likely) return; } if (history.action === 'PUSH' && typeof(gtag) === 'function') { gtag('config', GA_TRACKING_ID, { 'page_title': document.title, 'page_location': window.location.href, 'page_path': location.pathname }); } } render () { return null; } } export default withRouter(GoogleAnalytics);
Simplemente agregue el componente dentro de su enrutador (creo que lo ideal sería después de cualquier ruta que coincidiera y cualquier componente de Switch, porque la función de análisis no debería tener prioridad sobre la representación de su sitio):
import React from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import IndexPage from './IndexPage'; import NotFoundPage from './NotFoundPage'; import GoogleAnalytics from './GoogleAnalytics'; const App = () => ( <Router> <Switch> <Route exact path="/" component={IndexPage} /> <Route component={NotFoundPage} /> </Switch> <GoogleAnalytics /> </Router> );
Como se dijo:
Entonces, cuando la ruta cambie, el
GoogleAnalytics
componente se actualizará, recibirá la nueva ubicación como accesorios yhistory.action
seráPUSH
para un nuevo elemento del historial oPOP
para indicar que retrocede en el historial (lo que creo que no debería activar una vista de página, pero se puede ajustar el caso de declaraciones encomponentWillUpdate
como mejor le parezca (incluso se podría tratarcomponentDidUpdate
con elthis.props
lugar, pero estoy seguro de que es mejor)).fuente
<body> ... <script ...></script></body>
componentWillMount
acomponentDidMount
. Cambiepage_path
athis.props.location.pathname
. Envuelva los componentes de Switch y GoogleAnalytics en un <div>componentWillMount
, y no estoy seguro de en qué sepage_path
diferencia, pero intentaría incluir el componente Switch y GA en<React.Fragment>
lugar de undiv
. ¡Gracias!Tenga en cuenta que si está utilizando el
react-router-dom
paquete dereact-router-4
puede manejar esto así:import { Router, Route } from 'react-router-dom'; import { createBrowserHistory } from 'history'; const history = createBrowserHistory(); const initGA = (history) => { (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'YOUR_IDENTIFIER_HERE', 'auto'); ga('send', 'pageview'); history.listen((location) => { console.log("tracking page view: " + location.pathname); ga('send', 'pageview', location.pathname); }); }; initGA(history); class App extends Component { //eslint-disable-line render() { return (<Router history={history} > <Route exact path="/x" component={x} /> <Route exact path="/y" component={y} /> </Router>) } }
Tenga en cuenta que esto requiere que instale el
history
paquete (npm install history
). Esto ya es una dependencia de react-router-dom, por lo que no agregará ningún peso de página aquí.También tenga en cuenta: No es posible utilizar el componente BrowserRouter E instrumentar su seguimiento de GA de esta manera. Esto está bien porque el componente BrowserRouter es solo una envoltura muy delgada alrededor del objeto Router. Recreamos la funcionalidad BrowserRouter aquí con
<Router history={history}>
whereconst history = createBrowserHistory();
.fuente
history
objeto dentro de su compilación y luego almacenar el historial en elwindow
objeto y acceder a él en una etiqueta de secuencia de comandos en su,<head>
pero creo que, en última instancia, terminaría haciendo que su canal de compilación sea más complicado. ¯_ (ツ) _ / ¯BrowserRouter
componente, vea la respuesta a continuación que ofrece una solución alternativa.Sugeriría usar el excelente
react-router-ga
paquete que es extremadamente liviano y fácil de configurar, especialmente cuando se usa elBrowserRouter
contenedor.Importar el componente:
import Analytics from 'react-router-ga';
Luego, simplemente agregue el
<Analytics>
dentro de suBrowserRouter
:<BrowserRouter> <Analytics id="UA-ANALYTICS-1"> <Switch> <Route path="/somewhere" component={SomeComponent}/> </Switch> </Analytics> </BrowserRouter>
fuente
Me gusta cómo sugiere Mark Thomas Müller aquí :
En su index.js
import ReactGA from 'react-ga' ReactGA.initialize('YourAnalyticsID') ReactDOM.render(<App />, document.getElementById('root'))
Dónde están tus rutas:
import React, { Component } from 'react' import { Router, Route } from 'react-router-dom' import createHistory from 'history/createBrowserHistory' import ReactGA from 'react-ga' const history = createHistory() history.listen(location => { ReactGA.set({ page: location.pathname }) ReactGA.pageview(location.pathname) }) export default class AppRoutes extends Component { componentDidMount() { ReactGA.pageview(window.location.pathname) } render() { return ( <Router history={history}> <div> <Route path="/your" component={Your} /> <Route path="/pages" component={Pages} /> <Route path="/here" component={Here} /> </div> </Router> ) } }
Corto, escalable y simple :)
fuente
Dado que
react-router v5.1.0
esto se puede resolver mucho más fácilmente conuseLocation
.usePageTracking.js
import { useEffect} from "react"; import { useLocation } from "react-router-dom"; import ReactGA from "react-ga"; const usePageTracking = () => { const location = useLocation(); useEffect(() => { ReactGA.initialize("UA-000000000-0"); ReactGA.pageview(location.pathname + location.search); }, [location]); }; export default usePageTracking;
App.js
const App = () => { usePageTracking(); return (...); };
Ver también:
Aquí hay una versión un poco más inteligente:
usePageTracking.js
import { useEffect, useState } from "react"; import { useLocation } from "react-router-dom"; import ReactGA from "react-ga"; const usePageTracking = () => { const location = useLocation(); const [initialized, setInitialized] = useState(false); useEffect(() => { if (!window.location.href.includes("localhost")) { ReactGA.initialize("UA-000000000-0"); } setInitialized(true); }, []); useEffect(() => { if (initialized) { ReactGA.pageview(location.pathname + location.search); } }, [initialized, location]); }; export default usePageTracking;
fuente
Processing data layer push: {event: "gtm.historyChange-v2", gtm.historyChangeSource: "pushState", gtm.oldUrlFragment: "", gtm.newUrlFragment: "", gtm.oldHistoryState: null, gtm.newHistoryState: {key: "j5xoc4", state: undefined}, gtm.oldUrl: "https://site/", gtm.newUrl: "https://site/new-url?search-params", gtm.triggers: "1_36"}
y se muestra una nueva vista de página en el tablero de gaEn la documentación de React-GA, han agregado un componente de comunidad recomendado para usar con React Router: https://github.com/react-ga/react-ga/wiki/React-Router-v4-withTracker
Implementación
import withTracker from './withTracker'; ReactDOM.render( <Provider store={store}> <ConnectedRouter history={history}> <Route component={withTracker(App, { /* additional attributes */ } )} /> </ConnectedRouter> </Provider>, document.getElementById('root'), );
Código
import React, { Component, } from "react"; import GoogleAnalytics from "react-ga"; GoogleAnalytics.initialize("UA-0000000-0"); const withTracker = (WrappedComponent, options = {}) => { const trackPage = page => { GoogleAnalytics.set({ page, ...options, }); GoogleAnalytics.pageview(page); }; // eslint-disable-next-line const HOC = class extends Component { componentDidMount() { // eslint-disable-next-line const page = this.props.location.pathname + this.props.location.search; trackPage(page); } componentDidUpdate(prevProps) { const currentPage = prevProps.location.pathname + prevProps.location.search; const nextPage = this.props.location.pathname + this.props.location.search; if (currentPage !== nextPage) { trackPage(nextPage); } } render() { return <WrappedComponent {...this.props} />; } }; return HOC; }; export default withTracker;
fuente
store
vieneProvider
y de dondeConnectedRouter
viene? Esta es una respuesta incompleta y debería serPrimero, en su index.js configure la función onUpdate para llamar a ga
import ga from 'ga.js'; onUpdate() { console.log('=====GA=====>', location.pathname); console.log('=====GA_TRACKING_CODE=====>', GA_TRACKING_CODE); ga("send", "pageview", location.pathname); } render() { return ( <Router onUpdate={this.onUpdate.bind(this)}>...</Router> ); }
Y ga.js:
'use strict'; if(typeof window !== 'undefined' && typeof GA_TRACKING_CODE !== 'undefined') { (function(window, document, script, url, r, tag, firstScriptTag) { window['GoogleAnalyticsObject']=r; window[r] = window[r] || function() { (window[r].q = window[r].q || []).push(arguments) }; window[r].l = 1*new Date(); tag = document.createElement(script), firstScriptTag = document.getElementsByTagName(script)[0]; tag.async = 1; tag.src = url; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); })( window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga' ); var ga = window.ga; ga('create', GA_TRACKING_CODE, 'auto'); module.exports = function() { return window.ga.apply(window.ga, arguments); }; } else { module.exports = function() {console.log(arguments)}; }
fuente
aquí hay una forma más sencilla de rastrear todas las rutas con algunas soluciones:
npm i --save history react-ga
crear un archivo
history.js
import { createBrowserHistory } from "history" import ReactGA from "react-ga" ReactGA.initialize(process.env.REACT_APP_GA) const history = createBrowserHistory() history.listen((location) => { ReactGA.pageview(location.pathname) }) // workaround for initial visit if (window.performance && (performance.navigation.type === performance.navigation.TYPE_NAVIGATE)) { ReactGA.pageview("/") } export default history
y luego importarlo a donde está configurado su
Router
import history from "./history" ... class Route extends Component { render() { return ( <Router history={history}> <Switch> <Route path="/" exact component={HomePage} /> ... </Switch> </Router> ) } export default Route
fuente
Sugiero usar la biblioteca de análisis de segmentos y seguir la guía de inicio rápido de React para realizar un seguimiento de las llamadas de página utilizando la biblioteca react-router . Puede permitir que el
<Route />
componente maneje cuando la página se procesa y se usacomponentDidMount
para invocarpage
llamadas. El siguiente ejemplo muestra una forma en que puede hacer esto:const App = () => ( <div> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> </Switch> </div> ); export default App;
export default class Home extends Component { componentDidMount() { window.analytics.page('Home'); } render() { return ( <h1> Home page. </h1> ); } }
Soy el mantenedor de https://github.com/segmentio/analytics-react . Con Segment, podrá activar y desactivar diferentes destinos con solo tocar un interruptor si está interesado en probar varias herramientas de análisis (admitimos más de 250 destinos) sin tener que escribir ningún código adicional. 🙂
fuente
Si usa hash o historial del navegador, puede hacer:
import trackingHit from 'tracking'; import { Router, browserHistory } from 'react-router'; browserHistory.listen(trackingHit); // OR import { Router, hashHistory } from 'react-router'; hashHistory.listen(trackingHit);
donde ./tracking.es6
export default function(location) { console.log('New page hit', location.pathname); // Do your shizzle here }
fuente
implementación básica de react-ga con su index.js
var ReactGA = require('react-ga'); // require the react-ga module ReactGA.initialize('Your-UA-ID-HERE'); // add your UA code function logPageView() { // add this function to your component ReactGA.set({ page: window.location.pathname + window.location.search }); ReactGA.pageview(window.location.pathname + window.location.search); } React.render(( <Router history={createBrowserHistory()} onUpdate={logPageView} > // insert onUpdate props here <Route path="/" component={App}> <IndexRoute component={Home} onLeave={closeHeader}/> <Route path="/about" component={About} onLeave={closeHeader}/> <Route path="/gallery" component={Gallery} onLeave={closeHeader}/> <Route path="/contact-us" component={Contact} onLeave={closeHeader}> <Route path="/contact-us/:service" component={Contact} onLeave={closeHeader}/> </Route> <Route path="/privacy-policy" component={PrivacyPolicy} onLeave={closeHeader} /> <Route path="/feedback" component={Feedback} onLeave={closeHeader} /> </Route> <Route path="*" component={NoMatch} onLeave={closeHeader} /> </Router>), document.getElementById('root'));
fuente
Basado en sugerencias de @ david-l-walsh y @bozdoz
He creado un HOC que ejecute el
window.ga('set','page','{currentUrl})
ywindow.ga('send', 'pageview');
función y se usa fácilemte directamente en la página del router ...este es el HOC:
import React from 'react'; import { history } from '../../store'; // or wherever you createBrowserHistory(); invokation is function withGAHistoryTrack(WrappedComponent) { return class extends React.Component { constructor(props) { super(props); } componentDidMount() { const { location } = history; const page = location.pathname + location.search; if (typeof window.ga === 'function') { window.ga('set', 'page', page); window.ga('send', 'pageview'); } } render() { return <WrappedComponent {...this.props} />; } }; } export default withGAHistoryTrack;
y se usa de esta manera en la página del enrutador:
<Route path={'yourPath'} component={withGAHistoryTrack(yourComponent)} exact />
fuente
Para actualizar dinámicamente la URL en algún evento (como onClick, etc.), se puede usar lo siguiente:
//Imports import ReactGA from "react-ga"; import { createBrowserHistory } from "history"; // Add following on some event, like onClick (depends on your requirement) const history = createBrowserHistory(); ReactGA.initialize("<Your-UA-ID-HERE>"); ReactGA.pageview(history.location.pathname);
fuente