From 5a8442712f83284c74ac0446e30decd7229fd9d1 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Sat, 29 Apr 2023 12:02:52 +0800 Subject: [PATCH] refactor: update tracking components (#3792) * refactor: update tracking components * refactor: track once for the same session --- .changeset/four-poets-change.md | 9 +++ packages/app-insights/package.json | 3 +- packages/app-insights/src/custom-event.ts | 59 +++++++++++++++++++ .../src/react/AppInsightsBoundary.tsx | 20 +++++-- .../src/react/AppInsightsReact.ts | 19 +++--- packages/app-insights/src/react/TrackOnce.tsx | 47 +++++++++++++++ packages/app-insights/src/react/index.ts | 1 + packages/console/src/App.tsx | 2 +- .../console/src/components/PageMeta/index.tsx | 4 +- packages/console/src/consts/index.ts | 3 +- packages/console/src/consts/storage.ts | 13 ++++ .../src/contexts/AppThemeProvider/index.tsx | 6 +- packages/console/src/onboarding/App.tsx | 3 + .../src/onboarding/pages/About/index.tsx | 2 +- .../src/onboarding/pages/Congrats/index.tsx | 2 +- .../pages/SignInExperience/index.tsx | 2 +- .../src/onboarding/pages/Welcome/index.tsx | 2 +- packages/console/src/pages/Main/index.tsx | 3 + .../components/LinkAccountSection/index.tsx | 4 +- .../containers/HandleSocialCallback/index.tsx | 6 +- .../interaction/actions/submit-interaction.ts | 6 +- .../de/translation/admin-console/cloud.ts | 3 + .../en/translation/admin-console/cloud.ts | 3 + .../es/translation/admin-console/cloud.ts | 3 + .../fr/translation/admin-console/cloud.ts | 3 + .../it/translation/admin-console/cloud.ts | 3 + .../ja/translation/admin-console/cloud.ts | 3 + .../ko/translation/admin-console/cloud.ts | 3 + .../pl-pl/translation/admin-console/cloud.ts | 3 + .../pt-br/translation/admin-console/cloud.ts | 3 + .../pt-pt/translation/admin-console/cloud.ts | 3 + .../ru/translation/admin-console/cloud.ts | 3 + .../tr-tr/translation/admin-console/cloud.ts | 3 + .../zh-cn/translation/admin-console/cloud.ts | 3 + .../zh-hk/translation/admin-console/cloud.ts | 3 + .../zh-tw/translation/admin-console/cloud.ts | 3 + packages/ui/src/App.tsx | 2 +- packages/ui/src/components/PageMeta/index.tsx | 2 +- 38 files changed, 230 insertions(+), 35 deletions(-) create mode 100644 .changeset/four-poets-change.md create mode 100644 packages/app-insights/src/custom-event.ts create mode 100644 packages/app-insights/src/react/TrackOnce.tsx create mode 100644 packages/console/src/consts/storage.ts diff --git a/.changeset/four-poets-change.md b/.changeset/four-poets-change.md new file mode 100644 index 000000000..7b96909eb --- /dev/null +++ b/.changeset/four-poets-change.md @@ -0,0 +1,9 @@ +--- +"@logto/app-insights": minor +--- + +add custom events and new component + +- implement `getEventName()` to create standard event name with the format `/[/data]`. E.g. `core/sign_in`. +- four new event components `core`, `console`, `blog`, and `website`. +- implement `` for tracking a custom event once diff --git a/packages/app-insights/package.json b/packages/app-insights/package.json index ef09304b6..3b4c9d825 100644 --- a/packages/app-insights/package.json +++ b/packages/app-insights/package.json @@ -20,7 +20,8 @@ }, "//": "This field is for parcel. Remove after https://github.com/parcel-bundler/parcel/pull/8807 published.", "alias": { - "./react": "./lib/react/index.js" + "./react": "./lib/react/index.js", + "./custom-event": "./lib/custom-event.js" }, "publishConfig": { "access": "public" diff --git a/packages/app-insights/src/custom-event.ts b/packages/app-insights/src/custom-event.ts new file mode 100644 index 000000000..b542f3d22 --- /dev/null +++ b/packages/app-insights/src/custom-event.ts @@ -0,0 +1,59 @@ +/** The app (either frontend or backend) for a bunch of events. */ +export enum Component { + /** Logto core service. */ + Core = 'core', + /** Logto Console. */ + Console = 'console', + /** Logto blog. */ + Blog = 'blog', + /** Logto official website. */ + Website = 'website', +} + +/** General event enums that for frontend apps. */ +export enum GeneralEvent { + /** A user visited the current app, it should be recorded once per session. */ + Visit = 'visit', +} + +export enum CoreEvent { + /** An existing user signed in via an interaction. */ + SignIn = 'sign_in', + /** A new user has created in an interaction. */ + Register = 'register', +} + +export enum ConsoleEvent { + /** A user started the onboarding process. */ + Onboard = 'onboard', +} + +export enum BlogEvent { + /** A user viewed a blog post. */ + ViewPost = 'view_post', +} + +export const eventsMap = Object.freeze({ + [Component.Core]: CoreEvent, + [Component.Console]: { ...ConsoleEvent, ...GeneralEvent }, + [Component.Blog]: { ...BlogEvent, ...GeneralEvent }, + [Component.Website]: GeneralEvent, +}) satisfies Record; + +export type EventsMap = typeof eventsMap; + +export type EventType = EventsMap[C][keyof EventsMap[C]]; + +export function getEventName( + component: Component.Blog, + event: EventType, + postUrl?: string +): string; +export function getEventName(component: C, event: EventType): string; +export function getEventName( + component: C, + event: EventType, + data?: string +): string { + return [component, event, data].filter(Boolean).join('/'); +} diff --git a/packages/app-insights/src/react/AppInsightsBoundary.tsx b/packages/app-insights/src/react/AppInsightsBoundary.tsx index 076caa5d1..34444a79a 100644 --- a/packages/app-insights/src/react/AppInsightsBoundary.tsx +++ b/packages/app-insights/src/react/AppInsightsBoundary.tsx @@ -3,19 +3,27 @@ import { type ReactNode, useContext, useEffect } from 'react'; import { AppInsightsContext, AppInsightsProvider } from './context.js'; import { getPrimaryDomain } from './utils.js'; -const AppInsights = () => { +type AppInsightsProps = { + cloudRole: string; +}; + +const AppInsights = ({ cloudRole }: AppInsightsProps) => { const { needsSetup, setup } = useContext(AppInsightsContext); useEffect(() => { + const run = async () => { + await setup(cloudRole, { cookieDomain: getPrimaryDomain() }); + }; + if (needsSetup) { - void setup('console', { cookieDomain: getPrimaryDomain() }); + void run(); } - }, [needsSetup, setup]); + }, [cloudRole, needsSetup, setup]); return null; }; -type Props = { +type Props = AppInsightsProps & { children: ReactNode; }; @@ -28,10 +36,10 @@ type Props = { * cause issues for some context providers. For example, `useHandleSignInCallback` will be * called twice if you use this component to wrap a ``. */ -const AppInsightsBoundary = ({ children }: Props) => { +const AppInsightsBoundary = ({ children, ...rest }: Props) => { return ( - + {children} ); diff --git a/packages/app-insights/src/react/AppInsightsReact.ts b/packages/app-insights/src/react/AppInsightsReact.ts index b178ea5eb..4d16cfe33 100644 --- a/packages/app-insights/src/react/AppInsightsReact.ts +++ b/packages/app-insights/src/react/AppInsightsReact.ts @@ -12,6 +12,12 @@ export type SetupConfig = { }; export class AppInsightsReact { + /** + * URL search parameters that start with `utm_`. It is an empty object until you call `.setup()`, + * which will read the URL search string and store parameters in this property. + */ + utmParameters: Record = {}; + protected reactPlugin?: ReactPlugin; protected clickAnalyticsPlugin?: ClickAnalyticsPlugin; protected withAITracking?: typeof withAITracking; @@ -84,18 +90,17 @@ export class AppInsightsReact { }, }); + // Extract UTM parameters + const searchParams = [...new URLSearchParams(window.location.search).entries()]; + this.utmParameters = Object.fromEntries( + searchParams.filter(([key]) => key.startsWith('utm_')) + ); + this.appInsights.addTelemetryInitializer((item) => { // @see https://github.com/microsoft/ApplicationInsights-JS#example-setting-cloud-role-name // @see https://github.com/microsoft/ApplicationInsights-node.js/blob/a573e40fc66981c6a3106bdc5b783d1d94f64231/Schema/PublicSchema/ContextTagKeys.bond#L83 /* eslint-disable @silverhand/fp/no-mutation */ item.tags = [...(item.tags ?? []), { 'ai.cloud.role': cloudRole }]; - - // Extract UTM parameters - const searchParams = [...new URLSearchParams(window.location.search).entries()]; - item.data = { - ...item.data, - ...Object.fromEntries(searchParams.filter(([key]) => key.startsWith('utm_'))), - }; /* eslint-enable @silverhand/fp/no-mutation */ }); diff --git a/packages/app-insights/src/react/TrackOnce.tsx b/packages/app-insights/src/react/TrackOnce.tsx new file mode 100644 index 000000000..d2975dd2c --- /dev/null +++ b/packages/app-insights/src/react/TrackOnce.tsx @@ -0,0 +1,47 @@ +import { type ICustomProperties } from '@microsoft/applicationinsights-web'; +import { yes } from '@silverhand/essentials'; +import { useContext, useEffect } from 'react'; + +import { getEventName, type Component, type EventType } from '../custom-event.js'; + +import { AppInsightsContext } from './context.js'; + +type Props = { + component: C; + event: EventType; + customProperties?: ICustomProperties; +}; + +const storageKeyPrefix = 'logto:insights:'; + +/** Track an event after AppInsights SDK is setup, but only once during the current session. */ +const TrackOnce = ({ component, event, customProperties }: Props) => { + const { isSetupFinished, appInsights } = useContext(AppInsightsContext); + + useEffect(() => { + const eventName = getEventName(component, event); + const storageKey = `${storageKeyPrefix}${eventName}`; + const tracked = yes(sessionStorage.getItem(storageKey)); + + if (isSetupFinished && !tracked) { + appInsights.instance?.trackEvent( + { + name: getEventName(component, event), + }, + { ...appInsights.utmParameters, ...customProperties } + ); + sessionStorage.setItem(storageKey, '1'); + } + }, [ + appInsights.instance, + appInsights.utmParameters, + component, + customProperties, + event, + isSetupFinished, + ]); + + return null; +}; + +export default TrackOnce; diff --git a/packages/app-insights/src/react/index.ts b/packages/app-insights/src/react/index.ts index bed50d9da..638c4f0df 100644 --- a/packages/app-insights/src/react/index.ts +++ b/packages/app-insights/src/react/index.ts @@ -2,3 +2,4 @@ export { AppInsightsReact, type SetupConfig, withAppInsights } from './AppInsigh export * from './context.js'; export * from './utils.js'; export { default as AppInsightsBoundary } from './AppInsightsBoundary.js'; +export { default as TrackOnce } from './TrackOnce.js'; diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx index 3901cc74d..b1fd56348 100644 --- a/packages/console/src/App.tsx +++ b/packages/console/src/App.tsx @@ -71,7 +71,7 @@ function Content() { }} > - + {!isCloud || isSettle ? ( diff --git a/packages/console/src/components/PageMeta/index.tsx b/packages/console/src/components/PageMeta/index.tsx index 62f674572..3818d74d1 100644 --- a/packages/console/src/components/PageMeta/index.tsx +++ b/packages/console/src/components/PageMeta/index.tsx @@ -4,8 +4,6 @@ import { useContext, useEffect, useState } from 'react'; import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; -import { mainTitle } from '@/consts/tenants'; - export type Props = { titleKey: AdminConsoleKey | AdminConsoleKey[]; // eslint-disable-next-line react/boolean-prop-naming @@ -23,7 +21,7 @@ function PageMeta({ titleKey, trackPageView = true }: Props) { useEffect(() => { // Only track once for the same page if (isSetupFinished && trackPageView && !pageViewTracked) { - appInsights.trackPageView?.({ name: [rawTitle, mainTitle].join(' - ') }); + appInsights.trackPageView?.({ name: `Console: ${rawTitle}` }); setPageViewTracked(true); } }, [appInsights, isSetupFinished, pageViewTracked, rawTitle, trackPageView]); diff --git a/packages/console/src/consts/index.ts b/packages/console/src/consts/index.ts index ed48a9443..a869b348e 100644 --- a/packages/console/src/consts/index.ts +++ b/packages/console/src/consts/index.ts @@ -5,9 +5,8 @@ export * from './resources'; export * from './tenants'; export * from './page-tabs'; export * from './external-links'; +export * from './storage'; -export const appearanceModeStorageKey = 'logto:admin_console:appearance_mode'; -export const profileSocialLinkingKeyPrefix = 'logto:admin_console:linking_social_connector'; export const requestTimeout = 20_000; export const defaultPageSize = 20; diff --git a/packages/console/src/consts/storage.ts b/packages/console/src/consts/storage.ts new file mode 100644 index 000000000..22917d99e --- /dev/null +++ b/packages/console/src/consts/storage.ts @@ -0,0 +1,13 @@ +export type CamelCase = T extends `${infer A}_${infer B}` + ? `${A}${Capitalize>}` + : T; + +export type StorageType = 'appearance_mode' | 'linking_social_connector'; + +export const getStorageKey = (forType: T) => + `logto:admin_console:${forType}` as const; + +export const storageKeys = Object.freeze({ + appearanceMode: getStorageKey('appearance_mode'), + linkingSocialConnector: getStorageKey('linking_social_connector'), +} satisfies Record, string>); diff --git a/packages/console/src/contexts/AppThemeProvider/index.tsx b/packages/console/src/contexts/AppThemeProvider/index.tsx index 866dd8d35..f6225238d 100644 --- a/packages/console/src/contexts/AppThemeProvider/index.tsx +++ b/packages/console/src/contexts/AppThemeProvider/index.tsx @@ -3,7 +3,7 @@ import { conditionalString, noop, trySafe } from '@silverhand/essentials'; import type { ReactNode } from 'react'; import { useEffect, useMemo, useState, createContext } from 'react'; -import { appearanceModeStorageKey } from '@/consts'; +import { storageKeys } from '@/consts'; import type { AppearanceMode } from '@/types/appearance-mode'; import { appearanceModeGuard, DynamicAppearanceMode } from '@/types/appearance-mode'; @@ -24,7 +24,7 @@ const getThemeBySystemConfiguration = (): Theme => darkThemeWatchMedia.matches ? Theme.Dark : Theme.Light; export const buildDefaultAppearanceMode = (): AppearanceMode => - trySafe(() => appearanceModeGuard.parse(localStorage.getItem(appearanceModeStorageKey))) ?? + trySafe(() => appearanceModeGuard.parse(localStorage.getItem(storageKeys.appearanceMode))) ?? DynamicAppearanceMode.System; const defaultAppearanceMode = buildDefaultAppearanceMode(); @@ -47,7 +47,7 @@ export function AppThemeProvider({ children }: Props) { const setAppearanceMode = (mode: AppearanceMode) => { setMode(mode); - localStorage.setItem(appearanceModeStorageKey, mode); + localStorage.setItem(storageKeys.appearanceMode, mode); }; useEffect(() => { diff --git a/packages/console/src/onboarding/App.tsx b/packages/console/src/onboarding/App.tsx index 097124ec7..c8a90d9d3 100644 --- a/packages/console/src/onboarding/App.tsx +++ b/packages/console/src/onboarding/App.tsx @@ -1,3 +1,5 @@ +import { Component, ConsoleEvent } from '@logto/app-insights/custom-event'; +import { TrackOnce } from '@logto/app-insights/react'; import { Theme } from '@logto/schemas'; import { useContext, useEffect } from 'react'; import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; @@ -46,6 +48,7 @@ function App() { return ( +
diff --git a/packages/console/src/onboarding/pages/About/index.tsx b/packages/console/src/onboarding/pages/About/index.tsx index 36a29a426..1e0359d20 100644 --- a/packages/console/src/onboarding/pages/About/index.tsx +++ b/packages/console/src/onboarding/pages/About/index.tsx @@ -56,7 +56,7 @@ function About() { return (
- +
diff --git a/packages/console/src/onboarding/pages/Congrats/index.tsx b/packages/console/src/onboarding/pages/Congrats/index.tsx index 55cb66554..343e487ae 100644 --- a/packages/console/src/onboarding/pages/Congrats/index.tsx +++ b/packages/console/src/onboarding/pages/Congrats/index.tsx @@ -31,7 +31,7 @@ function Congrats() { return (
- +
diff --git a/packages/console/src/onboarding/pages/SignInExperience/index.tsx b/packages/console/src/onboarding/pages/SignInExperience/index.tsx index 00288dfc4..bfff83056 100644 --- a/packages/console/src/onboarding/pages/SignInExperience/index.tsx +++ b/packages/console/src/onboarding/pages/SignInExperience/index.tsx @@ -107,7 +107,7 @@ function SignInExperience() { return (
- +
diff --git a/packages/console/src/onboarding/pages/Welcome/index.tsx b/packages/console/src/onboarding/pages/Welcome/index.tsx index ca003e868..dcbd05539 100644 --- a/packages/console/src/onboarding/pages/Welcome/index.tsx +++ b/packages/console/src/onboarding/pages/Welcome/index.tsx @@ -53,7 +53,7 @@ function Welcome() { return (
- +
diff --git a/packages/console/src/pages/Main/index.tsx b/packages/console/src/pages/Main/index.tsx index 01fa5072a..96064e849 100644 --- a/packages/console/src/pages/Main/index.tsx +++ b/packages/console/src/pages/Main/index.tsx @@ -1,3 +1,5 @@ +import { Component, GeneralEvent } from '@logto/app-insights/custom-event'; +import { TrackOnce } from '@logto/app-insights/react'; import { useMemo } from 'react'; import { Route, @@ -41,6 +43,7 @@ function Main() { return ( + diff --git a/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx b/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx index 179cff30b..4ff19b40b 100644 --- a/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx +++ b/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx @@ -14,7 +14,7 @@ import FormCard from '@/components/FormCard'; import ImageWithErrorFallback from '@/components/ImageWithErrorFallback'; import UnnamedTrans from '@/components/UnnamedTrans'; import UserInfoCard from '@/components/UserInfoCard'; -import { adminTenantEndpoint, getBasename, meApi, profileSocialLinkingKeyPrefix } from '@/consts'; +import { adminTenantEndpoint, getBasename, meApi, storageKeys } from '@/consts'; import { useStaticApi } from '@/hooks/use-api'; import { useConfirmModal } from '@/hooks/use-confirm-modal'; import useTheme from '@/hooks/use-theme'; @@ -48,7 +48,7 @@ function LinkAccountSection({ user, connectors, onUpdate }: Props) { .post('me/social/authorization-uri', { json: { connectorId, state, redirectUri } }) .json<{ redirectTo: string }>(); - sessionStorage.setItem(profileSocialLinkingKeyPrefix, connectorId); + sessionStorage.setItem(storageKeys.linkingSocialConnector, connectorId); return redirectTo; }, diff --git a/packages/console/src/pages/Profile/containers/HandleSocialCallback/index.tsx b/packages/console/src/pages/Profile/containers/HandleSocialCallback/index.tsx index a5da637f9..2c6355b0b 100644 --- a/packages/console/src/pages/Profile/containers/HandleSocialCallback/index.tsx +++ b/packages/console/src/pages/Profile/containers/HandleSocialCallback/index.tsx @@ -2,7 +2,7 @@ import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import AppLoading from '@/components/AppLoading'; -import { adminTenantEndpoint, meApi, profileSocialLinkingKeyPrefix } from '@/consts'; +import { adminTenantEndpoint, meApi, storageKeys } from '@/consts'; import { useStaticApi } from '@/hooks/use-api'; import { useConfirmModal } from '@/hooks/use-confirm-modal'; @@ -19,8 +19,8 @@ function HandleSocialCallback() { useEffect(() => { (async () => { - const connectorId = sessionStorage.getItem(profileSocialLinkingKeyPrefix); - sessionStorage.removeItem(profileSocialLinkingKeyPrefix); + const connectorId = sessionStorage.getItem(storageKeys.linkingSocialConnector); + sessionStorage.removeItem(storageKeys.linkingSocialConnector); if (connectorId) { const queries = new URLSearchParams(search); diff --git a/packages/core/src/routes/interaction/actions/submit-interaction.ts b/packages/core/src/routes/interaction/actions/submit-interaction.ts index d93f33e97..6a305e579 100644 --- a/packages/core/src/routes/interaction/actions/submit-interaction.ts +++ b/packages/core/src/routes/interaction/actions/submit-interaction.ts @@ -1,3 +1,5 @@ +import { Component, CoreEvent, getEventName } from '@logto/app-insights/custom-event'; +import { appInsights } from '@logto/app-insights/node'; import type { User, Profile } from '@logto/schemas'; import { AdminTenantRole, @@ -196,6 +198,7 @@ export default async function submitInteraction( await assignInteractionResults(ctx, provider, { login: { accountId: id } }); log?.append({ userId: id }); + appInsights.client?.trackEvent({ name: getEventName(Component.Core, CoreEvent.Register) }); return; } @@ -208,9 +211,10 @@ export default async function submitInteraction( const upsertProfile = await parseUserProfile(connectors, interaction, user); await updateUserById(accountId, upsertProfile); - await assignInteractionResults(ctx, provider, { login: { accountId } }); + appInsights.client?.trackEvent({ name: getEventName(Component.Core, CoreEvent.SignIn) }); + return; } diff --git a/packages/phrases/src/locales/de/translation/admin-console/cloud.ts b/packages/phrases/src/locales/de/translation/admin-console/cloud.ts index fe540a8e5..fefce87f7 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Einführung', + }, welcome: { page_title: 'Willkommen', title: 'Willkommen, lass uns deine eigene Logto Cloud Preview erstellen', diff --git a/packages/phrases/src/locales/en/translation/admin-console/cloud.ts b/packages/phrases/src/locales/en/translation/admin-console/cloud.ts index 8d421120d..6b00d0507 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Onboarding', + }, welcome: { page_title: 'Welcome', title: 'Welcome and let’s create your own Logto Cloud Preview', diff --git a/packages/phrases/src/locales/es/translation/admin-console/cloud.ts b/packages/phrases/src/locales/es/translation/admin-console/cloud.ts index 2a6a21ba8..8be310fc6 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Integración', + }, welcome: { page_title: 'Bienvenido', title: 'Bienvenido y creemos su propia vista previa de Logto Cloud', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts b/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts index 479d75e20..52f97b458 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Intégration', + }, welcome: { page_title: 'Bienvenue', title: 'Bienvenue et créons votre propre aperçu cloud de Logto', diff --git a/packages/phrases/src/locales/it/translation/admin-console/cloud.ts b/packages/phrases/src/locales/it/translation/admin-console/cloud.ts index b772a8519..fdf53e430 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Inizio', + }, welcome: { page_title: 'Benvenuto', title: 'Benvenuto e creiamo insieme la tua anteprima di Logto Cloud', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/cloud.ts b/packages/phrases/src/locales/ja/translation/admin-console/cloud.ts index cda7097c8..477038941 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'オンボーディング', + }, welcome: { page_title: 'ようこそ', title: 'ようこそ、あなたのLogto Cloud Previewを作成しましょう', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts b/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts index 55a2b9ae7..33ea1e1b7 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: '온보딩', + }, welcome: { page_title: '환영합니다', title: '환영합니다. 당신 만의 Logto Cloud Preview를 만들어 보세요', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/cloud.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/cloud.ts index 19ee22fab..e804cdeea 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Wdrażanie', + }, welcome: { page_title: 'Witaj', title: 'Witaj i stwórz własny podgląd chmury Logto', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts index 00e961e15..cb1671b84 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Integração', + }, welcome: { page_title: 'Boas-vindas', title: 'Boas-vindas e vamos criar sua própria visualização de nuvem Logto', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts index 011dce97a..8497b26b4 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Introdução', + }, welcome: { page_title: 'Bem-vindo', title: 'Bem-vindo e vamos criar a sua própria visualização da Logto Cloud', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/cloud.ts b/packages/phrases/src/locales/ru/translation/admin-console/cloud.ts index df75a04fd..681d3e71f 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Вводный курс', + }, welcome: { page_title: 'Добро пожаловать', title: diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts index f072105f0..14d345b53 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: 'Başlatma', + }, welcome: { page_title: 'Hoşgeldiniz', title: 'Hoşgeldiniz ve kendi Logto Cloud Önizlemenizi oluşturalım', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts index 6e7ea3df9..25f8e0e95 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: '入门', + }, welcome: { page_title: '欢迎', title: '欢迎来到 Logto Cloud(预览版),让我们一起创建独属于你的体验', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/cloud.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/cloud.ts index 2cfe885fc..1ff45d0e6 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: '入門', + }, welcome: { page_title: '歡迎', title: '歡迎來到 Logto Cloud(預覽版),讓我們一起創建獨屬於你的體驗', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/cloud.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/cloud.ts index 35526964f..bc8a37fe6 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/cloud.ts @@ -1,4 +1,7 @@ const cloud = { + general: { + onboarding: '入門', + }, welcome: { page_title: '歡迎', title: '歡迎來到 Logto Cloud(預覽版),讓我們一起創建獨屬於你的體驗', diff --git a/packages/ui/src/App.tsx b/packages/ui/src/App.tsx index c714862a1..22fa5fa11 100644 --- a/packages/ui/src/App.tsx +++ b/packages/ui/src/App.tsx @@ -33,7 +33,7 @@ const App = () => { - + } /> }> diff --git a/packages/ui/src/components/PageMeta/index.tsx b/packages/ui/src/components/PageMeta/index.tsx index 07c826cdc..c4bf1c281 100644 --- a/packages/ui/src/components/PageMeta/index.tsx +++ b/packages/ui/src/components/PageMeta/index.tsx @@ -23,7 +23,7 @@ const PageMeta = ({ titleKey, trackPageView = true }: Props) => { useEffect(() => { // Only track once for the same page if (shouldTrack && isSetupFinished && trackPageView && !pageViewTracked) { - appInsights.trackPageView?.({ name: [rawTitle, 'SIE'].join(' - ') }); + appInsights.trackPageView?.({ name: `Main flow: ${rawTitle}` }); setPageViewTracked(true); } }, [appInsights, isSetupFinished, pageViewTracked, rawTitle, trackPageView]);