React-Router 용 Google Analytics를 설정하는 방법은 무엇입니까?


82

내 반응 사이트에서 Google Analytics를 설정하려고하는데 몇 가지 패키지를 발견했지만 그중 어느 것도 예제 측면에서 설정 한 종류가 없습니다. 누군가가 이것에 대해 밝힐 수 있기를 바랐습니다.

내가보고있는 패키지는 react-ga 입니다.

내 렌더링 방법은 index.js다음과 같습니다.

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'));

4
react-router-4/ react-router-dom아래 에 대한 답변을 게시했습니다. 여기에있는 상위 답변은 이전 버전의 react-router 용이며 불행히도 v4에서는 작동하지 않습니다.
Peter Berg

react SSR을 사용할 때 StaticRouter로 어떻게 추가합니까?
Subhendu Kundu

답변:


83

기록 개체에 대한 참조를 유지하십시오. 즉

import { createBrowserHistory } from 'history';

var history = createBrowserHistory();

ReactDOM.render((
    <Router history={history}>
        [...]

그런 다음 리스너를 추가하여 각 페이지 뷰를 기록합니다. (이것은 window.ga일반적인 방식으로 이미 객체를 설정했다고 가정합니다 .)

history.listen((location) => {
    window.ga('set', 'page', location.pathname + location.search);
    window.ga('send', 'pageview');
});

16
전송 된 이벤트 또는 기타 적중 유형은 고려되지 않습니다. 페이지로드시 URL을 계속 참조합니다. 대신 페이지 뷰를 보내기 전에 트래커에 새 값을 설정해야합니다 (예 :) ga('set', 'page', location.pathname + location.search); ga('send', 'pageview');.
Philip Walton

1
안녕하세요 David, ga 사이트의 일반 GA 코드를 사용하는 예입니까 아니면 react-ga 패키지를 사용합니까? 감사.
John Fu

아직 해결 방법을 결정하지 않았지만 다음 정보도 유용 할 수 있습니다. stackoverflow.com/questions/30052693/… ( 어트 리뷰 션 이 일부 경우에 올바르게 작동하지 않는 이유를 설명하고 높은 이탈률을 도입하기도합니다. ).
DeTeam

send 명령에 세 번째 매개 변수를 원하지 않습니다. "기술적으로 페이지 뷰 조회에 대한 send 명령은 선택적 페이지 필드를 세 번째 매개 변수로 허용하지만 단일 페이지 애플리케이션을 추적 할 때 페이지 필드를 전달하는 것은 권장되지 않습니다. 이는 send 명령을 통해 전달 된 필드가 추적기에 설정되지 않았기 때문입니다. 추적기를 업데이트하지 않으면 애플리케이션이 페이지 뷰가 아닌 조회수 (예 : 이벤트 또는 소셜 상호 작용)를 전송하는 경우 문제가 발생합니다. 이러한 조회수는 추적기가 생성되었을 때 보유한 페이지 값과 연관되기 때문입니다. "
Joshua Robinson


29

Google 애널리틱스가로드되고 추적 ID로 초기화된다는 점을 감안할 때.

다음은 <Route>페이지 뷰를 추적하기 위해 구성 요소를 사용하는 react-router 버전 4에 대한 솔루션입니다 .

<Route path="/" render={({location}) => {
  if (typeof window.ga === 'function') {
    window.ga('set', 'page', location.pathname + location.search);
    window.ga('send', 'pageview');
  }
  return null;
}} />

이 구성 요소를 내부에 렌더링하기 만하면 <Router>됩니다 (의 직계 자식이 <Switch>아님).

위치 소품이 변경 될 때마다 페이지 뷰를 발생시키는이 구성 요소 (실제로 아무것도 렌더링하지 않음)가 다시 렌더링됩니다.


1
React-router 4. 할 수없는 것이 있습니까?!
Anthony Cregan

1
개별 경로 수정을 포함하지 않는 또 다른 react-router-4 솔루션을 아래에 게시했습니다. 슬프게도 이것은 확실히 "독을 선택하십시오"유형의 상황입니다.
Peter Berg

1
이것은 "/"가 아무 것도 렌더링하지 않는다는 것을 의미하지 않습니까?
Dana Woodman

3
@DanaWoodman 원하는 것을 방출하는 다른 경로가 있습니다. 이 경로가 아닌 가정Switch
bozdoz

랜딩 페이지에서 두 번의 페이지 뷰를 추적합니까? GA가 방문 페이지를 자동으로 추적하고 이에 대한 추가 페이지 뷰 이벤트를 트리거합니다. 아니면 GA가 필터링합니까?
ArneHugo

27

저는 React Router v4와 Google Analytics 글로벌 사이트 태그를 사용 하고 있는데,이 글을 작성할 당시 권장되는 것으로 보입니다.

그리고 여기 내 해결책이 있습니다.

다음에서 withRouter 로 래핑 된 구성 요소를 만듭니다 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);

라우터 내에 구성 요소를 추가하기 만하면됩니다 (분석 기능이 사이트 렌더링보다 우선하지 않아야하기 때문에 일치 할 경로와 스위치 구성 요소 뒤에 이상적으로는 생각합니다).

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>
);

