From 655a4a159a1b4ab5e6c33da1cf1e9401cb6bd35e Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Tue, 19 Nov 2024 21:44:33 +0700 Subject: [PATCH 1/9] feat: initial setup posthog --- docs/package.json | 1 + web/app/layout.tsx | 12 ++++++++---- web/app/posthog.js | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 web/app/posthog.js diff --git a/docs/package.json b/docs/package.json index b2b74aba7..dddb88b04 100644 --- a/docs/package.json +++ b/docs/package.json @@ -36,6 +36,7 @@ "path": "^0.12.7", "plop": "^4.0.1", "plop-helper-date": "^1.0.0", + "posthog-js": "^1.186.3", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.51.1", diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 5f14d6f5c..29c44f19e 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -4,6 +4,8 @@ import { Metadata } from 'next' import '@/styles/main.scss' +import { CSPostHogProvider } from './posthog' + export const metadata: Metadata = { title: 'Jan', description: @@ -13,10 +15,12 @@ export const metadata: Metadata = { export default function RootLayout({ children }: PropsWithChildren) { return ( - -
- {children} - + + +
+ {children} + + ) } diff --git a/web/app/posthog.js b/web/app/posthog.js new file mode 100644 index 000000000..d6a6bf0bb --- /dev/null +++ b/web/app/posthog.js @@ -0,0 +1,14 @@ +'use client' + +import posthog from 'posthog-js' +import { PostHogProvider } from 'posthog-js/react' + +if (typeof window !== 'undefined') { + posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { + api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, + person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well + }) +} +export function CSPostHogProvider({ children }) { + return {children} +} From 9a8b76517cee19d04de8c3e90ce601f8cde6d466 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Wed, 20 Nov 2024 09:48:11 +0700 Subject: [PATCH 2/9] chore: disabled capture page view --- web/app/posthog.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/app/posthog.js b/web/app/posthog.js index d6a6bf0bb..1799f3b0d 100644 --- a/web/app/posthog.js +++ b/web/app/posthog.js @@ -7,6 +7,7 @@ if (typeof window !== 'undefined') { posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well + capture_pageview: false, }) } export function CSPostHogProvider({ children }) { From dd503767a29c5adc187361983125290df61b3aed Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Wed, 20 Nov 2024 13:35:55 +0700 Subject: [PATCH 3/9] chore: custom event ribbon icon click --- web/containers/Layout/RibbonPanel/index.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/web/containers/Layout/RibbonPanel/index.tsx b/web/containers/Layout/RibbonPanel/index.tsx index 13116dc16..45c4fd052 100644 --- a/web/containers/Layout/RibbonPanel/index.tsx +++ b/web/containers/Layout/RibbonPanel/index.tsx @@ -7,6 +7,7 @@ import { SquareCodeIcon, } from 'lucide-react' +import posthog from 'posthog-js' import { twMerge } from 'tailwind-merge' import { MainViewState } from '@/constants/screens' @@ -34,11 +35,14 @@ export default function RibbonPanel() { const threads = useAtomValue(threadsAtom) const isDownloadALocalModel = useAtomValue(isDownloadALocalModelAtom) - const onMenuClick = (state: MainViewState) => { + const onMenuClick = (state: MainViewState, id: string) => { if (mainViewState === state) return if (serverEnabled && state === MainViewState.Thread) return if (state === MainViewState.Settings) setSelectedSetting('My Models') setMainViewState(state) + posthog.capture('mainViewScreen', { + screen: id, + }) setEditMessage('') } @@ -55,21 +59,25 @@ export default function RibbonPanel() { /> ), state: MainViewState.Thread, + id: 'thread_screen', }, { name: 'Hub', icon: , state: MainViewState.Hub, + id: 'hub_screen', }, { name: 'Local API Server', icon: , state: MainViewState.LocalServer, + id: 'local_api_server_screen', }, { name: 'Settings', icon: , state: MainViewState.Settings, + id: 'setting', }, ] @@ -98,7 +106,7 @@ export default function RibbonPanel() { i === 1 && 'mb-auto' )} key={i} - onClick={() => onMenuClick(menu.state)} + onClick={() => onMenuClick(menu.state, menu.id)} > Date: Wed, 20 Nov 2024 20:46:46 +0700 Subject: [PATCH 4/9] chore: remove custome event --- web/containers/Layout/RibbonPanel/index.tsx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/web/containers/Layout/RibbonPanel/index.tsx b/web/containers/Layout/RibbonPanel/index.tsx index 45c4fd052..13116dc16 100644 --- a/web/containers/Layout/RibbonPanel/index.tsx +++ b/web/containers/Layout/RibbonPanel/index.tsx @@ -7,7 +7,6 @@ import { SquareCodeIcon, } from 'lucide-react' -import posthog from 'posthog-js' import { twMerge } from 'tailwind-merge' import { MainViewState } from '@/constants/screens' @@ -35,14 +34,11 @@ export default function RibbonPanel() { const threads = useAtomValue(threadsAtom) const isDownloadALocalModel = useAtomValue(isDownloadALocalModelAtom) - const onMenuClick = (state: MainViewState, id: string) => { + const onMenuClick = (state: MainViewState) => { if (mainViewState === state) return if (serverEnabled && state === MainViewState.Thread) return if (state === MainViewState.Settings) setSelectedSetting('My Models') setMainViewState(state) - posthog.capture('mainViewScreen', { - screen: id, - }) setEditMessage('') } @@ -59,25 +55,21 @@ export default function RibbonPanel() { /> ), state: MainViewState.Thread, - id: 'thread_screen', }, { name: 'Hub', icon: , state: MainViewState.Hub, - id: 'hub_screen', }, { name: 'Local API Server', icon: , state: MainViewState.LocalServer, - id: 'local_api_server_screen', }, { name: 'Settings', icon: , state: MainViewState.Settings, - id: 'setting', }, ] @@ -106,7 +98,7 @@ export default function RibbonPanel() { i === 1 && 'mb-auto' )} key={i} - onClick={() => onMenuClick(menu.state, menu.id)} + onClick={() => onMenuClick(menu.state)} > Date: Wed, 20 Nov 2024 21:00:18 +0700 Subject: [PATCH 5/9] chore: enable caputing pageview --- web/app/posthog.js | 1 - 1 file changed, 1 deletion(-) diff --git a/web/app/posthog.js b/web/app/posthog.js index 1799f3b0d..d6a6bf0bb 100644 --- a/web/app/posthog.js +++ b/web/app/posthog.js @@ -7,7 +7,6 @@ if (typeof window !== 'undefined') { posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well - capture_pageview: false, }) } export function CSPostHogProvider({ children }) { From 1a59b8cecb0e748ef4c041ae33815c0ae5cd81d7 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Wed, 20 Nov 2024 22:39:33 +0700 Subject: [PATCH 6/9] chore: add persistence localStorage --- web/app/posthog.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/app/posthog.js b/web/app/posthog.js index d6a6bf0bb..daa2a7ea2 100644 --- a/web/app/posthog.js +++ b/web/app/posthog.js @@ -7,6 +7,7 @@ if (typeof window !== 'undefined') { posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well + persistence: 'localStorage', }) } export function CSPostHogProvider({ children }) { From 786c16cc6f9c96ee9362b97f36ac895478b26833 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Wed, 20 Nov 2024 23:40:52 +0700 Subject: [PATCH 7/9] chore: profilce always identified --- web/app/posthog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/posthog.js b/web/app/posthog.js index daa2a7ea2..2ed24dbd0 100644 --- a/web/app/posthog.js +++ b/web/app/posthog.js @@ -6,7 +6,7 @@ import { PostHogProvider } from 'posthog-js/react' if (typeof window !== 'undefined') { posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, - person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well + person_profiles: 'always', persistence: 'localStorage', }) } From 97ad9e726abc98ff982cc4e488b564361a7ed0bb Mon Sep 17 00:00:00 2001 From: eckartal Date: Thu, 21 Nov 2024 23:18:03 +0700 Subject: [PATCH 8/9] feat: new privacy page --- docs/src/pages/docs/_meta.json | 1 + docs/src/pages/docs/privacy.mdx | 63 +++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 docs/src/pages/docs/privacy.mdx diff --git a/docs/src/pages/docs/_meta.json b/docs/src/pages/docs/_meta.json index 231f6a763..8ed88963c 100644 --- a/docs/src/pages/docs/_meta.json +++ b/docs/src/pages/docs/_meta.json @@ -13,6 +13,7 @@ }, "desktop": "Desktop", "data-folder": "Jan Data Folder", + "privacy": "Privacy", "user-guides": { "title": "BASIC USAGE", "type": "separator" diff --git a/docs/src/pages/docs/privacy.mdx b/docs/src/pages/docs/privacy.mdx new file mode 100644 index 000000000..d3be5b6de --- /dev/null +++ b/docs/src/pages/docs/privacy.mdx @@ -0,0 +1,63 @@ +--- +title: Jan Privacy +description: Jan is an app that allows you to own your AI. We prioritize your control over your data and explain what data we collect and why. +keywords: + [ + Jan AI, + Jan, + ChatGPT alternative, + local AI, + private AI, + conversational AI, + OpenAI platform alternative, + no-subscription fee, + large language model, + about Jan, + desktop application, + thinking machine, + jan vision, + ] +--- + +# Privacy + +Jan is an app that allows you to own your AI. We prioritize your control over your data and explain what data we collect and why. + +- Jan can't see your chats with AI +- You're free to opt out + +## Why and what we track + +To build a reliable, user-friendly AI that you own, we need to understand how Jan is used. We collect two types of data: performance data and usage data. + +### Performance data +We track app crashes and collect technical details about what went wrong, along with basic information about the hardware you’re using. + +When Jan crashes, we collect technical details about what went wrong. + +- Specific AI model in use during the crash +- Hardware: `CPU`, `GPU`, `RAM` +- Logs: `Date/Time`, `OS & version`, `app version`, `error codes & messages`. + +### Usage data + +We track data like how often the app is opened to check: + +- **Active Users**: How many people use Jan daily to measure engagement +- **Retention Rates**: To understand if users are finding value in Jan over time + +Usage data is tied to a randomly generated telemetry ID. None of our usage data can be linked to your personal identity. + +## What we **don’t** track: +- Your conversations with Jan. Those stay on your device. +- Your files. We don’t scan, upload, or even look at them. +- Anything tied to your identity. + +## Using Cloud Models + +Jan allows you to connect cloud model APIs. If you choose to use cloud-based models (e.g. GPT, Claude models), the API provider handling the model will have access to your messages as part of processing the request. Again, Jan doesn't see or store these messages - they go directly to the provider. Remember: With local models, everything stays on your device, so no one - not even us- can see your messages. + +## Where we store & process data +We use [PostHog](https://posthog.com/eu) EU for analytics, ensuring all data is processed within the European Union. This setup complies with GDPR and other strict privacy regulations. PostHog lets us self-host and securely manage the data we collect. Read more [on PostHog's GDPR doc](https://posthog.com/docs/privacy/gdpr-compliance). + +For a detailed breakdown of the analytics data we collect, you can check out our analytics repo. If you have any questions or concerns, feel free to reach out to us at hi@jan.ai. \ No newline at end of file From 813357cff63954b45faeb4b3f1618fd071b6fafd Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Fri, 22 Nov 2024 12:59:34 +0700 Subject: [PATCH 9/9] chore: remove analytic --- docs/package.json | 1 - web/app/layout.tsx | 12 ++++-------- web/app/posthog.js | 15 --------------- web/package.json | 1 - 4 files changed, 4 insertions(+), 25 deletions(-) delete mode 100644 web/app/posthog.js diff --git a/docs/package.json b/docs/package.json index dddb88b04..b2b74aba7 100644 --- a/docs/package.json +++ b/docs/package.json @@ -36,7 +36,6 @@ "path": "^0.12.7", "plop": "^4.0.1", "plop-helper-date": "^1.0.0", - "posthog-js": "^1.186.3", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.51.1", diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 29c44f19e..5f14d6f5c 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -4,8 +4,6 @@ import { Metadata } from 'next' import '@/styles/main.scss' -import { CSPostHogProvider } from './posthog' - export const metadata: Metadata = { title: 'Jan', description: @@ -15,12 +13,10 @@ export const metadata: Metadata = { export default function RootLayout({ children }: PropsWithChildren) { return ( - - -
- {children} - - + +
+ {children} + ) } diff --git a/web/app/posthog.js b/web/app/posthog.js deleted file mode 100644 index 2ed24dbd0..000000000 --- a/web/app/posthog.js +++ /dev/null @@ -1,15 +0,0 @@ -'use client' - -import posthog from 'posthog-js' -import { PostHogProvider } from 'posthog-js/react' - -if (typeof window !== 'undefined') { - posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { - api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, - person_profiles: 'always', - persistence: 'localStorage', - }) -} -export function CSPostHogProvider({ children }) { - return {children} -} diff --git a/web/package.json b/web/package.json index 24c47e53c..c4304d236 100644 --- a/web/package.json +++ b/web/package.json @@ -29,7 +29,6 @@ "next-themes": "^0.2.1", "postcss": "8.4.31", "postcss-url": "10.1.3", - "posthog-js": "^1.95.1", "react": "18.2.0", "react-circular-progressbar": "^2.1.0", "react-dom": "18.2.0",