From 721a3d5b3cb2e8b0dbe21fd9546859e2eac3ce4c Mon Sep 17 00:00:00 2001
From: Ben White
Date: Wed, 24 Apr 2024 13:36:39 +0200
Subject: [PATCH] chore: Update nextjs project to have more realistic controls
(#1151)
---
README.md | 16 +-
package.json | 5 +-
playground/nextjs/.gitignore | 2 +
playground/nextjs/package.json | 7 +-
playground/nextjs/pages/_app.tsx | 23 ++-
playground/nextjs/pages/_document.tsx | 3 +-
playground/nextjs/pages/animations.tsx | 57 -------
playground/nextjs/pages/api/auth/login.ts | 16 ++
playground/nextjs/pages/api/auth/logout.ts | 13 ++
playground/nextjs/pages/iframe.tsx | 41 -----
playground/nextjs/pages/index.tsx | 141 ++++++++----------
playground/nextjs/pages/long.tsx | 34 -----
playground/nextjs/pages/longmain.tsx | 70 ---------
playground/nextjs/pages/media.tsx | 29 ----
.../pages/replay-examples/animations.tsx | 46 ++++++
.../pages/{ => replay-examples}/canvas.tsx | 13 +-
.../nextjs/pages/replay-examples/iframe.tsx | 34 +++++
.../nextjs/pages/replay-examples/long.tsx | 27 ++++
.../nextjs/pages/replay-examples/media.tsx | 24 +++
playground/nextjs/pnpm-lock.yaml | 31 +++-
playground/nextjs/src/AuthModal.tsx | 95 ++++++++++++
playground/nextjs/src/Header.tsx | 44 ++++++
playground/nextjs/src/auth.ts | 61 ++++++++
playground/nextjs/src/posthog.ts | 49 +++++-
24 files changed, 530 insertions(+), 351 deletions(-)
delete mode 100644 playground/nextjs/pages/animations.tsx
create mode 100644 playground/nextjs/pages/api/auth/login.ts
create mode 100644 playground/nextjs/pages/api/auth/logout.ts
delete mode 100644 playground/nextjs/pages/iframe.tsx
delete mode 100644 playground/nextjs/pages/long.tsx
delete mode 100644 playground/nextjs/pages/longmain.tsx
delete mode 100644 playground/nextjs/pages/media.tsx
create mode 100644 playground/nextjs/pages/replay-examples/animations.tsx
rename playground/nextjs/pages/{ => replay-examples}/canvas.tsx (91%)
create mode 100644 playground/nextjs/pages/replay-examples/iframe.tsx
create mode 100644 playground/nextjs/pages/replay-examples/long.tsx
create mode 100644 playground/nextjs/pages/replay-examples/media.tsx
create mode 100644 playground/nextjs/src/AuthModal.tsx
create mode 100644 playground/nextjs/src/Header.tsx
create mode 100644 playground/nextjs/src/auth.ts
diff --git a/README.md b/README.md
index 0f974354a..814401078 100644
--- a/README.md
+++ b/README.md
@@ -49,23 +49,15 @@ You can use the create react app setup in `playground/nextjs` to test posthog-js
## Developing together with another project
-Install Yalc to link a local version of `posthog-js` in another JS project: `npm install -g yalc`
+Install pnpm to link a local version of `posthog-js` in another JS project: `npm install -g pnpm`
#### Run this to link the local version
-- In the `posthog-js` directory: `yalc publish`
-- In the other directory: `yalc add posthog-js`, then install dependencies
- (for `posthog` this means: `yalc add posthog-js && pnpm i && pnpm copy-scripts`)
-#### Run this to update the linked local version
+- In the `posthog-js` directory: `pnpm link --global`
+- (for `posthog` this means: `pnpm link --global posthog-js && pnpm i && pnpm copy-scripts`)
+- You can then remove the link with `pnpm link --global posthog-js
-- In the other directory: `yalc update`, then install dependencies
- (for `posthog` this means: `yalc update && pnpm i && pnpm copy-scripts`)
-
-#### Run this to unlink the local version
-
-- In the other directory: `yalc remove posthog-js`, then install dependencies
- (for `posthog` this means: `yalc remove posthog-js && pnpm i && pnpm copy-scripts`)
## Releasing a new version
diff --git a/package.json b/package.json
index 3086d7601..d2cf208a2 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"start": "pnpm build-react && pnpm build-rollup -w",
"build": "pnpm build-rollup && pnpm build-react",
"build-rollup": "rm -rf lib && tsc -b && rollup -c --bundleConfigAsCjs",
- "build-react": "cd react; pnpm i; pnpm build;",
+ "build-react": "cd react; NODE_ENV=dev pnpm i; pnpm build;",
"lint": "eslint src && eslint cypress",
"prettier": "prettier --write src/ functional_tests/",
"prepublishOnly": "pnpm lint && pnpm test && pnpm build && pnpm test:react",
@@ -20,8 +20,7 @@
"test:functional": "jest functional_tests",
"test-watch": "jest --watch src",
"cypress": "cypress open",
- "prepare": "husky install",
- "yalc-publish": "yalc publish"
+ "prepare": "husky install"
},
"main": "dist/module.js",
"module": "dist/es.js",
diff --git a/playground/nextjs/.gitignore b/playground/nextjs/.gitignore
index c87c9b392..81740d43d 100644
--- a/playground/nextjs/.gitignore
+++ b/playground/nextjs/.gitignore
@@ -34,3 +34,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+.next/
+.yalc
\ No newline at end of file
diff --git a/playground/nextjs/package.json b/playground/nextjs/package.json
index 9182d4fe2..bd9ad14c5 100644
--- a/playground/nextjs/package.json
+++ b/playground/nextjs/package.json
@@ -5,9 +5,10 @@
"scripts": {
"clean-react": "cd ../../react && rm -rf ./node_modules/",
"dev": "pnpm run link-posthog-js && pnpm run clean-react && next dev",
- "build": "next build",
+ "build": "pnpm run build-posthog-js && pnpm run link-posthog-js && pnpm run clean-react && next build",
"start": "next start",
"lint": "next lint",
+ "build-posthog-js": "cd ../../ && NODE_ENV=dev pnpm i && pnpm run build",
"link-posthog-js": "cd ../../ && pnpm link --global && cd playground/nextjs && pnpm link --global posthog-js"
},
"dependencies": {
@@ -15,15 +16,17 @@
"@types/node": "18.13.0",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.10",
+ "cookie": "^0.6.0",
"eslint": "8.34.0",
"eslint-config-next": "13.1.6",
"next": "13.5.6",
- "posthog-js": "1.120.3",
+ "posthog-js": "1.128.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "4.9.5"
},
"devDependencies": {
+ "@types/cookie": "^0.6.0",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.35",
"tailwindcss": "^3.4.1"
diff --git a/playground/nextjs/pages/_app.tsx b/playground/nextjs/pages/_app.tsx
index 9c4a0e66b..d6d550995 100644
--- a/playground/nextjs/pages/_app.tsx
+++ b/playground/nextjs/pages/_app.tsx
@@ -8,10 +8,22 @@ import posthog from 'posthog-js'
import { PostHogProvider } from 'posthog-js/react'
import { CookieBanner } from '@/src/CookieBanner'
import '@/src/posthog'
+import Head from 'next/head'
+import { PageHeader } from '@/src/Header'
+import { useUser } from '@/src/auth'
+import { posthogHelpers } from '@/src/posthog'
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter()
+ const user = useUser()
+
+ useEffect(() => {
+ if (user) {
+ posthogHelpers.setUser(user)
+ }
+ }, [user])
+
useEffect(() => {
// Track page views
const handleRouteChange = () => posthog.capture('$pageview')
@@ -24,9 +36,16 @@ export default function App({ Component, pageProps }: AppProps) {
return (
-
+
+ PostHog
+
+
-
+
+
+
+
+
)
}
diff --git a/playground/nextjs/pages/_document.tsx b/playground/nextjs/pages/_document.tsx
index 4984c17fa..d586b3595 100644
--- a/playground/nextjs/pages/_document.tsx
+++ b/playground/nextjs/pages/_document.tsx
@@ -5,10 +5,11 @@ export default function Document() {
return (
+
-
+
)
}
diff --git a/playground/nextjs/pages/animations.tsx b/playground/nextjs/pages/animations.tsx
deleted file mode 100644
index 73ca0d043..000000000
--- a/playground/nextjs/pages/animations.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import Head from 'next/head'
-import { useFeatureFlagEnabled, usePostHog } from 'posthog-js/react'
-import { useEffect, useState } from 'react'
-import { Player, Controls } from '@lottiefiles/react-lottie-player'
-
-export default function Home() {
- const posthog = usePostHog()
-
- return (
- <>
-
- PostHog
-
-
-
- Animations
- Useful testing for Replay handling heavy animations
-
-
-
-
- >
- )
-}
diff --git a/playground/nextjs/pages/api/auth/login.ts b/playground/nextjs/pages/api/auth/login.ts
new file mode 100644
index 000000000..2c8ecdf9f
--- /dev/null
+++ b/playground/nextjs/pages/api/auth/login.ts
@@ -0,0 +1,16 @@
+import { serialize } from 'cookie'
+import type { NextApiRequest, NextApiResponse } from 'next'
+
+export default function handler(req: NextApiRequest, res: NextApiResponse) {
+ const sessionData = req.body
+ const encryptedSessionData = JSON.stringify(sessionData)
+
+ const cookie = serialize('session', encryptedSessionData, {
+ httpOnly: false,
+ secure: false,
+ maxAge: 60 * 60 * 24 * 7, // One week
+ path: '/',
+ })
+ res.setHeader('Set-Cookie', cookie)
+ res.status(200).json({ message: 'Successfully set cookie!' })
+}
diff --git a/playground/nextjs/pages/api/auth/logout.ts b/playground/nextjs/pages/api/auth/logout.ts
new file mode 100644
index 000000000..7820928bc
--- /dev/null
+++ b/playground/nextjs/pages/api/auth/logout.ts
@@ -0,0 +1,13 @@
+import { serialize } from 'cookie'
+import type { NextApiRequest, NextApiResponse } from 'next'
+
+export default function handler(req: NextApiRequest, res: NextApiResponse) {
+ const cookie = serialize('session', '', {
+ httpOnly: false,
+ secure: false,
+ maxAge: 1, // One week
+ path: '/',
+ })
+ res.setHeader('Set-Cookie', cookie)
+ res.status(200).json({ message: 'Successfully cleared cookie!' })
+}
diff --git a/playground/nextjs/pages/iframe.tsx b/playground/nextjs/pages/iframe.tsx
deleted file mode 100644
index f96c427b9..000000000
--- a/playground/nextjs/pages/iframe.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import Head from 'next/head'
-import { usePostHog } from 'posthog-js/react'
-import { useEffect, useState } from 'react'
-
-export default function Home() {
- const posthog = usePostHog()
-
- const [otherHost, setOtherHost] = useState('')
-
- useEffect(() => {
- setOtherHost(window.location.origin.includes('other-localhost') ? 'localhost' : 'other-localhost')
- })
-
- return (
- <>
-
- PostHog
-
-
-
- Iframes
-
- Cross origin iframe
-
- This loads the same page but from other-localhost which you need to add to your hosts file.
-
-
- {otherHost && (
-
- >
- )
-}
diff --git a/playground/nextjs/pages/index.tsx b/playground/nextjs/pages/index.tsx
index 350c01053..f778ee510 100644
--- a/playground/nextjs/pages/index.tsx
+++ b/playground/nextjs/pages/index.tsx
@@ -1,13 +1,11 @@
-import Head from 'next/head'
-import { useFeatureFlagEnabled, usePostHog } from 'posthog-js/react'
+import { useActiveFeatureFlags, usePostHog } from 'posthog-js/react'
import React, { useEffect, useState } from 'react'
-import Link from 'next/link'
-import { cookieConsentGiven } from '@/src/posthog'
+import { PERSON_PROCESSING_MODE, cookieConsentGiven } from '@/src/posthog'
export default function Home() {
const posthog = usePostHog()
const [isClient, setIsClient] = useState(false)
- const result = useFeatureFlagEnabled('test')
+ const flags = useActiveFeatureFlags()
const [time, setTime] = useState('')
const consentGiven = cookieConsentGiven()
@@ -27,80 +25,65 @@ export default function Home() {
return (
<>
-
- PostHog
-
-
-
-
-
- PostHog React
-
-
-
- The current time is {time}
-
-
-
posthog.capture('Clicked button')}>Capture event
-
Autocapture buttons
-
- Autocapture a > span
-
-
-
Ignore certain elements
-
-
posthog?.identify('user-' + randomID())}>Identify
-
-
- posthog?.setPersonProperties({
- email: `user-${randomID()}@posthog.com`,
- })
- }
- >
- Set user properties
-
-
-
posthog?.reset()}>Reset
-
-
-
- Animations
- Iframe
- Canvas
- Media
- Long
- Long Main
-
-
- Feature flag response: {JSON.stringify(result)}
-
- {isClient && (
- <>
- {!consentGiven && (
-
- Consent not given! Session recording, surveys, and autocapture are disabled.
-
- )}
-
- PostHog info
-
-
- DistinctID: {posthog.get_distinct_id()}
-
-
- SessionID: {posthog.get_session_id()}
-
-
-
-
- PostHog config
-
- {JSON.stringify(posthog.config, null, 2)}
-
- >
- )}
-
+ The current time is {time}
+
+ Trigger posthog events
+
+
posthog.capture('Clicked button')}>Capture event
+
Autocapture buttons
+
+ Autocapture a > span
+
+
+
Ignore certain elements
+
+
+ posthog?.setPersonProperties({
+ email: `user-${randomID()}@posthog.com`,
+ })
+ }
+ >
+ Set user properties
+
+
+
posthog?.reset()}>Reset
+
+
+ {isClient && (
+ <>
+ {!consentGiven && (
+
+ Consent not given! Session recording, surveys, and autocapture are disabled.
+
+ )}
+
+ PostHog info
+
+
+ PostHog config
+
+ {JSON.stringify(posthog.config, null, 2)}
+
+ >
+ )}
>
)
}
diff --git a/playground/nextjs/pages/long.tsx b/playground/nextjs/pages/long.tsx
deleted file mode 100644
index e08d77981..000000000
--- a/playground/nextjs/pages/long.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import Head from 'next/head'
-import Link from 'next/link'
-import React from 'react'
-
-export default function Home() {
- return (
- <>
-
- PostHog
-
-
-
- A long page
-
- Home
-
-
- {Array.from({ length: 100 }, (_, i) => (
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
- labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
- laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
- voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
- non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
-
- ))}
-
-
- Home
-
-
- >
- )
-}
diff --git a/playground/nextjs/pages/longmain.tsx b/playground/nextjs/pages/longmain.tsx
deleted file mode 100644
index dcf5fb245..000000000
--- a/playground/nextjs/pages/longmain.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import Head from 'next/head'
-import Link from 'next/link'
-import React, { useEffect } from 'react'
-
-export default function Home() {
- useEffect(() => {
- const html = document.querySelector('html')
- const body = document.querySelector('body')
- const nextRoot = document.querySelector('div#__next')
- if (!html || !body || !nextRoot) return
- html.style.height = '100%'
- html.style.overflow = 'hidden'
- body.style.height = '100%'
- nextRoot.style.height = '100%'
- return () => {
- html.style.height = ''
- html.style.overflow = ''
- body.style.height = ''
- nextRoot.style.height = ''
- }
- }, [])
-
- return (
- <>
-
- PostHog
-
-
-
-
-
A long page
-
- The window itself does not scroll, the main
element does. The content is exactly
- 4000px tall.
-
-
- Home
-
-
- {Array.from({ length: 100 }, (_, i) => (
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
- labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
- laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
- voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
- cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
-
- ))}
-
-
- Home
-
-
-
- >
- )
-}
diff --git a/playground/nextjs/pages/media.tsx b/playground/nextjs/pages/media.tsx
deleted file mode 100644
index 963963925..000000000
--- a/playground/nextjs/pages/media.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import Head from 'next/head'
-
-export default function Home() {
- return (
- <>
-
- PostHog
-
-
-
- Video
- Useful testing for Replay handling video elements
-
-
Video
-
-
-
-
-
-
-
- >
- )
-}
diff --git a/playground/nextjs/pages/replay-examples/animations.tsx b/playground/nextjs/pages/replay-examples/animations.tsx
new file mode 100644
index 000000000..8025b303d
--- /dev/null
+++ b/playground/nextjs/pages/replay-examples/animations.tsx
@@ -0,0 +1,46 @@
+import { Player } from '@lottiefiles/react-lottie-player'
+
+export default function Home() {
+ return (
+ <>
+ Animations
+ Useful testing for Replay handling heavy animations
+
+
+
+ >
+ )
+}
diff --git a/playground/nextjs/pages/canvas.tsx b/playground/nextjs/pages/replay-examples/canvas.tsx
similarity index 91%
rename from playground/nextjs/pages/canvas.tsx
rename to playground/nextjs/pages/replay-examples/canvas.tsx
index 7c96cd0a8..f24e4a98a 100644
--- a/playground/nextjs/pages/canvas.tsx
+++ b/playground/nextjs/pages/replay-examples/canvas.tsx
@@ -1,5 +1,4 @@
import React from 'react'
-import Head from 'next/head'
import { useEffect, useRef } from 'react'
export default function Canvas() {
@@ -110,15 +109,9 @@ export default function Canvas() {
return (
<>
-
- PostHog
-
-
-
- Canvas
-
-
-
+ Canvas
+
+
>
)
}
diff --git a/playground/nextjs/pages/replay-examples/iframe.tsx b/playground/nextjs/pages/replay-examples/iframe.tsx
new file mode 100644
index 000000000..ca8b6e21b
--- /dev/null
+++ b/playground/nextjs/pages/replay-examples/iframe.tsx
@@ -0,0 +1,34 @@
+import { usePostHog } from 'posthog-js/react'
+import { useEffect, useState } from 'react'
+
+export default function Home() {
+ const posthog = usePostHog()
+
+ const [otherHost, setOtherHost] = useState('')
+
+ useEffect(() => {
+ setOtherHost(window.location.origin.includes('other-localhost') ? 'localhost' : 'other-localhost')
+ })
+
+ return (
+ <>
+ Iframes
+
+ Cross origin iframe
+
+ This loads the same page but from other-localhost which you need to add to your hosts file.
+
+
+ {otherHost && (
+