├── public
├── robots.txt
├── favicon.ico
└── index.html
├── src
├── pages
│ ├── Home.js
│ ├── NotFound.js
│ ├── ShoePage.js
│ └── Shoes.js
├── index.js
├── App.js
└── index.css
├── .gitignore
├── README.md
└── package.json
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DavidWells/use-analytics-with-react-router-demo/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/pages/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | export default function Home() {
4 | return (
5 |
6 |
Using use-analytics & react router v6
7 |
8 | )
9 | }
--------------------------------------------------------------------------------
/src/pages/NotFound.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | export default function NotFound() {
4 | return (
5 |
6 |
Not found!
7 |
Sorry your page was not found!
8 |
9 | )
10 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 | Use Analytic React Demo
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Use [Analytics](https://github.com/DavidWells/analytics) React Tutorial
2 |
3 | Example of using [`use-analytics`](https://www.npmjs.com/package/use-analytics) hooks with React router v6.
4 |
5 | [Video demo & explanation](https://www.youtube.com/watch?v=C_1ced3l9cU)
6 |
7 | [Docs site](https://getanalytics.io/utils/react-hooks/)
8 |
9 | [use-analytics source code](https://github.com/DavidWells/analytics/tree/master/packages/use-analytics)
10 |
11 | ## Install
12 |
13 | ```
14 | npm install
15 | ```
16 |
17 | ## Run Demo
18 |
19 | ```
20 | npm start
21 | ```
22 |
23 | ## Shoutout
24 |
25 | Shoutout to [Leigh Halliday](https://www.youtube.com/watch?v=4NpGzBEySvI) for his great router tutorial & the base for this code!
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "use-analytics-demo",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@analytics/google-analytics": "^0.3.1",
7 | "analytics": "^0.3.5",
8 | "react": "^16.13.0",
9 | "react-dom": "^16.13.0",
10 | "react-router": "^6.0.0-alpha.2",
11 | "react-router-dom": "^6.0.0-alpha.2",
12 | "react-scripts": "3.4.0",
13 | "use-analytics": "^0.0.3"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build"
18 | },
19 | "eslintConfig": {
20 | "extends": "react-app"
21 | },
22 | "browserslist": {
23 | "production": [
24 | ">0.2%",
25 | "not dead",
26 | "not op_mini all"
27 | ],
28 | "development": [
29 | "last 1 chrome version",
30 | "last 1 firefox version",
31 | "last 1 safari version"
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/pages/ShoePage.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { useParams, Link } from "react-router-dom"
3 | import { shoes } from './Shoes'
4 | import { useAnalytics } from 'use-analytics'
5 |
6 | export default function LaunchShoe() {
7 | const { slug } = useParams()
8 | const { track } = useAnalytics()
9 | const shoe = shoes[slug]
10 |
11 | if (!shoe) {
12 | return Not Found!
13 | }
14 |
15 | function handlePurchase() {
16 | track('shoePurchased', {
17 | name: shoe.name,
18 | price: shoe.price,
19 | })
20 | }
21 |
22 | const { name, img } = shoe
23 |
24 | return (
25 |
26 |
27 | Back to all shoes
28 |
29 |
{name}
30 |
31 |

32 |
35 |
36 |
37 | )
38 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import Analytics from 'analytics'
4 | import googleAnalytics from '@analytics/google-analytics'
5 | import { BrowserRouter } from "react-router-dom"
6 | import { AnalyticsProvider } from 'use-analytics'
7 | import App from './App'
8 | import './index.css'
9 |
10 | // Custom inline analytics plugin
11 | const myPlugin = {
12 | name: 'my-custom-plugin',
13 | page: ({ payload }) => {
14 | console.log('page view fired', payload)
15 | },
16 | track: ({ payload }) => {
17 | console.log('track event payload', payload)
18 | }
19 | }
20 |
21 | const analytics = Analytics({
22 | app: 'awesome',
23 | plugins: [
24 | myPlugin,
25 | googleAnalytics({
26 | trackingId: '123-xyz'
27 | })
28 | ]
29 | })
30 |
31 | ReactDOM.render((
32 |
33 |
34 |
35 |
36 |
37 | ), document.getElementById('root'))
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react"
2 | import { Routes, Route, Link, useLocation } from "react-router-dom"
3 | import Home from './pages/Home'
4 | import Shoes from './pages/Shoes'
5 | import ShoePage from './pages/ShoePage'
6 | import NotFound from './pages/NotFound'
7 | import { useAnalytics } from 'use-analytics'
8 |
9 | export default function App() {
10 | let location = useLocation()
11 | const analytics = useAnalytics()
12 |
13 | // When location changes in app send page view
14 | useEffect(() => {
15 | analytics.page()
16 | }, [location])
17 |
18 | return (
19 |
20 |
24 |
25 |
26 | } />
27 | } />
28 | } />
29 | } />
30 |
31 |
32 | )
33 | }
34 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0px;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
15 | nav {
16 | background: #cfd8dc;
17 | padding: 10px;
18 | }
19 |
20 | nav a {
21 | display: inline-block;
22 | padding: 5px;
23 | }
24 |
25 | a {
26 | text-decoration: none;
27 | }
28 |
29 | ul {
30 | list-style: none;
31 | padding: 0;
32 | max-width: 400px;
33 | display: flex;
34 | align-items: center;
35 | font-size: 12px;
36 | }
37 |
38 | li {
39 | margin-right: 30px;
40 | min-width: 330px;
41 | }
42 |
43 | img {
44 | max-width: 300px;
45 | }
46 |
47 | button {
48 | font-size: 30px;
49 | max-height: 60px;
50 | margin-left: 20px;
51 | }
52 |
53 | .page {
54 | padding: 20px;
55 | }
56 | .product {
57 | display: flex;
58 | align-items: center
59 | }
60 |
--------------------------------------------------------------------------------
/src/pages/Shoes.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Link } from "react-router-dom"
3 |
4 | export default function Shoes() {
5 | return (
6 |
7 |
Shoe shop
8 |
9 | {Object.entries(shoes).map(([slug, { name, img }]) => (
10 | -
11 |
12 |
{name}
13 |
14 |
15 |
16 | ))}
17 |
18 |
19 | )
20 | }
21 |
22 | const shoes = {
23 | "air-jordan-3-valor-blue": {
24 | name: "VALOUR BLUE",
25 | img: "https://secure-images.nike.com/is/image/DotCom/CT8532_104_A_PREM?$SNKRS_COVER_WD$&align=0,1",
26 | price: 100,
27 | },
28 | "jordan-mars-270-london": {
29 | name: "JORDAN MARS 270 LONDON",
30 | img: "https://secure-images.nike.com/is/image/DotCom/CV3042_001_A_PREM?$SNKRS_COVER_WD$&align=0,1",
31 | price: 200,
32 | },
33 | "air-jordan-1-zoom-racer-blue": {
34 | name: "RACER BLUE",
35 | img: "https://secure-images.nike.com/is/image/DotCom/CK6637_104_A_PREM?$SNKRS_COVER_WD$&align=0,1",
36 | price: 300,
37 | }
38 | }
39 |
40 | export { shoes }
41 |
--------------------------------------------------------------------------------