Skip to content
This repository was archived by the owner on May 6, 2024. It is now read-only.

Commit 6138a0f

Browse files
connor-baerfernandofleury
authored andcommitted
docs: improve README (#13)
* docs: improve contributing guidelines * docs: move motivation to separate file * docs: simplify the README and clarify Collector's purpose * docs: define "page view"
1 parent fb0455b commit 6138a0f

File tree

3 files changed

+323
-306
lines changed

3 files changed

+323
-306
lines changed

.github/CONTRIBUTING.md

+11-5
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,26 @@
33
So you want to contribute to our project? That's awesome. Here are a few
44
things that can help you make it a reality.
55

6-
## Code of conduct
6+
## Contributor License Agreement (CLA)
77

8-
We expect all participants to read and adhere to our [code of conduct](/CODE_OF_CONDUCT.md).
8+
To start contributing to SumUp Open Source projects, please accept our [Contributor License Agreement](https://opensource.sumup.com/cla). Should you have any questions or concerns, please get in touch with [[email protected]](mailto:[email protected]).
9+
10+
## Code of Conduct (CoC)
11+
12+
We want to foster an inclusive and friendly community around our Open Source efforts. Like all SumUp Open Source projects, this project follows the Contributor Covenant Code of Conduct. Please, [read it and follow it](CODE_OF_CONDUCT.md).
13+
14+
If you feel another member of the community violated our CoC or you are experiencing problems participating in our community because of another individual's behavior, please get in touch with our [maintainers](README.md#maintainers). We will enforce the CoC.
915

1016
## Contributing
1117

12-
Signal uses a [conventional commit message format](https://www.conventionalcommits.org). In order to use it, commit using `yarn commit` instead of `git commit`.
18+
Collector uses a [conventional commit message format](https://www.conventionalcommits.org). In order to use it, commit using `yarn commit` instead of `git commit`.
1319

1420
## Bugs
1521

16-
We use the [GitHub issues](https://github.com/sumup/signal/issues) to track
22+
We use the [GitHub issues](https://github.com/sumup-oss/collector/issues) to track
1723
all our bugs and feature requests.
1824

19-
When [submitting a new issue](https://github.com/sumup/signal/issues/new),
25+
When [submitting a new issue](https://github.com/sumup-oss/collector/issues/new),
2026
please check that it hasn't already been raised by someone else. We've provided
2127
a template for new issues which will help you structure your issue to ensure it
2228
can be picked up and actioned easily.

MOTIVATION.md

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
# Motivation
2+
3+
The larger a web applications grows, the harder it is to provide predictable and traceable tracking structures. Consider our usual analytics event dispatching:
4+
5+
```jsx
6+
import React, { useContext } from 'react';
7+
import { TrackingContext } from 'your-tracking';
8+
9+
function Button({ onClick, label, category, value, dispatch, children }) {
10+
let handler = onClick;
11+
12+
if (dispatch) {
13+
handler = e => {
14+
dispatch({ label, category, value });
15+
onClick && onClick(e);
16+
};
17+
}
18+
19+
return <button onClick={handler}>{children}</button>;
20+
}
21+
22+
function AccountBalance() {
23+
return (
24+
<Button
25+
type="submit"
26+
label="show-value"
27+
category="balance"
28+
dispatch={dispatch}
29+
>
30+
Click me
31+
</Button>
32+
);
33+
}
34+
35+
function AccountPage() {
36+
return (
37+
...,
38+
<Balance />
39+
);
40+
}
41+
42+
function Balance() {
43+
return (
44+
...,
45+
<ShowBalance />
46+
);
47+
}
48+
49+
function App() {
50+
return (
51+
<TrackingContext.Provider
52+
value={{
53+
dispatch: e => {
54+
window.dataLayer.push(e);
55+
}
56+
}}
57+
>
58+
<AccountPage />
59+
</TrackingContext.Provider>
60+
);
61+
}
62+
63+
```
64+
65+
Now, what happens if we need to define the event `category` somewhere else in the tree? For this small example it might not sound like much:
66+
67+
```jsx
68+
function AccountBalance({ category }) {
69+
const { dispatch } = useContext(TrackingContext);
70+
71+
return (
72+
<Button
73+
type="submit"
74+
label="show-value"
75+
category={category}
76+
dispatch={dispatch}
77+
>
78+
Click me
79+
</Button>
80+
);
81+
}
82+
```
83+
84+
But over time this can tightly couple our component implementation with the tracking usage. Ideally the `AccountBalance` component shouldn't have to worry about this sort of domain.
85+
86+
What about leveraging our already existing `TrackingContext`?
87+
88+
```jsx
89+
function AccountBalance() {
90+
const { dispatch, category } = useContext(TrackingContext);
91+
92+
return (
93+
<Button
94+
type="submit"
95+
label="show-value"
96+
category={category}
97+
dispatch={dispatch}
98+
>
99+
Click me
100+
</Button>
101+
);
102+
}
103+
```
104+
105+
But having a context usage also implies that you eventually need to set the value somewhere in the tree:
106+
107+
```jsx
108+
function AccountBalance() {
109+
const { dispatch, category } = useContext(TrackingContext);
110+
111+
return (
112+
<Button
113+
type="submit"
114+
label="show-value"
115+
category={category}
116+
dispatch={dispatch}
117+
>
118+
Click me
119+
</Button>
120+
);
121+
}
122+
123+
function Balance() {
124+
const { dispatch, setValue } = useContext(TrackingContext);
125+
useEffect(() => {
126+
setValue({ category: 'account-balance' });
127+
}, []);
128+
129+
return (
130+
...,
131+
<ShowBalance />
132+
);
133+
}
134+
135+
function App() {
136+
const [trackingData, setTrackingData] = useState({});
137+
return (
138+
<TrackingContext.Provider
139+
value={{
140+
...trackingData,
141+
dispatch: e => {
142+
window.dataLayer.push(e);
143+
},
144+
setValue: value => setTrackingData({ ...trackingData, ...value })
145+
}}
146+
>
147+
<AccountPage />
148+
</TrackingContext.Provider>
149+
);
150+
}
151+
```
152+
153+
But again, over time this can tightly couple our component implementation with the event tracking usage, and the more fields you need to overwrite, the harder it is to reason about the current state of the context. That's where Collector can help you!
154+
155+
Collector was built to track user-interactions with high granularity. Using an agnostic event schema you can serve different tracking purposes with it. Consider the same example using Collector:
156+
157+
```jsx
158+
import React from 'react';
159+
import {
160+
TrackingRoot,
161+
TrackingView,
162+
TrackingElement,
163+
useClickTrigger
164+
} from '@sumup/collector';
165+
166+
function Button({ onClick, 'tracking-label': trackingId, children }) {
167+
const dispatch = useClickTrigger();
168+
let handler = onClick;
169+
170+
if (trackingId) {
171+
handler = (e) => {
172+
dispatch({ label: trackingId, component: 'button' });
173+
onClick && onClick(e);
174+
};
175+
}
176+
177+
return <button onClick={handler}>{children}</button>;
178+
}
179+
180+
function AccountBalance() {
181+
return (
182+
<Button type="submit" tracking-label="show-balance">
183+
Click me
184+
</Button>
185+
);
186+
}
187+
188+
function AccountPage() {
189+
return (
190+
<TrackingView name="account">
191+
...,
192+
<Balance />
193+
</TrackingView>
194+
);
195+
}
196+
197+
function Balance() {
198+
return (
199+
<TrackingElement name="balance">
200+
...,
201+
<ShowBalance />
202+
</TrackingElement>
203+
);
204+
}
205+
206+
function toAnalyticsEvent({ view, elementTree, label, action }) {
207+
return {
208+
category: `${view}-${elementTree.join('-')}`,
209+
label: label,
210+
action
211+
};
212+
}
213+
214+
function App() {
215+
return (
216+
<TrackingRoot
217+
name="my-app"
218+
onDispatch={(event) => {
219+
window.dataLayer.push(toAnalyticsEvent(event));
220+
}}
221+
>
222+
<AccountPage />
223+
</TrackingRoot>
224+
);
225+
}
226+
```
227+
228+
For more information about the event schema and component structure, please refer to the [Event Schema](https://github.com/sumup/collector/#event-schema) and [Usage](https://github.com/sumup/collector/#usage) sections.

0 commit comments

Comments
 (0)