diff --git a/apps/cs/instrumentation-client.ts b/apps/cs/instrumentation-client.ts new file mode 100644 index 000000000..07509aaa4 --- /dev/null +++ b/apps/cs/instrumentation-client.ts @@ -0,0 +1,13 @@ +import * as Sentry from "@sentry/nextjs"; + +export const onRouterTransitionStart = Sentry.captureRouterTransitionStart; + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + environment: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT ?? "local", + tracesSampleRate: 1.0, + replaysSessionSampleRate: 1.0, + replaysOnErrorSampleRate: 1.0, + integrations: [Sentry.replayIntegration()], + debug: process.env.NEXT_PUBLIC_SENTRY_DEBUG === "true", +}); diff --git a/apps/cs/instrumentation.ts b/apps/cs/instrumentation.ts new file mode 100644 index 000000000..7cbe93c13 --- /dev/null +++ b/apps/cs/instrumentation.ts @@ -0,0 +1,13 @@ +import * as Sentry from "@sentry/nextjs"; + +export async function register() { + if (process.env.NEXT_RUNTIME === "nodejs") { + await import("./sentry.server.config"); + } + + if (process.env.NEXT_RUNTIME === "edge") { + await import("./sentry.edge.config"); + } +} + +export const onRequestError = Sentry.captureRequestError; diff --git a/apps/cs/next.config.ts b/apps/cs/next.config.ts index 61d7f72cc..11d8237c7 100644 --- a/apps/cs/next.config.ts +++ b/apps/cs/next.config.ts @@ -1,4 +1,5 @@ import type { NextConfig } from "next"; +import { withSentryConfig } from "@sentry/nextjs"; const subDomain = process.env.NEXT_PUBLIC_SUB_DOMAIN || "http://localhost:13000"; @@ -58,4 +59,16 @@ const nextConfig: NextConfig = { }, }; -export default nextConfig; +export default withSentryConfig(nextConfig, { + org: process.env.SENTRY_ORG, + project: process.env.SENTRY_PROJECT, + silent: true, + widenClientFileUpload: true, + tunnelRoute: "/monitoring", + webpack: { + treeshake: { + removeDebugLogging: process.env.NEXT_PUBLIC_SENTRY_DEBUG === "true" ? false : true, + }, + automaticVercelMonitors: false, + }, +}); diff --git a/apps/cs/package.json b/apps/cs/package.json index 9d128263a..5bc498b88 100644 --- a/apps/cs/package.json +++ b/apps/cs/package.json @@ -27,6 +27,7 @@ "@radix-ui/react-label": "^2.1.2", "@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", + "@sentry/nextjs": "^10.57.0", "@tanstack/react-query": "^5.75.5", "@tanstack/react-query-devtools": "^5.75.5", "@tanstack/react-table": "^8.21.2", diff --git a/apps/cs/sentry.edge.config.ts b/apps/cs/sentry.edge.config.ts new file mode 100644 index 000000000..436630178 --- /dev/null +++ b/apps/cs/sentry.edge.config.ts @@ -0,0 +1,8 @@ +import * as Sentry from "@sentry/nextjs"; + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + environment: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT ?? "local", + tracesSampleRate: 1.0, + debug: process.env.NEXT_PUBLIC_SENTRY_DEBUG === "true", +}); diff --git a/apps/cs/sentry.server.config.ts b/apps/cs/sentry.server.config.ts new file mode 100644 index 000000000..436630178 --- /dev/null +++ b/apps/cs/sentry.server.config.ts @@ -0,0 +1,8 @@ +import * as Sentry from "@sentry/nextjs"; + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + environment: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT ?? "local", + tracesSampleRate: 1.0, + debug: process.env.NEXT_PUBLIC_SENTRY_DEBUG === "true", +}); diff --git a/apps/cs/src/entities/menu/lib/menu-wrapper.tsx b/apps/cs/src/entities/menu/lib/menu-wrapper.tsx index 1f1080cac..d09801dac 100644 --- a/apps/cs/src/entities/menu/lib/menu-wrapper.tsx +++ b/apps/cs/src/entities/menu/lib/menu-wrapper.tsx @@ -2,9 +2,10 @@ import { useEffect } from "react"; import { usePathname, useRouter } from "next/navigation"; +import { useQuery } from "@tanstack/react-query"; import { MenuAuthorityApi } from "@/entities/menu-authority/@x/menu"; import { getCookie, useAlertStore, useMenuStore } from "@/shared/lib"; -import { SITE_ID } from "@/shared/config"; +import { SITE_ID, ENDPOINT } from "@/shared/config"; import { MenuApi } from "../api/menu-service"; import { getCurrentMenu } from "./utils"; @@ -16,11 +17,10 @@ const MenuWrapper = ({ children }: { children: React.ReactNode }) => { const { pageMenuAuthority, setCurrentMenuInfo, setPageMenuAuthority } = useMenuStore((state) => state); - const getCurrentMenuInfo = async () => { - const menuRoles = await MenuApi.getMenuRoles(SITE_ID); - if (!menuRoles) return; - return getCurrentMenu(menuRoles, pathname ?? ""); - }; + const { data: menuRoles } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES], + queryFn: () => MenuApi.getMenuRoles(SITE_ID), + }); const getPageMenuAuthority = async () => { const menuCd = getCookie("menu-code-key"); @@ -36,10 +36,14 @@ const MenuWrapper = ({ children }: { children: React.ReactNode }) => { }; useEffect(() => { - (async () => { - const currentMenu = await getCurrentMenuInfo(); + if (menuRoles) { + const currentMenu = getCurrentMenu(menuRoles, pathname ?? ""); if (currentMenu) setCurrentMenuInfo(currentMenu); + } + }, [menuRoles, pathname]); + useEffect(() => { + (async () => { const response = await getPageMenuAuthority(); if (response?.length) setPageMenuAuthority(response[0]!); })();