명시된 바와 같이 :

withRouter는 렌더 소품과 동일한 소품으로 경로가 변경 될 때마다 구성 요소를 다시 렌더링합니다.

그래서, 때 경로 변경 GoogleAnalytics구성 요소가 업데이트됩니다, 그것은 소품으로 새 위치를 받게됩니다, 그리고 history.action이 될 것이다 PUSH새로운 기록 항목에 대한 또는 POP내가 페이지 뷰를 트리거하지한다고 생각하는 (역사를 뒤로가는 신호를하지만, 당신은 경우를 조절할 수있는 문 componentWillUpdate당신이 적합을 참조로 (당신도 시도 할 수 componentDidUpdatethis.props대신하지만, 내가 더 잘되는 확실 해요)).


bozdoz는 페이지에 글로벌 사이트 태그를 어떻게 추가 했습니까? body 태그 아래의 html 페이지 에 <script async src = " googletagmanager.com/gtag/js?id=GA_TRACKING_ID " > </… >를 추가하셨습니까 ?
me-me

1
@ me-me 예. 그러나 본문 태그 내에서 :<body> ... <script ...></script></body>
bozdoz

최신 React 및 React Router에는 몇 가지 조정이 필요했습니다. 변경 componentWillMountcomponentDidMount. 변화 page_path에를 this.props.location.pathname. Switch 및
GoogleAnalytics

당신이보고있는 확실하지 어디에 componentWillMount, 그리고 확인하는 방법 page_path다르다,하지만 난에 포장 스위치 및 GA 구성 요소를 시도 할 것입니다 <React.Fragment>대신의 div. 감사!
bozdoz

2
안녕하세요 @JoshuaRobinson, 저는 하단에 "... 페이지보기를 트리거해서는 안된다고 생각하지만 조정할 수 있습니다 ..."라고 썼습니다. 이 질문은 어떤 뷰를 기록해야하는지가 아니라 Google Analytics를 React Router와 통합하는 것에 관한 것입니다. 그래도 Google이 구성 요소를 다르게 추적하므로 내 구성 요소를 조정할 수 있습니다. 감사.
bozdoz

19

react-router-dom패키지를 사용하는 경우 react-router-4다음과 같이 처리 할 수 ​​있습니다.

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>)
  }
}

이 경우 history패키지 ( npm install history) 를 설치해야합니다 . 이것은 이미 react-router-dom의 종속성이므로 여기에 페이지 가중치를 추가하지 않습니다.

또한 참고 : BrowserRouter 구성 요소를 사용하고 이러한 방식으로 GA 추적을 계측하는 것은 불가능합니다. BrowserRouter 구성 요소 는 Router 개체를 둘러싼 정말 얇은 래퍼 이기 때문에 괜찮습니다 . 우리와 함께 여기에 BrowserRouter 기능을 다시 <Router history={history}>const history = createBrowserHistory();.


initGA에 전화하지 않으셨습니까?
Muhammad Umer

사실 @MuhammadUmer, 그냥 고정
피터 버그에게

정적 HTML에 GA를 추가하지 않는 이유는 무엇입니까? 나는 당신에게 1을 더했습니다. 역사 객체를 듣는 것이 올바른 방법이라고 생각하기 때문입니다.
Vince V.

@VinceV. history빌드 내 에서 객체를 초기화 한 다음 객체에 대한 기록을 저장 window하고 스크립트 태그에 액세스 할 수 <head>있지만 궁극적으로 빌드 파이프 라인을 더 복잡하게 만들 것이라고 생각합니다. ¯_ (ツ) _ / ¯
Peter Berg

BrowserRouter구성 요소를 사용하는 경우 대체 솔루션을 제공하는 아래 답변을 참조하십시오.
Toshe

15

react-router-ga특히 BrowserRouter래퍼를 사용할 때 매우 가볍고 구성하기 쉬운 우수한 패키지를 사용하는 것이 좋습니다 .

구성 요소를 가져옵니다.

import Analytics from 'react-router-ga';

그런 다음 간단히 다음을 추가 <Analytics>하십시오 BrowserRouter.

<BrowserRouter>
    <Analytics id="UA-ANALYTICS-1">
        <Switch>
            <Route path="/somewhere" component={SomeComponent}/>
        </Switch>
    </Analytics>
</BrowserRouter>

