Skip to content

Commit 20116af

Browse files
authored
refactor(gdpr-cookie-consent): Switch to V2 + Vite (#510)
* refactor(gdpr-cookie-consent): Switch to V2 + Vite * lint * use useRouteLoaderData instead of useLoaderData, and call it out
1 parent 4dea3c4 commit 20116af

File tree

12 files changed

+169
-61
lines changed

12 files changed

+169
-61
lines changed

gdpr-cookie-consent/.eslintrc.cjs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* This is intended to be a basic starting point for linting in your app.
3+
* It relies on recommended configs out of the box for simplicity, but you can
4+
* and should modify this configuration to best suit your team's needs.
5+
*/
6+
7+
/** @type {import('eslint').Linter.Config} */
8+
module.exports = {
9+
root: true,
10+
parserOptions: {
11+
ecmaVersion: "latest",
12+
sourceType: "module",
13+
ecmaFeatures: {
14+
jsx: true,
15+
},
16+
},
17+
env: {
18+
browser: true,
19+
commonjs: true,
20+
es6: true,
21+
},
22+
ignorePatterns: ["!**/.server", "!**/.client"],
23+
24+
// Base config
25+
extends: ["eslint:recommended"],
26+
27+
overrides: [
28+
// React
29+
{
30+
files: ["**/*.{js,jsx,ts,tsx}"],
31+
plugins: ["react", "jsx-a11y"],
32+
extends: [
33+
"plugin:react/recommended",
34+
"plugin:react/jsx-runtime",
35+
"plugin:react-hooks/recommended",
36+
"plugin:jsx-a11y/recommended",
37+
],
38+
settings: {
39+
react: {
40+
version: "detect",
41+
},
42+
formComponents: ["Form"],
43+
linkComponents: [
44+
{ name: "Link", linkAttribute: "to" },
45+
{ name: "NavLink", linkAttribute: "to" },
46+
],
47+
"import/resolver": {
48+
typescript: {},
49+
},
50+
},
51+
},
52+
53+
// Typescript
54+
{
55+
files: ["**/*.{ts,tsx}"],
56+
plugins: ["@typescript-eslint", "import"],
57+
parser: "@typescript-eslint/parser",
58+
settings: {
59+
"import/internal-regex": "^~/",
60+
"import/resolver": {
61+
node: {
62+
extensions: [".ts", ".tsx"],
63+
},
64+
typescript: {
65+
alwaysTryTypes: true,
66+
},
67+
},
68+
},
69+
extends: [
70+
"plugin:@typescript-eslint/recommended",
71+
"plugin:import/recommended",
72+
"plugin:import/typescript",
73+
],
74+
},
75+
76+
// Node
77+
{
78+
files: [".eslintrc.cjs"],
79+
env: {
80+
node: true,
81+
},
82+
},
83+
],
84+
};

gdpr-cookie-consent/.eslintrc.js

Lines changed: 0 additions & 4 deletions
This file was deleted.

gdpr-cookie-consent/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ node_modules
22

33
/.cache
44
/build
5-
/public/build
65
.env

gdpr-cookie-consent/README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# GDPR Cookie Consent
22

3-
Create a simple GDPR consent form.
4-
Till the user doesn't click on the `Accept` button, she will see a banner prompting to accept cookies.
3+
Create a simple GDPR consent form, displayed until the button click the `Accept` button.
54

65
## Preview
76

@@ -14,7 +13,7 @@ Open this example on [CodeSandbox](https://codesandbox.com):
1413
Users will be presented with a GDPR consent form on every page [app/root.tsx](app/root.tsx) till they submit the accept button.
1514
Once they submit the consent form, a dummy tracking [script](public/dummy-analytics-script.js) at the [app/root.tsx](app/root.tsx) will start tracking the user's data (open the browser console too see the dummy tracking message).
1615

17-
> If you want to reset the example delete the `gdpr-consent` cookie in the `Application`/`cookies` in the browser's developer tools.
16+
> If you want to reset the example, delete the `gdpr-consent` cookie in the `Application`/`cookies` in the browser's developer tools.
1817
1918
The example is using [Remix Cookie API](https://remix.run/utils/cookies).
2019

File renamed without changes.

gdpr-cookie-consent/app/root.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,53 @@
1-
import type { LoaderArgs, MetaFunction } from "@remix-run/node";
2-
import { json } from "@remix-run/node";
1+
import type { LoaderFunctionArgs } from "@remix-run/node";
32
import {
43
Links,
5-
LiveReload,
64
Meta,
75
Outlet,
86
Scripts,
97
ScrollRestoration,
8+
json,
109
useFetcher,
11-
useLoaderData,
10+
useRouteLoaderData,
1211
} from "@remix-run/react";
13-
import * as React from "react";
12+
import { useEffect } from "react";
1413

15-
import { gdprConsent } from "~/cookies";
14+
import { gdprConsent } from "~/cookies.server";
1615

17-
export const loader = async ({ request }: LoaderArgs) => {
16+
export const loader = async ({ request }: LoaderFunctionArgs) => {
1817
const cookieHeader = request.headers.get("Cookie");
1918
const cookie = (await gdprConsent.parse(cookieHeader)) || {};
19+
2020
return json({ track: cookie.gdprConsent });
2121
};
2222

23-
export const meta: MetaFunction = () => ({
24-
charset: "utf-8",
25-
title: "New Remix App",
26-
viewport: "width=device-width,initial-scale=1",
27-
});
23+
export function Layout({ children }: { children: React.ReactNode }) {
24+
// We use `useRouteLoaderData` here instead of `useLoaderData` because
25+
// the <Layout /> component will also be used by the <ErrorBoundary />
26+
// if an error is thrown somewhere in the app, and we can't call
27+
// `useLoaderData()` while rendering an <ErrorBoundary />.
28+
const rootLoaderData = useRouteLoaderData<{ track?: true }>("root");
29+
const track = rootLoaderData?.track ?? false;
2830

29-
export default function App() {
30-
const { track } = useLoaderData<typeof loader>();
31-
const analyticsFetcher = useFetcher();
32-
React.useEffect(() => {
31+
useEffect(() => {
3332
if (track) {
3433
const script = document.createElement("script");
3534
script.src = "/dummy-analytics-script.js";
3635
document.body.append(script);
3736
}
3837
}, [track]);
3938

39+
const analyticsFetcher = useFetcher();
40+
4041
return (
4142
<html lang="en">
4243
<head>
44+
<meta charSet="utf-8" />
45+
<meta name="viewport" content="width=device-width, initial-scale=1" />
4346
<Meta />
4447
<Links />
4548
</head>
4649
<body>
47-
<Outlet />
50+
{children}
4851
{track ? null : (
4952
<div
5053
style={{
@@ -64,8 +67,11 @@ export default function App() {
6467
)}
6568
<ScrollRestoration />
6669
<Scripts />
67-
<LiveReload />
6870
</body>
6971
</html>
7072
);
7173
}
74+
75+
export default function App() {
76+
return <Outlet />;
77+
}

gdpr-cookie-consent/app/routes/enable-analytics.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import type { ActionArgs } from "@remix-run/node";
1+
import type { ActionFunctionArgs } from "@remix-run/node";
22
import { json } from "@remix-run/node";
33

4-
import { gdprConsent } from "~/cookies";
4+
import { gdprConsent } from "~/cookies.server";
55

6-
export const action = async ({ request }: ActionArgs) => {
6+
export const action = async ({ request }: ActionFunctionArgs) => {
77
const formData = await request.formData();
88
const cookieHeader = request.headers.get("Cookie");
99
const cookie = (await gdprConsent.parse(cookieHeader)) || {};

gdpr-cookie-consent/package.json

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,40 @@
11
{
2+
"name": "gdpr-cookie-consent",
23
"private": true,
34
"sideEffects": false,
5+
"type": "module",
46
"scripts": {
5-
"build": "remix build",
6-
"dev": "remix dev",
7-
"start": "remix-serve build",
7+
"build": "remix vite:build",
8+
"dev": "remix vite:dev",
9+
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
10+
"start": "remix-serve ./build/server/index.js",
811
"typecheck": "tsc"
912
},
1013
"dependencies": {
11-
"@remix-run/node": "^1.19.3",
12-
"@remix-run/react": "^1.19.3",
13-
"@remix-run/serve": "^1.19.3",
14-
"isbot": "^3.6.5",
14+
"@remix-run/node": "^2.9.2",
15+
"@remix-run/react": "^2.9.2",
16+
"@remix-run/serve": "^2.9.2",
17+
"isbot": "^4.1.0",
1518
"react": "^18.2.0",
1619
"react-dom": "^18.2.0"
1720
},
1821
"devDependencies": {
19-
"@remix-run/dev": "^1.19.3",
20-
"@remix-run/eslint-config": "^1.19.3",
21-
"@types/react": "^18.0.25",
22-
"@types/react-dom": "^18.0.8",
23-
"eslint": "^8.27.0",
24-
"typescript": "^4.8.4"
22+
"@remix-run/dev": "^2.9.2",
23+
"@types/react": "^18.2.20",
24+
"@types/react-dom": "^18.2.7",
25+
"@typescript-eslint/eslint-plugin": "^6.7.4",
26+
"@typescript-eslint/parser": "^6.7.4",
27+
"eslint": "^8.38.0",
28+
"eslint-import-resolver-typescript": "^3.6.1",
29+
"eslint-plugin-import": "^2.28.1",
30+
"eslint-plugin-jsx-a11y": "^6.7.1",
31+
"eslint-plugin-react": "^7.33.2",
32+
"eslint-plugin-react-hooks": "^4.6.0",
33+
"typescript": "^5.1.6",
34+
"vite": "^5.1.0",
35+
"vite-tsconfig-paths": "^4.2.1"
2536
},
2637
"engines": {
27-
"node": ">=14.0.0"
38+
"node": ">=20.0.0"
2839
}
2940
}

gdpr-cookie-consent/remix.config.js

Lines changed: 0 additions & 11 deletions
This file was deleted.

gdpr-cookie-consent/remix.env.d.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)