diff --git a/apps/basic-integration/react-router/react-router-v7-project/package-lock.json b/apps/basic-integration/react-router/react-router-v7-project/package-lock.json
index 2af43d735..197ab753b 100644
--- a/apps/basic-integration/react-router/react-router-v7-project/package-lock.json
+++ b/apps/basic-integration/react-router/react-router-v7-project/package-lock.json
@@ -6,10 +6,13 @@
"": {
"name": "rrv7-project",
"dependencies": {
+ "@posthog/react": "^1.9.0",
"@react-router/node": "^7.12.0",
"@react-router/serve": "^7.12.0",
"isbot": "^5.1.17",
"nanoid": "^5.1.6",
+ "posthog-js": "^1.372.6",
+ "posthog-node": "^5.32.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router": "^7.12.0"
@@ -988,6 +991,347 @@
"node": ">= 8"
}
},
+ "node_modules/@opentelemetry/api": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
+ "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@opentelemetry/api-logs": {
+ "version": "0.208.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.208.0.tgz",
+ "integrity": "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@opentelemetry/core": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz",
+ "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/exporter-logs-otlp-http": {
+ "version": "0.208.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.208.0.tgz",
+ "integrity": "sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/api-logs": "0.208.0",
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/otlp-exporter-base": "0.208.0",
+ "@opentelemetry/otlp-transformer": "0.208.0",
+ "@opentelemetry/sdk-logs": "0.208.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ }
+ },
+ "node_modules/@opentelemetry/otlp-exporter-base": {
+ "version": "0.208.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.208.0.tgz",
+ "integrity": "sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/otlp-transformer": "0.208.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ }
+ },
+ "node_modules/@opentelemetry/otlp-transformer": {
+ "version": "0.208.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.208.0.tgz",
+ "integrity": "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/api-logs": "0.208.0",
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/resources": "2.2.0",
+ "@opentelemetry/sdk-logs": "0.208.0",
+ "@opentelemetry/sdk-metrics": "2.2.0",
+ "@opentelemetry/sdk-trace-base": "2.2.0",
+ "protobufjs": "^7.3.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ }
+ },
+ "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz",
+ "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/resources": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz",
+ "integrity": "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.7.1",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/core": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.1.tgz",
+ "integrity": "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-logs": {
+ "version": "0.208.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.208.0.tgz",
+ "integrity": "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/api-logs": "0.208.0",
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/resources": "2.2.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.4.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz",
+ "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-metrics": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.2.0.tgz",
+ "integrity": "sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/resources": "2.2.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.9.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz",
+ "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-trace-base": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.2.0.tgz",
+ "integrity": "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/resources": "2.2.0",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz",
+ "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.2.0",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz",
+ "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@posthog/core": {
+ "version": "1.28.0",
+ "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.28.0.tgz",
+ "integrity": "sha512-753giUMWuk602UtS101tDZuNcwiKkr+3UEhLgfOwHAk2W32n53knOxAjyWT0JwMq5/+0uSQ2y4uaZXQAxwvBSw==",
+ "license": "MIT",
+ "dependencies": {
+ "@posthog/types": "1.372.6"
+ }
+ },
+ "node_modules/@posthog/react": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@posthog/react/-/react-1.9.0.tgz",
+ "integrity": "sha512-lVdTsWT5+PtHBu44gSQ7QohbLjAYqHkFAIGAQ+HV8Eh9yj+OcnQ7mXCmyhaMlTBD3z7D0H1eWMp4vQaFnsIyWQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": ">=16.8.0",
+ "posthog-js": ">=1.257.2",
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@posthog/types": {
+ "version": "1.372.6",
+ "resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.372.6.tgz",
+ "integrity": "sha512-sqI36LBvuo8xcYsXIlVa0q3IXJJjqtatM2LrXlyOM7kgHrldBwS4ldzaTXrTdpe/TiIl1b4ZHxtSHMzPig+DnQ==",
+ "license": "MIT"
+ },
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
+ "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.1.tgz",
+ "integrity": "sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
+ "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/@react-router/dev": {
"version": "7.12.0",
"resolved": "https://registry.npmjs.org/@react-router/dev/-/dev-7.12.0.tgz",
@@ -1493,7 +1837,6 @@
"version": "20.19.29",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.29.tgz",
"integrity": "sha512-YrT9ArrGaHForBaCNwFjoqJWmn8G1Pr7+BH/vwyLHciA9qT/wSiuOhxGCT50JA5xLvFBd6PIiGkE3afxcPE1nw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@@ -1503,7 +1846,7 @@
"version": "19.2.8",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.8.tgz",
"integrity": "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.2.2"
@@ -1519,6 +1862,13 @@
"@types/react": "^19.2.0"
}
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -1958,6 +2308,17 @@
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
"license": "MIT"
},
+ "node_modules/core-js": {
+ "version": "3.49.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz",
+ "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -1975,7 +2336,7 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/debug": {
@@ -2044,6 +2405,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/dompurify": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.2.tgz",
+ "integrity": "sha512-lHeS9SA/IKeIFFyYciHBr2n0v1VMPlSj843HdLOwjb2OxNwdq9Xykxqhk+FE42MzAdHvInbAolSE4mhahPpjXA==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -2302,6 +2672,12 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fflate": {
+ "version": "0.4.8",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
+ "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==",
+ "license": "MIT"
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -2707,6 +3083,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0"
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -3260,6 +3642,57 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
+ "node_modules/posthog-js": {
+ "version": "1.372.6",
+ "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.372.6.tgz",
+ "integrity": "sha512-+Fy9fwWni5WDKQXiUBIzFvdmnZSR6OBxGC/4wj09JvvK5JE4dhI9ZlKO1+b887PowjeAx0sx1Tf+S1eAjDvzqg==",
+ "license": "SEE LICENSE IN LICENSE",
+ "dependencies": {
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/api-logs": "^0.208.0",
+ "@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
+ "@opentelemetry/resources": "^2.2.0",
+ "@opentelemetry/sdk-logs": "^0.208.0",
+ "@posthog/core": "1.28.0",
+ "@posthog/types": "1.372.6",
+ "core-js": "^3.38.1",
+ "dompurify": "^3.3.2",
+ "fflate": "^0.4.8",
+ "preact": "^10.28.2",
+ "query-selector-shadow-dom": "^1.0.1",
+ "web-vitals": "^5.1.0"
+ }
+ },
+ "node_modules/posthog-node": {
+ "version": "5.32.1",
+ "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.32.1.tgz",
+ "integrity": "sha512-xO9ux41jZS1ZlXSGsQGzFVLtLkHbg7ss8+F9nWAtaliu+MFhR4J3FYOor688GNvuYwY8WNNdJjp9ASP7dDJk7w==",
+ "license": "MIT",
+ "dependencies": {
+ "@posthog/core": "1.28.0"
+ },
+ "engines": {
+ "node": "^20.20.0 || >=22.22.0"
+ },
+ "peerDependencies": {
+ "rxjs": "^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rxjs": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.29.1",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.1.tgz",
+ "integrity": "sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
"node_modules/prettier": {
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
@@ -3276,6 +3709,30 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
+ "node_modules/protobufjs": {
+ "version": "7.5.6",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.6.tgz",
+ "integrity": "sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.5",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.1",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.1",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -3304,6 +3761,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/query-selector-shadow-dom": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz",
+ "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==",
+ "license": "MIT"
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -4038,7 +4501,6 @@
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/unpipe": {
@@ -4231,6 +4693,12 @@
}
}
},
+ "node_modules/web-vitals": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-5.2.0.tgz",
+ "integrity": "sha512-i2z98bEmaCqSDiHEDu+gHl/dmR4Q+TxFmG3/13KkMO+o8UxQzCqWaDRCiLgEa41nlO4VpXSI0ASa1xWmO9sBlA==",
+ "license": "Apache-2.0"
+ },
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
diff --git a/apps/basic-integration/react-router/react-router-v7-project/package.json b/apps/basic-integration/react-router/react-router-v7-project/package.json
index 8d95f4f82..510953b97 100644
--- a/apps/basic-integration/react-router/react-router-v7-project/package.json
+++ b/apps/basic-integration/react-router/react-router-v7-project/package.json
@@ -9,10 +9,13 @@
"typecheck": "react-router typegen && tsc"
},
"dependencies": {
+ "@posthog/react": "^1.9.0",
"@react-router/node": "^7.12.0",
"@react-router/serve": "^7.12.0",
"isbot": "^5.1.17",
"nanoid": "^5.1.6",
+ "posthog-js": "^1.372.6",
+ "posthog-node": "^5.32.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router": "^7.12.0"
diff --git a/apps/basic-integration/react-router/react-router-v7-project/posthog-setup-report.md b/apps/basic-integration/react-router/react-router-v7-project/posthog-setup-report.md
new file mode 100644
index 000000000..50f6ad561
--- /dev/null
+++ b/apps/basic-integration/react-router/react-router-v7-project/posthog-setup-report.md
@@ -0,0 +1,63 @@
+
+# PostHog post-wizard report
+
+The wizard has completed a deep integration of PostHog into this React Router v7 (Framework mode) project — RESTExplorer, a country-claiming social app. The integration covers client-side SDK initialization, server-side middleware, user identification, event tracking across all key user flows, and error boundary capture.
+
+## Summary of changes
+
+| File | Change |
+|------|--------|
+| `app/entry.client.tsx` | Initialized `posthog-js` with `PostHogProvider` wrapping the app; enabled tracing headers for client↔server correlation |
+| `app/lib/posthog-middleware.ts` | **New file** — server-side PostHog middleware using `posthog-node`; extracts session/distinct ID from request headers and attaches the client to route context |
+| `app/root.tsx` | Registered `posthogMiddleware`; added `usePostHog().captureException()` to the `ErrorBoundary` for automatic error tracking |
+| `react-router.config.ts` | Enabled `v8_middleware: true` future flag (required for middleware support) |
+| `vite.config.ts` | Added `ssr.noExternal` for `posthog-js` and `@posthog/react`; added reverse proxy config for `/ingest/*` routes |
+| `.env` | Set `VITE_PUBLIC_POSTHOG_PROJECT_TOKEN` and `VITE_PUBLIC_POSTHOG_HOST` |
+| `app/routes/login.tsx` | `posthog.identify()` + `user_logged_in` capture on successful login |
+| `app/routes/signup.tsx` | `posthog.identify()` + `user_signed_up` capture on successful signup |
+| `app/routes/profile.tsx` | `user_logged_out` capture + `posthog.reset()` on logout button click |
+| `app/routes/countries.tsx` | `country_claimed`, `country_liked`, `country_visited`, `country_region_filtered`, and `achievement_unlocked` captures |
+| `app/routes/home.tsx` | `explore_now_clicked` capture on the "Explore Now" CTA (top of conversion funnel) |
+| `app/routes/stats.tsx` | `leaderboard_viewed` capture with user rank and point stats |
+
+## Events tracked
+
+| Event | Description | File |
+|-------|-------------|------|
+| `user_signed_up` | User successfully creates a new account | `app/routes/signup.tsx` |
+| `user_logged_in` | User successfully logs in to an existing account | `app/routes/login.tsx` |
+| `user_logged_out` | User clicks the logout button from their profile | `app/routes/profile.tsx` |
+| `country_claimed` | User claims a country (earns 100 pts). Props: `country`, `region` | `app/routes/countries.tsx` |
+| `country_liked` | User likes a country (earns 10 pts). Props: `country`, `region` | `app/routes/countries.tsx` |
+| `country_visited` | User marks a country as visited (earns 50 pts). Props: `country`, `region` | `app/routes/countries.tsx` |
+| `country_region_filtered` | User filters the countries list by region. Props: `region` | `app/routes/countries.tsx` |
+| `explore_now_clicked` | User clicks the "Explore Now" CTA on the home page — top of conversion funnel | `app/routes/home.tsx` |
+| `achievement_unlocked` | User unlocks a new achievement. Props: `achievement_name` | `app/routes/countries.tsx` |
+| `leaderboard_viewed` | Authenticated user views the stats/leaderboard page. Props: `user_rank`, `total_points`, `claimed_countries` | `app/routes/stats.tsx` |
+
+## Next steps
+
+We recommend building these insights and a dashboard in PostHog to keep an eye on user behavior, based on the events instrumented:
+
+1. **Conversion funnel** — Track the signup funnel: `explore_now_clicked` → `user_signed_up` → `country_claimed`
+ [Create funnel insight](https://us.posthog.com/project/2/insights/new?insight=FUNNELS)
+
+2. **Engagement trends** — Trend of `country_claimed`, `country_liked`, and `country_visited` over time
+ [Create trends insight](https://us.posthog.com/project/2/insights/new?insight=TRENDS)
+
+3. **New signups over time** — Daily/weekly `user_signed_up` events as a growth metric
+ [Create trends insight](https://us.posthog.com/project/2/insights/new?insight=TRENDS)
+
+4. **Achievement unlock rate** — `achievement_unlocked` events broken down by `achievement_name`
+ [Create trends insight](https://us.posthog.com/project/2/insights/new?insight=TRENDS)
+
+5. **Churn signal** — `user_logged_out` trend over time — a spike may indicate disengagement
+ [Create trends insight](https://us.posthog.com/project/2/insights/new?insight=TRENDS)
+
+[Create a new "Analytics basics" dashboard](https://us.posthog.com/project/2/dashboards)
+
+### Agent skill
+
+We've left an agent skill folder in your project at `.claude/skills/integration-react-react-router-7-framework/`. You can use this context for further agent development when using Claude Code. This will help ensure the model provides the most up-to-date approaches for integrating PostHog.
+
+
diff --git a/apps/basic-integration/react-router/react-router-v7-project/react-router.config.ts b/apps/basic-integration/react-router/react-router-v7-project/react-router.config.ts
index 6ff16f917..f286789d5 100644
--- a/apps/basic-integration/react-router/react-router-v7-project/react-router.config.ts
+++ b/apps/basic-integration/react-router/react-router-v7-project/react-router.config.ts
@@ -4,4 +4,7 @@ export default {
// Config options...
// Server-side render by default, to enable SPA mode set this to `false`
ssr: true,
+ future: {
+ v8_middleware: true,
+ },
} satisfies Config;
diff --git a/apps/basic-integration/react-router/react-router-v7-project/vite.config.ts b/apps/basic-integration/react-router/react-router-v7-project/vite.config.ts
index cbf229d1a..416d5e57e 100644
--- a/apps/basic-integration/react-router/react-router-v7-project/vite.config.ts
+++ b/apps/basic-integration/react-router/react-router-v7-project/vite.config.ts
@@ -1,10 +1,12 @@
import { reactRouter } from "@react-router/dev/vite";
import autoprefixer from "autoprefixer";
import tailwindcss from "tailwindcss";
-import { defineConfig } from "vite";
+import { defineConfig, loadEnv } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
-export default defineConfig(() => {
+export default defineConfig(({ mode }) => {
+ const env = loadEnv(mode, process.cwd(), '');
+
return {
css: {
postcss: {
@@ -12,5 +14,27 @@ export default defineConfig(() => {
},
},
plugins: [reactRouter(), tsconfigPaths()],
+ ssr: {
+ noExternal: ['posthog-js', '@posthog/react'],
+ },
+ server: {
+ proxy: {
+ '/ingest/static': {
+ target: 'https://us-assets.i.posthog.com',
+ changeOrigin: true,
+ rewrite: (path) => path.replace(/^\/ingest/, ''),
+ },
+ '/ingest/array': {
+ target: 'https://us-assets.i.posthog.com',
+ changeOrigin: true,
+ rewrite: (path) => path.replace(/^\/ingest/, ''),
+ },
+ '/ingest': {
+ target: env.VITE_PUBLIC_POSTHOG_HOST || 'https://us.i.posthog.com',
+ changeOrigin: true,
+ rewrite: (path) => path.replace(/^\/ingest/, ''),
+ },
+ },
+ },
};
});