사용자가 페이지보기 만 추적하는 데 관심이있는 경우 이것은 매우 간단한 솔루션으로 보입니다. 매우 린!
peyo

11

Mark Thomas Müller가 여기에서 제안하는 방식이 마음에 듭니다 .

당신에 하는 index.js

import ReactGA from 'react-ga'

ReactGA.initialize('YourAnalyticsID')

ReactDOM.render(<App />, document.getElementById('root'))

경로 :

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>
        )
    }
}

짧고 확장 가능하며 간단합니다. :)


추적, 하나의 글로벌, 하나의 로컬이있는 이유는 무엇입니까?
Thellimist

10

이후 react-router v5.1.0이 쉽게와 많이 해결 될 수있다 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 (...);
};

또한보십시오:

다음은 좀 더 스마트 한 버전입니다.

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;

최신 'gtag'에 필요한지 잘 모르겠습니다. 탐색 할 때 ga 디버거가 푸시 이벤트를 올바르게 기록하는 것 같습니다 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"}. ga 대시 보드에 새 페이지보기가 표시됩니다
Dattaya

6

항상 도서관의 권장 방법을 따르십시오.

React-GA 문서에서 React Router와 함께 사용하도록 권장되는 커뮤니티 구성 요소를 추가했습니다. https://github.com/react-ga/react-ga/wiki/React-Router-v4-withTracker

이행

import withTracker from './withTracker';

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Route component={withTracker(App, { /* additional attributes */ } )} />
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root'),
);

암호

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;

1
SSR (서버 측 렌더링)을 사용하면 GA는 페이지를 새로 고치지 않고 실제 페이지의 제목을 알지 못합니다.
Francis Rodrigues

1
React를 사용하여 마운트의 제목을 변경할 수 있습니다
Paras

게시 해 주셔서 감사합니다!
Sailesh Kotha

어디에서 store왔습니까?
user_78361084

어디 않습니다 ProviderConnectedRouter에서 온? 이는 불완전한 답하고을 downvoted한다
user_78361084

2

먼저 index.js에서 onUpdate 함수를 설정하여 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>
  );
}

그리고 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)};
}

여기서 사용되는 라우터 버전은 무엇입니까?
Pavan

v4가 아닌 react router dom v2 또는 v3 용
Hugo Gresse

2

다음은 몇 가지 해결 방법으로 모든 경로를 추적하는 가장 간단한 방법입니다.

npm i --save history react-ga

파일 생성 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

그런 다음 설정된 위치로 가져옵니다. 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

참조 :

구스타보 곤잘레스 | medium.com

역사 | GitHub


2

세그먼트 분석 라이브러리를 사용하고 React 빠른 시작 가이드 에 따라 react-router 라이브러리를 사용하여 페이지 호출을 추적 하는 것이 좋습니다 . <Route />페이지가 렌더링 될 때 구성 요소가 처리 하도록 허용하고 componentDidMount호출을 호출 하는 데 사용할 수 page있습니다. 아래 예는이를 수행 할 수있는 한 가지 방법을 보여줍니다.

    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>
        );
      }
    }

저는 https://github.com/segmentio/analytics-react 의 유지 관리자입니다 . Segment를 사용하면 추가 코드를 작성하지 않고도 여러 분석 도구 (250 개 이상의 대상 지원)를 사용하는 데 관심이있는 경우 스위치를 켜고 끌 수 있습니다. 🙂


1

해시 또는 브라우저 기록을 사용하는 경우 다음을 수행 할 수 있습니다.

import trackingHit from 'tracking';

import { Router, browserHistory } from 'react-router';
browserHistory.listen(trackingHit);
// OR
import { Router, hashHistory } from 'react-router';
hashHistory.listen(trackingHit);

여기서 ./tracking.es6

export default function(location) {
    console.log('New page hit', location.pathname);
    // Do your shizzle here
}

0

index.js를 사용한 기본 react-ga 구현

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'));

@BigDong 나는 closeHeader가 뭔지 모르겠다. 렌더 코드가 그의 것이기 때문에 OP에게 그 질문을해야 할 것입니다. 난 그냥 당신이 자신의 코드 (내 // 의견 모양) 반응 가역을 구현하는 것이 방법을 표시하고
이삭 박

0

@ david-l-walsh 및 @bozdoz 제안을 기반으로 함

window.ga('set','page','{currentUrl})window.ga('send', 'pageview');기능 을 실행 하고 라우터 페이지에서 직접 쉽게 사용되는 HOC를 만들었습니다 .

이것은 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;

라우터 페이지에서 다음과 같이 사용됩니다.

<Route
 path={'yourPath'}
 component={withGAHistoryTrack(yourComponent)}
 exact
/>

0

일부 이벤트 (onClick 등)에서 동적으로 URL을 업데이트하려면 다음을 사용할 수 있습니다.

 //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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.