Próbuję skonfigurować Google Analytics w mojej witrynie React i natknąłem się na kilka pakietów, ale żaden z nich nie jest tak skonfigurowany, jak ja, jeśli chodzi o przykłady. Miał nadzieję, że ktoś może rzucić na to trochę światła.
Pakiet, na który patrzę, to: react-ga .
Moja metoda renderowania index.js
wygląda tak.
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
źródło
źródło
react-router-4
/react-router-dom
poniżej, tutaj najlepsza odpowiedź dotyczy wcześniejszych wersji routera React i niestety nie będzie działać z wersją 4.Odpowiedzi:
Zachowaj odniesienie do obiektu historii. to znaczy
import { createBrowserHistory } from 'history'; var history = createBrowserHistory(); ReactDOM.render(( <Router history={history}> [...]
Następnie dodaj odbiornik, aby rejestrować każdą odsłonę. (Zakłada się, że obiekt został już skonfigurowany
window.ga
w zwykły sposób).history.listen((location) => { window.ga('set', 'page', location.pathname + location.search); window.ga('send', 'pageview'); });
źródło
ga('set', 'page', location.pathname + location.search); ga('send', 'pageview');
.Zakładając, że Google Analytics jest ładowane i inicjowane z identyfikatorem śledzenia.
Oto rozwiązanie dla React-router w wersji 4 wykorzystujące
<Route>
komponent do śledzenia wyświetleń strony.<Route path="/" render={({location}) => { if (typeof window.ga === 'function') { window.ga('set', 'page', location.pathname + location.search); window.ga('send', 'pageview'); } return null; }} />
Po prostu renderujesz ten komponent wewnątrz
<Router>
(ale nie jako bezpośrednie dziecko a<Switch>
).Dzieje się tak, że za każdym razem, gdy zmienia się właściwość lokalizacji, powoduje to ponowne renderowanie tego komponentu (a nie renderowanie niczego), który uruchamia odsłonę.
źródło
Switch
Używam React Router v4 i Google Analytics globalnego tagu witryny , który wydaje się być zalecany w chwili pisania tego.
A oto moje rozwiązanie:
Utwórz komponent opakowany w withRouter z
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);
Po prostu dodaj komponent do routera (uważam, że najlepiej po wszystkich trasach, które byłyby dopasowane, i dowolnych komponentach Switch, ponieważ funkcja analityczna nie powinna mieć pierwszeństwa przed renderowaniem witryny):
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> );
Jak wspomniano:
Więc kiedy trasa się zmieni,
GoogleAnalytics
komponent zostanie zaktualizowany, otrzyma nową lokalizację jako rekwizyty ihistory.action
będzie alboPUSH
dla nowego elementu historii, alboPOP
zasygnalizował cofnięcie się w historii (co myślę, że nie powinno wywołać wyświetlenia strony, ale można dostosować, jeśli oświadczeniacomponentWillUpdate
zgodnie z potrzebami (można nawet spróbowaćcomponentDidUpdate
zethis.props
zamiast, ale jestem pewien, co jest lepsze)).źródło
<body> ... <script ...></script></body>
componentWillMount
nacomponentDidMount
. Zmieńpage_path
TOthis.props.location.pathname
. Owiń komponenty Switch i GoogleAnalytics w <div>componentWillMount
, i nie jestem pewien, jak siępage_path
różni, ale spróbuję owinąć komponent Switch i GA<React.Fragment>
zamiastdiv
. Dzięki!Uwaga, jeśli korzystasz z
react-router-dom
pakietureact-router-4
, możesz sobie z tym poradzić w następujący sposób: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>) } }
Zauważ, że wymaga to zainstalowania
history
pakietu (npm install history
). Jest to już zależność reakcja-router-dom, więc nie dodajesz tutaj żadnej wagi strony.Uwaga: nie jest możliwe użycie komponentu BrowserRouter ORAZ instrumentu śledzenia ga w ten sposób. To jest w porządku, ponieważ komponent BrowserRouter jest po prostu bardzo cienką otoczką wokół obiektu Router. Odtworzyliśmy tutaj funkcjonalność BrowserRouter z
<Router history={history}>
miejscem, w którymconst history = createBrowserHistory();
.źródło
history
obiekt w swojej kompilacji, a następnie zapisać historię nawindow
obiekcie i uzyskać do niej dostęp w tagu skryptu w swoim,<head>
ale myślę, że ostatecznie spowodowałoby to, że potok kompilacji byłby bardziej skomplikowany. ¯_ (ツ) _ / ¯BrowserRouter
komponentu, zobacz odpowiedź poniżej, która oferuje alternatywne rozwiązanie.Sugerowałbym użycie doskonałego
react-router-ga
pakietu, który jest niezwykle lekki i łatwy w konfiguracji, szczególnie w przypadku korzystania zBrowserRouter
opakowania.Zaimportuj komponent:
import Analytics from 'react-router-ga';
Następnie po prostu dodaj
<Analytics>
w swoimBrowserRouter
:<BrowserRouter> <Analytics id="UA-ANALYTICS-1"> <Switch> <Route path="/somewhere" component={SomeComponent}/> </Switch> </Analytics> </BrowserRouter>
źródło
Podoba mi się to, co sugeruje tutaj Mark Thomas Müller :
W pliku index.js
import ReactGA from 'react-ga' ReactGA.initialize('YourAnalyticsID') ReactDOM.render(<App />, document.getElementById('root'))
Gdzie są twoje trasy:
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> ) } }
Krótkie, skalowalne i proste :)
źródło
Ponieważ
react-router v5.1.0
można to rozwiązać o wiele łatwiej za pomocąuseLocation
.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 (...); };
Zobacz też:
Oto nieco inteligentniejsza wersja:
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;
źródło
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"}
i nowy widok strony jest wyświetlany na pulpicie nawigacyjnym gaW dokumentacji React-GA dodali komponent społeczności zalecany do używania z React Router: https://github.com/react-ga/react-ga/wiki/React-Router-v4-withTracker
Realizacja
import withTracker from './withTracker'; ReactDOM.render( <Provider store={store}> <ConnectedRouter history={history}> <Route component={withTracker(App, { /* additional attributes */ } )} /> </ConnectedRouter> </Provider>, document.getElementById('root'), );
Kod
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;
źródło
store
pochodzi?Provider
iConnectedRouter
skąd? To jest niepełna odpowiedź i powinna zostać odrzuconaNajpierw w pliku index.js ustaw funkcję onUpdate, aby wywoł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> ); }
Oraz 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)}; }
źródło
oto najprostszy sposób śledzenia wszystkich ścieżek z pewnymi obejściami:
npm i --save history react-ga
utwórz plik
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
a następnie zaimportuj go do miejsca, w którym jest ustawiony plik
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
źródło
Proponuję skorzystać z biblioteki analitycznej segmentu i postępować zgodnie z przewodnikiem szybkiego startu React, aby śledzić wywołania stron za pomocą biblioteki React -router . Możesz zezwolić
<Route />
komponentowi na obsługę renderowania strony i używać gocomponentDidMount
do wywoływaniapage
połączeń. Poniższy przykład pokazuje jeden sposób, w jaki możesz to zrobić: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> ); } }
Jestem opiekunem https://github.com/segmentio/analytics-react . Dzięki Segmentowi możesz włączać i wyłączać różne miejsca docelowe za pomocą przełącznika, jeśli chcesz wypróbować wiele narzędzi analitycznych (obsługujemy ponad 250 miejsc docelowych) bez konieczności pisania dodatkowego kodu. 🙂
źródło
Jeśli korzystasz z skrótu lub historii przeglądarki, możesz:
import trackingHit from 'tracking'; import { Router, browserHistory } from 'react-router'; browserHistory.listen(trackingHit); // OR import { Router, hashHistory } from 'react-router'; hashHistory.listen(trackingHit);
gdzie ./tracking.es6
export default function(location) { console.log('New page hit', location.pathname); // Do your shizzle here }
źródło
podstawowa implementacja reakcji-ga z Twoim 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'));
źródło
Na podstawie sugestii @ david-l-walsh i @bozdoz
I stworzył hoc wykonać ten
window.ga('set','page','{currentUrl})
iwindow.ga('send', 'pageview');
funkcję i jest w łatwy stosowany bezpośrednio na stronie routera ...to jest 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;
i jest używany w ten sposób na stronie routera:
<Route path={'yourPath'} component={withGAHistoryTrack(yourComponent)} exact />
źródło
Aby dynamicznie aktualizować adres URL w niektórych zdarzeniach (takich jak onClick itp.), Można użyć:
//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);
źródło