authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-10-06 13:55:07-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-06 13:55:07-07:00
log115640ae49924c9e4e6215bd8d911445ad932bff
tree320b02c82b07949c2513c83c0372f779a7461ade
parent3b44698d07c722471279d6a933499d6108148632
signature Signed by PGP key B5690EEEBB952194

feat(web): note anonymous usage data in onboarding and link the privacy policy (#16564)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

4 files changed, 37 insertions(+), 1 deletions(-)

apps/web/src/components/onboarding/WelcomeWizard.tsx+16-1
...@@ -35,6 +35,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";...@@ -35,6 +35,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
35import { TYPOGRAPHY_ADVANCED_STORAGE_KEY } from "../../appearanceFonts";35import { TYPOGRAPHY_ADVANCED_STORAGE_KEY } from "../../appearanceFonts";
36import { useLocalStorage } from "../../hooks/useLocalStorage";36import { useLocalStorage } from "../../hooks/useLocalStorage";
37import { hasCloudPublicConfig } from "../../cloud/publicConfig";37import { hasCloudPublicConfig } from "../../cloud/publicConfig";
38import { PRIVACY_POLICY_URL } from "../../legalLinks";
38import { useT3ConnectAuthPrompt } from "../clerk/useT3ConnectAuthPrompt";39import { useT3ConnectAuthPrompt } from "../clerk/useT3ConnectAuthPrompt";
39import { useCompleteOnboarding } from "../../onboarding/firstRun";40import { useCompleteOnboarding } from "../../onboarding/firstRun";
40import {41import {
...@@ -413,8 +414,22 @@ function ConnectionStep({...@@ -413,8 +414,22 @@ function ConnectionStep({
413 </Collapsible>414 </Collapsible>
414 </div>415 </div>
415 </div>416 </div>
416 <div className="mt-6 flex items-center justify-end gap-3">417 <div className="mt-6 flex flex-col-reverse gap-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6">
418 <p className="min-w-0 text-xs leading-relaxed text-muted-foreground">
419 T3 Code collects anonymous usage data to help us improve it. To read more about how your
420 data is used and how to opt out, see our{" "}
421 <a
422 className="underline underline-offset-2 hover:text-foreground"
423 href={PRIVACY_POLICY_URL}
424 target="_blank"
425 rel="noreferrer noopener"
426 >
427 privacy policy
428 </a>
429 .
430 </p>
417 <Button431 <Button
432 className="shrink-0 self-end"
418 ref={continueRef}433 ref={continueRef}
419 autoFocus={!expandPairingInitially}434 autoFocus={!expandPairingInitially}
420 disabled={!ready || isPairing}435 disabled={!ready || isPairing}
apps/web/src/components/settings/SettingsPanels.tsx+14
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1import { SettingsGroup } from "./SettingsGroup";1import { SettingsGroup } from "./SettingsGroup";
2import { Spinner } from "~/components/ui/spinner";2import { Spinner } from "~/components/ui/spinner";
3import { NotificationSettings } from "./NotificationSettings";3import { NotificationSettings } from "./NotificationSettings";
4import { PRIVACY_POLICY_URL } from "../../legalLinks";
4import { ArchiveIcon, ArchiveX, CheckIcon, ChevronRightIcon, SettingsIcon } from "lucide-react";5import { ArchiveIcon, ArchiveX, CheckIcon, ChevronRightIcon, SettingsIcon } from "lucide-react";
5import { Link, useNavigate } from "@tanstack/react-router";6import { Link, useNavigate } from "@tanstack/react-router";
6import type { CSSProperties, ReactNode } from "react";7import type { CSSProperties, ReactNode } from "react";
...@@ -3342,6 +3343,19 @@ export function GeneralSettingsPanel() {...@@ -3342,6 +3343,19 @@ export function GeneralSettingsPanel() {
3342 {IS_NIGHTLY_BUILD ? <NightlyMobileBetaRow /> : null}3343 {IS_NIGHTLY_BUILD ? <NightlyMobileBetaRow /> : null}
3343 </>3344 </>
3344 )}3345 )}
3346 <SettingsRow
3347 {...searchableSetting("privacy-policy")}
3348 description="How we handle your data, including the anonymous usage data T3 Code collects."
3349 control={
3350 <Button
3351 render={<a href={PRIVACY_POLICY_URL} target="_blank" rel="noreferrer noopener" />}
3352 size="sm"
3353 variant="outline"
3354 >
3355 View policy
3356 </Button>
3357 }
3358 />
3345 </SettingsSection>3359 </SettingsSection>
3346 <SettingsSection title="Diagnostics">3360 <SettingsSection title="Diagnostics">
3347 <SettingsRow3361 <SettingsRow
apps/web/src/components/settings/settingsSearch.ts+6
...@@ -503,6 +503,12 @@ export const SETTINGS_SEARCH_ITEMS = [...@@ -503,6 +503,12 @@ export const SETTINGS_SEARCH_ITEMS = [
503 scope: "project-defaults",503 scope: "project-defaults",
504 searchTerms: ["generated thread titles source control content default provider"],504 searchTerms: ["generated thread titles source control content default provider"],
505 },505 },
506 {
507 id: "privacy-policy",
508 title: "Privacy policy",
509 to: "/settings/general",
510 searchTerms: ["telemetry analytics usage data tracking legal opt out"],
511 },
506 {512 {
507 id: "diagnostics",513 id: "diagnostics",
508 title: "Diagnostics",514 title: "Diagnostics",
apps/web/src/legalLinks.ts created+1
...@@ -0,0 +1 @@
1export const PRIVACY_POLICY_URL = "https://t3.codes/privacy-policy";