Skip to content

Commit 478601f

Browse files
Axel-KIRKAxel KIRKSlashgear
authored
feat(cookie): init cookie consent package (#1494)
* feat(cookie): init cookie consent package * chore(clean): remove comments * Update README.md * Update README.md * Update README.md * docs: add usage documentation * refactor(options): add props cookie config * refactor(options): add props cookie config * refactor(options): add props cookie config * refactor(options): add props cookie config * fix: review suggestions * fix: fix typing and test * fix: remove useless react typings inside package * docs: reference new package in global README --------- Co-authored-by: Axel KIRK <[email protected]> Co-authored-by: Antoine Caron <[email protected]> Co-authored-by: Antoine Caron <[email protected]>
1 parent 7d38f6f commit 478601f

File tree

19 files changed

+955
-0
lines changed

19 files changed

+955
-0
lines changed

.changeset/breezy-donuts-scream.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@scaleway/cookie-consent': major
3+
---
4+
5+
Extract internal cookie consent provider strategy to shared package

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ scaleway-lib is a set of NPM packages used at Scaleway.
3333

3434
## Available packages
3535

36+
- [`@scaleway/cookie-consent`](./packages/countries/README.md): React provider to handle website end user consent cookie storage based on segment integrations.
37+
38+
![npm](https://img.shields.io/npm/dm/@scaleway/cookie-consent)
39+
![npm bundle size](https://img.shields.io/bundlephobia/min/@scaleway/cookie-consent)
40+
![npm](https://img.shields.io/npm/v/@scaleway/cookie-consent)
41+
42+
3643
- [`@scaleway/countries`](./packages/countries/README.md): ISO 3166/3166-2 coutries JSON database.
3744

3845
![npm](https://img.shields.io/npm/dm/@scaleway/countries)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { join } = require('path')
2+
3+
module.exports = {
4+
rules: {
5+
'import/no-extraneous-dependencies': [
6+
'error',
7+
{ packageDir: [__dirname, join(__dirname, '../../')] },
8+
],
9+
},
10+
}

packages/cookie-consent/.npmignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
**/__tests__/**
2+
examples/
3+
src
4+
.eslintrc.cjs
5+
!.npmignore

packages/cookie-consent/README.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Shire - Cookie Consent
2+
3+
This package is an helper to handle cookie consents with Segment integrations.
4+
It will handle the cookie consent for each categories.
5+
6+
This package does not contain design element to display a cookie consent modal,
7+
it only handle the storage and the init of cookie consent in a React provider.
8+
9+
## QuickStart
10+
11+
In order to use it, first you need to provide a context at the top level of your application
12+
13+
```tsx
14+
import { PropsWithChildren } from 'react'
15+
16+
const MyApp = ({ children }: PropsWithChildren) => {
17+
return (
18+
<CookieConsentProvider
19+
isConsentRequired // Switch off consents if not defined (usefull for E2E testing)
20+
essentialIntegrations={[]} // List of mandatory integrations
21+
config={{
22+
segment, // Segment configuration used to get dynamically the integration used
23+
}}
24+
// not required
25+
cookiePrefix="_scw_rgpd" // default value
26+
consentMaxAge={13 * 30 * 24 * 60 * 60} // default value (appx 13 months)
27+
consentAdvertisingMaxAge={6 * 30 * 24 * 60 * 60} // default value (appx 6 months)
28+
cookiesOptions={{ sameSite: 'strict', secure: true, path: '/' }} // default value
29+
>
30+
{children}
31+
</CookieConsentProvider>
32+
)
33+
}
34+
```
35+
36+
Then in your cookie modal component you could simply use exposed hook to get and modify consents
37+
38+
```tsx
39+
export function PanelConsent() {
40+
const { saveConsent, categoriesConsent } = useCookieConsent()
41+
42+
const setAllConsents = ({
43+
categoriesConsent,
44+
value,
45+
}: {
46+
categoriesConsent: Partial<Consent>
47+
value: boolean
48+
}) =>
49+
Object.keys(categoriesConsent).reduce(
50+
(acc, category) => ({ ...acc, [category]: value }),
51+
{},
52+
)
53+
54+
const handleClick = (consentForAll: boolean) => () => {
55+
saveConsent(setAllConsents({ categoriesConsent, value: consentForAll }))
56+
}
57+
58+
const onAgreeAll = handleClick(true)
59+
60+
const onReject = handleClick(false)
61+
62+
return (
63+
<div className={styles.consent}>
64+
<div>Do you accept consents ?</div>
65+
<div>
66+
<Button onClick={onAgreeAll} autoFocus>
67+
Accept
68+
</Button>
69+
<Button onClick={onReject}>Decline</Button>
70+
</div>
71+
</div>
72+
)
73+
}
74+
```
75+
76+
### User flow
77+
78+
```mermaid
79+
flowchart TD
80+
Z[Application boot] -..-> A
81+
subgraph "Cookie Consent booting"
82+
A[First user navigation in app] --> B{isConsentRequired}
83+
B --> |false| C[do nothing with cookies]
84+
B --> |true| D[Fetch segment integrations configuration]
85+
D --> E[Generate hash of integration and define required consent categories depending on integration]
86+
E -..->F[Set needConsent to true]
87+
end
88+
subgraph "Consent storage"
89+
F -..-> | | G[/User saveConsent with categories/]
90+
G --> H[Hash of integration is stored in _scw_rgpd_hash cookie with storage of 6 months]
91+
G --> I[_scw_rgpd_$category$ cookie is stored for each accepted cookie consent category, 6 months for ad consent, 13 month for others]
92+
H & I --> J[needConsent is set to false]
93+
end
94+
subgraph "User come back on website in futur (within cookie duration)"
95+
J -..-> K[Application boot]
96+
K -..-> L[Check value fo cookies _scw_rgpd_hash and _scw_rgpd_$categorie$]
97+
L --> M[Load in context accepted categories]
98+
end
99+
subgraph "User come back after 6 months"
100+
J -...-> N[Application boot]
101+
N -..-> O[Check value fo cookies _scw_rgpd_hash and _scw_rgpd_$categorie$]
102+
O --> B
103+
end
104+
```
105+
106+
## How to contribute ?
107+
108+
### Prerequisites
109+
110+
```
111+
$ cd packages/cookie-consent
112+
```
113+
114+
### Start
115+
116+
```bash
117+
$ pnpm build # Build the package
118+
$ pnpm watch # Build the package and watch for changes
119+
```
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "@scaleway/cookie-consent",
3+
"version": "0.1.0",
4+
"description": "React provider to handle website end user consent cookie storage based on segment integrations",
5+
"type": "module",
6+
"sideEffects": false,
7+
"exports": {
8+
"types": "./dist/index.d.ts",
9+
"default": "./dist/index.js"
10+
},
11+
"publishConfig": {
12+
"access": "public"
13+
},
14+
"keywords": [
15+
"react",
16+
"reactjs",
17+
"hooks",
18+
"segment",
19+
"cookies",
20+
"gdpr"
21+
],
22+
"repository": {
23+
"type": "git",
24+
"url": "https://github.com/scaleway/scaleway-lib",
25+
"directory": "packages/cookie-consent"
26+
},
27+
"dependencies": {
28+
"cookie": "0.5.0"
29+
},
30+
"devDependencies": {
31+
"@types/cookie": "0.5.1",
32+
"react": "18.2.0"
33+
},
34+
"peerDependencies": {
35+
"react": "18.x || 18"
36+
}
37+
}

0 commit comments

Comments
 (0)