diff --git a/app/components/ClarityTracking.tsx b/app/components/ClarityTracking.tsx
index 4b7d66f1..6770eb69 100644
--- a/app/components/ClarityTracking.tsx
+++ b/app/components/ClarityTracking.tsx
@@ -1,3 +1,5 @@
+import Clarity from "@microsoft/clarity";
+
const ClarityTracking: FC = () => {
const {
component,
@@ -6,9 +8,9 @@ const ClarityTracking: FC = () => {
// == Current user tracking
useShallowEffect(() => {
- if (typeof clarity !== "undefined" && currentUser) {
+ if (currentUser) {
const { id, name } = currentUser;
- clarity("identify", id, undefined, component, name);
+ Clarity.identify(id, undefined, component, name);
}
}, [currentUser, component]);
diff --git a/app/entrypoints/application.tsx b/app/entrypoints/application.tsx
index c84c0549..70f17f30 100644
--- a/app/entrypoints/application.tsx
+++ b/app/entrypoints/application.tsx
@@ -7,6 +7,7 @@ import { createRoot, hydrateRoot } from "react-dom/client";
import AppWrapper from "~/components/AppWrapper";
import { setupActiveStorage } from "~/helpers/activestorage";
+import { setupClarity } from "~/helpers/clarity";
import { setupFetch } from "~/helpers/fetch";
import { setupFullStory } from "~/helpers/fullstory";
import {
@@ -26,6 +27,7 @@ setupLuxon();
setupActiveStorage();
setupSentry();
setupFullStory();
+setupClarity();
void registerServiceWorker();
// == Pages
diff --git a/app/helpers/clarity.ts b/app/helpers/clarity.ts
new file mode 100644
index 00000000..92af933e
--- /dev/null
+++ b/app/helpers/clarity.ts
@@ -0,0 +1,13 @@
+import Clarity from "@microsoft/clarity";
+
+import { getMeta } from "~/helpers/meta";
+
+export const setupClarity = () => {
+ const projectId = getMeta("clarity-project-id");
+ if (projectId) {
+ Clarity.init(projectId);
+ console.info("Initialized Clarity", projectId);
+ } else {
+ console.warn("Missing Clarity project ID; skipping initialization");
+ }
+};
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 17af1410..87ed7755 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -43,14 +43,8 @@
<% end %>
<%# == Clarity %>
- <% if Rails.env.production? && (settings = Clarity.settings) %>
-
+ <% if (settings = Clarity.settings) %>
+
<% end %>
<%# == Vite %>
diff --git a/package-lock.json b/package-lock.json
index 2d81ba24..062267ef 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
"@mantine/modals": "^7.12.1",
"@mantine/notifications": "^7.12.1",
"@mantine/nprogress": "^7.12.1",
+ "@microsoft/clarity": "^1.0.0",
"@rails/actioncable": "^7.1.3-2",
"@rails/activestorage": "^7.1.3-2",
"@react-email/components": "^0.0.25",
@@ -1516,6 +1517,12 @@
"gl-style-validate": "dist/gl-style-validate.mjs"
}
},
+ "node_modules/@microsoft/clarity": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@microsoft/clarity/-/clarity-1.0.0.tgz",
+ "integrity": "sha512-2QY6SmXnqRj6dWhNY8NYCN3e53j4zCFebH4wGnNhdGV1mqAsQwql2fT0w8TISxCvwwfVp8idsWLIdrRHOms1PQ==",
+ "license": "MIT"
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
diff --git a/package.json b/package.json
index 788c74ff..47e70122 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"@mantine/modals": "^7.12.1",
"@mantine/notifications": "^7.12.1",
"@mantine/nprogress": "^7.12.1",
+ "@microsoft/clarity": "^1.0.0",
"@rails/actioncable": "^7.1.3-2",
"@rails/activestorage": "^7.1.3-2",
"@react-email/components": "^0.0.25",
diff --git a/sorbet/rbi/shims/lib/frozen_record.rbi b/sorbet/rbi/shims/lib/frozen_record.rbi
new file mode 100644
index 00000000..c6a950d8
--- /dev/null
+++ b/sorbet/rbi/shims/lib/frozen_record.rbi
@@ -0,0 +1,6 @@
+# typed: true
+
+class FrozenRecord::Base
+ sig { params(id: T.untyped).returns(T.attached_class) }
+ def self.find(id); end
+end
diff --git a/typings/clarity.d.ts b/typings/clarity.d.ts
deleted file mode 100644
index d939398b..00000000
--- a/typings/clarity.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-type Clarity = (...args: any[]) => void;
-
-declare global {
- const clarity: Clarity | undefined;
-
- interface Window {
- clarity: Clarity | undefined;
- }
-}
-
-export {};
diff --git a/vite.config.ts b/vite.config.ts
index 14b2b977..135335a7 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -55,6 +55,9 @@ export default defineConfig(() => {
return {
clearScreen: false,
resolve: { alias: [{ find: "lodash", replacement: "lodash-es" }] },
+ ssr: {
+ noExternal: ["@microsoft/clarity"],
+ },
plugins,
};
});