@karan171996/metricflow 0.5.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/fallback-build-manifest.json +3 -3
  4. package/.next/next-server.js.nft.json +1 -1
  5. package/.next/prerender-manifest.json +6 -6
  6. package/.next/server/app/_global-error.html +1 -1
  7. package/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  12. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/_not-found.html +2 -2
  14. package/.next/server/app/_not-found.rsc +9 -9
  15. package/.next/server/app/_not-found.segments/_full.segment.rsc +9 -9
  16. package/.next/server/app/_not-found.segments/_index.segment.rsc +8 -8
  17. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  19. package/.next/server/app/api/analyze/route.js +2 -2
  20. package/.next/server/app/api/analyze/route.js.nft.json +1 -1
  21. package/.next/server/app/api/connect/route.js +1 -1
  22. package/.next/server/app/api/connect/route.js.nft.json +1 -1
  23. package/.next/server/app/api/health/route.js.nft.json +1 -1
  24. package/.next/server/app/api/metrics/route.js +2 -2
  25. package/.next/server/app/api/metrics/route.js.nft.json +1 -1
  26. package/.next/server/app/api/settings/route.js.nft.json +1 -1
  27. package/.next/server/app/api/setup/ai/route.js.nft.json +1 -1
  28. package/.next/server/app/api/setup/route.js +3 -2
  29. package/.next/server/app/api/setup/route.js.nft.json +1 -1
  30. package/.next/server/app/connect/page.js.nft.json +1 -1
  31. package/.next/server/app/connect/page_client-reference-manifest.js +1 -1
  32. package/.next/server/app/connect.html +19 -66
  33. package/.next/server/app/connect.rsc +11 -11
  34. package/.next/server/app/connect.segments/_full.segment.rsc +11 -11
  35. package/.next/server/app/connect.segments/_index.segment.rsc +8 -8
  36. package/.next/server/app/connect.segments/_tree.segment.rsc +2 -2
  37. package/.next/server/app/connect.segments/connect/__PAGE__.segment.rsc +6 -6
  38. package/.next/server/app/index.html +2 -2
  39. package/.next/server/app/index.rsc +11 -11
  40. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  41. package/.next/server/app/index.segments/_full.segment.rsc +11 -11
  42. package/.next/server/app/index.segments/_index.segment.rsc +8 -8
  43. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  44. package/.next/server/app/page.js.nft.json +1 -1
  45. package/.next/server/app/page_client-reference-manifest.js +1 -1
  46. package/.next/server/app/performance/[slug]/page.js +2 -2
  47. package/.next/server/app/performance/[slug]/page.js.nft.json +1 -1
  48. package/.next/server/app/performance/[slug]/page_client-reference-manifest.js +1 -1
  49. package/.next/server/app/performance/page.js.nft.json +1 -1
  50. package/.next/server/app/performance/page_client-reference-manifest.js +1 -1
  51. package/.next/server/app/performance.html +2 -2
  52. package/.next/server/app/performance.rsc +12 -12
  53. package/.next/server/app/performance.segments/_full.segment.rsc +12 -12
  54. package/.next/server/app/performance.segments/_index.segment.rsc +8 -8
  55. package/.next/server/app/performance.segments/_tree.segment.rsc +2 -2
  56. package/.next/server/app/performance.segments/performance/__PAGE__.segment.rsc +7 -7
  57. package/.next/server/app/settings/page.js.nft.json +1 -1
  58. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  59. package/.next/server/app/settings.html +2 -2
  60. package/.next/server/app/settings.rsc +22 -22
  61. package/.next/server/app/settings.segments/_full.segment.rsc +22 -22
  62. package/.next/server/app/settings.segments/_index.segment.rsc +8 -8
  63. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  64. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +17 -17
  65. package/.next/server/app/setup/page.js.nft.json +1 -1
  66. package/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  67. package/.next/server/app/setup.html +2 -2
  68. package/.next/server/app/setup.rsc +12 -12
  69. package/.next/server/app/setup.segments/_full.segment.rsc +12 -12
  70. package/.next/server/app/setup.segments/_index.segment.rsc +8 -8
  71. package/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  72. package/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +7 -7
  73. package/.next/server/app/tools/[tool]/page.js.nft.json +1 -1
  74. package/.next/server/app/tools/[tool]/page_client-reference-manifest.js +1 -1
  75. package/.next/server/chunks/[root-of-the-server]__0fkj1-q._.js +1 -1
  76. package/.next/server/chunks/[root-of-the-server]__0o2ceqr._.js +18 -0
  77. package/.next/server/chunks/[root-of-the-server]__0pil1g6._.js +3 -0
  78. package/.next/server/chunks/[root-of-the-server]__0xmaf60._.js +18 -0
  79. package/.next/server/chunks/[root-of-the-server]__18s35pf._.js +1 -1
  80. package/.next/server/chunks/[root-of-the-server]__1f_fo0j._.js +1 -1
  81. package/.next/server/chunks/[root-of-the-server]__1naf7j4._.js +3 -0
  82. package/.next/server/chunks/[root-of-the-server]__1o9k4jf._.js +1 -1
  83. package/.next/server/chunks/[root-of-the-server]__1rx5s6r._.js +3 -0
  84. package/.next/server/chunks/_08xo8nu._.js +4 -4
  85. package/.next/server/chunks/_0w8wvdn._.js +1 -1
  86. package/.next/server/chunks/_0wct7-r._.js +1 -16
  87. package/.next/server/chunks/_1l9d64o._.js +2 -2
  88. package/.next/server/chunks/ssr/0x0c_next_dist_1icgwks._.js +1 -1
  89. package/.next/server/chunks/ssr/[root-of-the-server]__02c3m72._.js +1 -1
  90. package/.next/server/chunks/ssr/[root-of-the-server]__0g1dtzd._.js +1 -1
  91. package/.next/server/chunks/ssr/[root-of-the-server]__0l4t71c._.js +1 -1
  92. package/.next/server/chunks/ssr/[root-of-the-server]__1jr0qvs._.js +1 -1
  93. package/.next/server/chunks/ssr/{[root-of-the-server]__0ryyli3._.js → [root-of-the-server]__1xhr2zy._.js} +1 -1
  94. package/.next/server/chunks/ssr/_045bvlq._.js +1 -1
  95. package/.next/server/chunks/ssr/_0_02db6._.js +1 -1
  96. package/.next/server/chunks/ssr/_0bxxvzb._.js +1 -1
  97. package/.next/server/chunks/ssr/_0cq6qjs._.js +9 -63
  98. package/.next/server/chunks/ssr/_0htqt7_._.js +10 -5
  99. package/.next/server/chunks/ssr/_0ompurr._.js +2 -2
  100. package/.next/server/chunks/ssr/_0un641_._.js +1 -1
  101. package/.next/server/chunks/ssr/_12pw-ix._.js +151 -0
  102. package/.next/server/chunks/ssr/_13m9nev._.js +1 -1
  103. package/.next/server/chunks/ssr/_19s4g71._.js +1 -1
  104. package/.next/server/chunks/ssr/_1n6rdd2._.js +1 -1
  105. package/.next/server/chunks/ssr/components_1_8btz1._.js +1 -1
  106. package/.next/server/middleware-build-manifest.js +3 -3
  107. package/.next/server/middleware.js.nft.json +1 -1
  108. package/.next/server/pages/404.html +2 -2
  109. package/.next/server/pages/500.html +1 -1
  110. package/.next/static/chunks/036zzfotyi252.js +1 -0
  111. package/.next/static/chunks/18thq9ido-jej.js +5 -0
  112. package/.next/static/chunks/{19qbz8dh8aqt6.js → 190rvtbj8tqbw.js} +1 -1
  113. package/.next/static/chunks/1kqzgl2gb6ily.js +1 -0
  114. package/.next/static/chunks/2h1anqi3hzijd.js +1 -0
  115. package/.next/static/chunks/{0_xh0vh4uh0vk.js → 2pf7wdwyhi6ks.js} +1 -1
  116. package/.next/static/chunks/{278--y-yo6m9v.js → 31od3fbrskb5_.js} +1 -1
  117. package/.next/static/chunks/332sb1iij72mz.css +1 -0
  118. package/.next/static/chunks/3khzw5hn41lt7.js +11 -0
  119. package/.next/static/chunks/3o4y8rhawejsr.js +1 -0
  120. package/.next/trace +1 -1
  121. package/.next/trace-build +1 -1
  122. package/README.md +48 -7
  123. package/bin/cli.mjs +2 -1
  124. package/dist/browser/index.d.mts +27 -0
  125. package/dist/browser/index.mjs +110 -0
  126. package/dist/browser/newrelic-agent.d.mts +4 -0
  127. package/dist/browser/newrelic-agent.mjs +32 -0
  128. package/dist/browser/newrelic.d.mts +2 -0
  129. package/dist/browser/newrelic.mjs +35 -0
  130. package/dist/browser/sentry-sdk.d.mts +2 -0
  131. package/dist/browser/sentry-sdk.mjs +22 -0
  132. package/dist/browser/sentry.d.mts +2 -0
  133. package/dist/browser/sentry.mjs +45 -0
  134. package/package.json +15 -3
  135. package/.next/server/chunks/[root-of-the-server]__12h8r83._.js +0 -3
  136. package/.next/server/chunks/[root-of-the-server]__19yigji._.js +0 -3
  137. package/.next/server/chunks/[root-of-the-server]__1sf143y._.js +0 -3
  138. package/.next/server/chunks/[root-of-the-server]__1zlr3w0._.js +0 -3
  139. package/.next/server/chunks/ssr/_14aoqb2._.js +0 -151
  140. package/.next/static/chunks/2-az50vi0iboz.js +0 -5
  141. package/.next/static/chunks/2bt9wtnw1g0g_.css +0 -1
  142. package/.next/static/chunks/2mi013mf2pu08.js +0 -1
  143. package/.next/static/chunks/2wmat901j6po0.js +0 -1
  144. package/.next/static/chunks/332-owz6utwp5.js +0 -1
  145. package/.next/static/chunks/39h0f3s2ddxz_.js +0 -65
  146. package/.next/static/chunks/3ab7oxjuh1asy.js +0 -1
  147. /package/.next/static/{fn1O5hprdyzrIbY1gapbZ → 4kpNMSdt6_Tq6ls8b4gmd}/_buildManifest.js +0 -0
  148. /package/.next/static/{fn1O5hprdyzrIbY1gapbZ → 4kpNMSdt6_Tq6ls8b4gmd}/_clientMiddlewareManifest.js +0 -0
  149. /package/.next/static/{fn1O5hprdyzrIbY1gapbZ → 4kpNMSdt6_Tq6ls8b4gmd}/_ssgManifest.js +0 -0
@@ -1,65 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,29821,e=>{"use strict";var t=e.i(40798),s=e.i(96341),r=e.i(3547),a=e.i(70065),n=e.i(67881),i=e.i(23750);let o=`// emitMetric.ts - sends a custom event through the New Relic browser agent (no key in your code)
2
- // Needs a recent @newrelic/browser-agent (recordCustomEvent). Using New Relic's copy-paste snippet instead? Call window.newrelic.recordCustomEvent the same way.
3
- import { getAgent } from './newrelic'; // from snippet 1
4
-
5
- export function emitMetric(name: string, value: number, attrs: Record<string, string | number | boolean> = {}) {
6
- // No-op until <NewRelicAgent /> has mounted, so this is safe to call anywhere.
7
- getAgent()?.recordCustomEvent('MetricFlowEvent', { name, value, page: location.pathname, ...attrs });
8
- }
9
-
10
- // emitMetric('checkout_step', 2, { step: 'payment' });`,l=`// npm i @sentry/browser
11
- import * as Sentry from '@sentry/browser';
12
-
13
- Sentry.init({
14
- dsn: '<YOUR_SENTRY_DSN>', // Sentry > Project settings > Client Keys (DSN)
15
- integrations: [Sentry.browserTracingIntegration()], // records page loads and web vitals (LCP, CLS, INP, TTFB)
16
- tracesSampleRate: 0.1, // share of page loads recorded; raise it on low-traffic sites
17
- });`,c="border-[#2d3748] bg-[#1a202c] shadow-md";function d({n:e,title:r,help:i,code:o}){let[l,h]=(0,s.useState)(null);return(0,t.jsxs)(a.Card,{className:c,children:[(0,t.jsxs)(a.CardHeader,{children:[(0,t.jsx)(a.CardTitle,{className:"text-base font-bold text-white",children:r}),(0,t.jsx)(a.CardDescription,{className:"text-sm text-gray-400",children:i})]}),(0,t.jsxs)(a.CardContent,{className:"flex flex-col gap-3",children:[(0,t.jsx)("pre",{tabIndex:0,"aria-label":`Code snippet ${e}`,className:"overflow-x-auto rounded-md border border-[#2d3748] bg-[#0f1419] p-3 text-xs text-gray-300",children:o}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)(n.Button,{variant:"outline","aria-label":`Copy snippet ${e}: ${r.replace(/^\d+\. /,"")}`,onClick:()=>{navigator.clipboard.writeText(o).then(()=>h("ok"),()=>h("fail")),setTimeout(()=>h(null),2500)},children:"Copy"}),(0,t.jsx)("span",{"aria-live":"polite",className:`text-sm ${"fail"===l?"text-[#f87171]":"text-[#3ee0a1]"}`,children:"ok"===l?"Copied":"fail"===l?"Copy failed, select the text and copy manually":""})]})]})]})}function h({label:e,state:s,detail:r}){let a="ok"===s?"text-[#3ee0a1]":"bad"===s?"text-[#f87171]":"text-gray-400";return(0,t.jsxs)("div",{className:"flex items-start gap-3 border-b border-[#2d3748] py-2 last:border-0",children:[(0,t.jsx)("span",{className:`font-mono text-sm ${a}`,"aria-hidden":!0,children:"ok"===s?"✓":"bad"===s?"✗":"…"}),(0,t.jsx)("span",{className:"sr-only",children:"ok"===s?"working":"bad"===s?"not working":"checking"}),(0,t.jsx)("span",{className:"text-sm text-gray-300 w-56 shrink-0",children:e}),(0,t.jsx)("span",{className:`min-w-0 text-sm ${a}`,children:r})]})}function u({label:e,s}){let r="Checking…",a="text-gray-400";if(s?.error)r=s.error,a="text-[#f87171]";else if(s){let e=null!==s.recent&&s.recent>0;r=e?`Receiving data${s.lastEventAt?` \xb7 last event ${new Date(s.lastEventAt).toLocaleTimeString()}`:""}`:s.lastEventAt?`None in the last 5 minutes \xb7 last event ${new Date(s.lastEventAt).toLocaleString()}`:"None yet",a=e?"text-[#3ee0a1]":"text-[#f59e0b]"}return(0,t.jsxs)("div",{className:"flex items-center justify-between gap-4 border-b border-[#2d3748] py-2 last:border-0",children:[(0,t.jsx)("span",{className:"text-sm text-gray-300 shrink-0",children:e}),(0,t.jsx)("span",{className:`min-w-0 break-words text-right text-sm ${a}`,children:r})]})}e.s(["ConnectPage",0,function(){let[e,p]=(0,s.useState)(null),[x,m]=(0,s.useState)(""),[g,y]=(0,s.useState)(null),[f,b]=(0,s.useState)(!1),[w,N]=(0,s.useState)(!1),C=(0,s.useCallback)(()=>{fetch("/api/connect").then(e=>e.json()).then(p).catch(()=>{})},[]);async function k(){b(!0),y(null);try{let e=await fetch("/api/setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({NEWRELIC_INSERT_KEY:x})}),t=await e.json();t.saved?(m(""),N(!1),y({ok:!0,text:"Insert key saved."}),C()):y({ok:!1,text:t.error??t.results?.NEWRELIC_INSERT_KEY?.error??"Could not save the key."})}catch{y({ok:!1,text:"Could not reach the dashboard server."})}finally{b(!1)}}async function j(){b(!0),y(null);try{let e=await fetch("/api/connect",{method:"POST"}),t=await e.json();y(t.sent?{ok:!0,text:"Test event sent. It can take up to a minute to show below."}:{ok:!1,text:t.error??"Failed."}),C()}catch{y({ok:!1,text:"Could not reach the dashboard server."})}finally{b(!1)}}if((0,s.useEffect)(()=>{C();let e=setInterval(()=>{document.hidden||C()},5e3);return()=>clearInterval(e)},[C]),e?.error)return(0,t.jsx)(a.Card,{className:c,children:(0,t.jsx)(a.CardContent,{className:"p-10 text-center","aria-live":"polite",children:(0,t.jsx)("p",{className:"text-sm text-[#f87171]",children:e.error})})});if(e&&!e.configured)return(0,t.jsx)(a.Card,{className:c,children:(0,t.jsxs)(a.CardContent,{className:"flex flex-col items-center gap-3 p-10 text-center",children:[(0,t.jsx)("h3",{className:"text-lg font-semibold text-white",children:"Set up your keys first"}),(0,t.jsx)("p",{className:"max-w-md text-sm text-gray-400",children:"Add your New Relic or Sentry keys, then come back to connect your site."}),(0,t.jsx)(r.default,{href:"/setup",className:(0,n.buttonVariants)(),children:"Go to setup"})]})});let v=!e?.tools||e.tools.includes("new-relic"),I=!e?.tools||e.tools.includes("sentry"),S=2*!!v+ +!!I+1;return(0,t.jsxs)("div",{className:"flex flex-col gap-6 max-w-3xl",children:[v&&(0,t.jsxs)(a.Card,{className:c,children:[(0,t.jsxs)(a.CardHeader,{children:[(0,t.jsx)(a.CardTitle,{className:"text-base font-bold text-white",children:"Connection"}),(0,t.jsx)(a.CardDescription,{className:"text-sm text-gray-400",children:"Each link in the chain from your site to this dashboard. Fix the first \\u2717."})]}),(0,t.jsxs)(a.CardContent,{"aria-live":"polite",children:[(0,t.jsx)(h,{label:"Keys for reading",state:e?"ok":"wait",detail:e?.accountId?`Reading New Relic account ${e.accountId}`:"Checking…"}),(0,t.jsx)(h,{label:"Browser app in New Relic",state:e?.setup?e.setup.error?"bad":e.setup.appCount>0?"ok":"bad":"wait",detail:e?.setup?e.setup.error?e.setup.error:e.setup.appCount>0?`${e.setup.appName} \u00b7 application ID ${e.setup.applicationId}`:"None yet. Create one: New Relic > Add data > Browser monitoring. Until then your site has no application ID to send to.":"Checking…"}),(0,t.jsx)(h,{label:"Browser key",state:e?.setup?e.setup.browserKey?"ok":"bad":"wait",detail:e?.setup?e.setup.browserKey?`${e.setup.browserKey} \u00b7 already filled into snippet 1 below`:"Could not read it. Copy the key VALUE from New Relic > API keys (type Ingest - Browser), not the ID beside it.":"Checking…"}),(0,t.jsx)(h,{label:"Your site sending data",state:e?.browser?(e.browser.recent??0)>0?"ok":"bad":"wait",detail:e?.browser?(e.browser.recent??0)>0?"New Relic is receiving page views":"No page views yet. Load your site, then check for blocked requests to nr-data.net - ad and privacy blockers drop them silently.":"Checking…"})]})]}),(0,t.jsxs)(a.Card,{className:c,children:[(0,t.jsxs)(a.CardHeader,{children:[(0,t.jsx)(a.CardTitle,{className:"text-base font-bold text-white",children:"Events received (last 5 minutes)"}),(0,t.jsxs)(a.CardDescription,{className:"text-sm text-gray-400",children:[e?.accountId?(0,t.jsxs)(t.Fragment,{children:["Querying New Relic account ",(0,t.jsx)("span",{className:"font-mono text-gray-200",children:e.accountId}),". "]}):null,"Updates every few seconds. All rows empty? Check this is the account your site sends to."]})]}),(0,t.jsxs)(a.CardContent,{"aria-live":"polite",children:[v&&(0,t.jsx)(u,{label:"Browser agent (page views)",s:e?.browser}),v&&(0,t.jsx)(u,{label:"Custom events (emitMetric / test event)",s:e?.custom}),I&&(0,t.jsx)(u,{label:"Sentry errors",s:e?.sentry})]})]}),v&&(0,t.jsxs)(a.Card,{className:c,children:[(0,t.jsxs)(a.CardHeader,{children:[(0,t.jsx)(a.CardTitle,{className:"text-base font-bold text-white",children:"Two different New Relic keys"}),(0,t.jsxs)(a.CardDescription,{className:"text-sm text-gray-400",children:[(0,t.jsx)("strong",{className:"text-gray-200",children:"User API key"})," (set on Setup): lets this dashboard ",(0,t.jsx)("em",{children:"read"})," your data."," ",(0,t.jsx)("strong",{className:"text-gray-200",children:"Ingest - License key"})," (below): lets a script ",(0,t.jsx)("em",{children:"send"})," events. Only the Insert key is used by the test button. The Browser agent snippet uses a third key, the ",(0,t.jsx)("strong",{className:"text-gray-200",children:"Ingest - Browser"})," key. Dashboards for US New Relic accounts only."]})]}),(0,t.jsxs)(a.CardContent,{className:"flex flex-col gap-3",children:[e?.insertKeySet&&!w?(0,t.jsxs)("p",{className:"text-sm text-[#3ee0a1]",children:["✓ Insert key is set"," ",(0,t.jsx)("button",{type:"button",className:"ml-2 text-gray-300 underline",onClick:()=>N(!0),children:"Replace"})]}):(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsx)("label",{htmlFor:"insert-key",className:"text-sm font-medium text-gray-300",children:"Insert key · sends test events"}),(0,t.jsx)("p",{id:"insert-key-help",className:"text-xs text-gray-400",children:'Only needed for the test button and custom events. Different from the User key. Create it as type "Ingest - License".'}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(i.Input,{id:"insert-key","aria-describedby":"insert-key-help",type:"password",autoComplete:"off",spellCheck:!1,placeholder:"Ingest - License key",value:x,onChange:e=>m(e.target.value),className:"bg-[#0f1419] border-[#2d3748] text-gray-200 font-mono text-xs"}),(0,t.jsx)(n.Button,{onClick:k,disabled:f||!x.trim(),children:"Save"})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)(n.Button,{onClick:j,disabled:f||!e?.insertKeySet,children:"Send test event"}),!e?.insertKeySet&&(0,t.jsx)("span",{className:"text-sm text-gray-400",children:"Add an Insert key first"}),g&&(0,t.jsx)("span",{"aria-live":"polite",className:`text-sm ${g.ok?"text-[#3ee0a1]":"text-[#f87171]"}`,children:g.text})]})]})]}),v&&(0,t.jsx)(a.Card,{className:c,children:(0,t.jsxs)(a.CardContent,{className:"p-4 text-sm text-[#f87171] border-l-2 border-[#f87171]",children:[(0,t.jsx)("strong",{children:"Snippet 1 runs in the browser, so its key is public."})," Use the ",(0,t.jsx)("strong",{children:"Ingest - Browser"})," key (starts ",(0,t.jsx)("span",{className:"font-mono",children:"NRJS-"}),"), never your ",(0,t.jsx)("span",{className:"font-mono",children:"NRAK-"})," User key from Setup - that one would hand every visitor full read/write access to your account. The application ID is also not your account ID."]})}),v&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(d,{n:1,title:"1. New Relic Browser agent",help:"Gives page views, load timing and Core Web Vitals. Create the Browser app in New Relic first (Add data > Browser monitoring) - that is where the NRJS- key and the application ID come from.",code:(({accountId:e,applicationId:t,browserKey:s}={})=>`// Step 0 - create the Browser app first: New Relic > Add data > Browser monitoring.
18
- // Without it there is no ingest key and no application ID to copy.
19
- // That page gives you both:
20
- // ingest key starts with NRJS- (NOT your NRAK- User API key from Setup)
21
- // application ID a plain number (NOT your account ID - they look identical)
22
- // Copy the key VALUE, not the ID shown beside it in the key list: an ID is
23
- // accepted by the form but rejected by the beacon, and nothing is logged.
24
- // npm i @newrelic/browser-agent
25
-
26
- // .env.local - NEXT_PUBLIC_* values are inlined into your public JavaScript.
27
- // Only the NRJS- ingest key belongs here. An NRAK- User key would be published
28
- // to every visitor as a full-account read/write credential.
29
- // NEXT_PUBLIC_NEWRELIC_BROWSER_KEY=${s??"NRJS-xxxxxxxxxxxxxxxxxxx"}
30
- // NEXT_PUBLIC_NEWRELIC_APP_ID=${t??"123456789"}
31
- // NEXT_PUBLIC_NEWRELIC_ACCOUNT_ID=${e??"1234567"}
32
-
33
- // newrelic.ts
34
- import { BrowserAgent } from '@newrelic/browser-agent/loaders/browser-agent';
35
-
36
- const licenseKey = process.env.NEXT_PUBLIC_NEWRELIC_BROWSER_KEY!;
37
- const applicationID = process.env.NEXT_PUBLIC_NEWRELIC_APP_ID!;
38
- const accountID = process.env.NEXT_PUBLIC_NEWRELIC_ACCOUNT_ID!;
39
-
40
- let agent: BrowserAgent | undefined;
41
-
42
- // Never construct at import time: the agent touches window, so a module-level
43
- // \`export const agent = new BrowserAgent(...)\` fails \`next build\` on any
44
- // prerendered route - TypeError: Cannot create property 'NREUM' on boolean 'false'.
45
- export function startAgent() {
46
- agent ??= new BrowserAgent({
47
- init: { distributed_tracing: { enabled: true }, privacy: { cookies_enabled: true } },
48
- info: { beacon: 'bam.nr-data.net', errorBeacon: 'bam.nr-data.net', licenseKey, applicationID, sa: 1 },
49
- loader_config: { accountID, trustKey: accountID, agentID: applicationID, licenseKey, applicationID },
50
- });
51
- return agent;
52
- }
53
-
54
- export const getAgent = () => agent;
55
-
56
- // app/newrelic-agent.tsx - render <NewRelicAgent /> once in app/layout.tsx.
57
- 'use client';
58
- import { useEffect } from 'react';
59
-
60
- export function NewRelicAgent() {
61
- // Dynamic import keeps the agent out of the server bundle entirely.
62
- useEffect(() => { import('./newrelic').then(m => m.startAgent()); }, []);
63
- return null;
64
- }
65
- // That alone gives you PageView, load timing, Core Web Vitals and JS errors.`)({accountId:e?.accountId,applicationId:e?.setup?.applicationId,browserKey:e?.setup?.browserKey})}),(0,t.jsx)(d,{n:2,title:"2. emitMetric() helper",help:"Send your own numbers from your site. Uses the agent from snippet 1, so no key goes in your code.",code:o})]}),I&&(0,t.jsx)(d,{n:v?3:1,title:`${v?3:1}. Sentry errors and web vitals`,help:"Send JavaScript errors, page loads and web vitals to Sentry. Call it once, before anything else on your site runs. Use your project's DSN.",code:l}),(0,t.jsx)(a.Card,{className:c,children:(0,t.jsxs)(a.CardHeader,{children:[(0,t.jsxs)(a.CardTitle,{className:"text-base font-bold text-white",children:[S,". Verify"]}),(0,t.jsx)(a.CardDescription,{className:"text-sm text-gray-400",children:v?(0,t.jsx)(t.Fragment,{children:'Reload your site, then watch "Events received" above turn green. Use Send test event to check the custom-event path.'}):(0,t.jsx)(t.Fragment,{children:'Cause an error on your site, then watch "Sentry errors" above turn green.'})})]})})]})}],29821)},70065,e=>{"use strict";var t=e.i(40798),s=e.i(28603);e.s(["Card",0,function({className:e,size:r="default",...a}){return(0,t.jsx)("div",{"data-slot":"card","data-size":r,className:(0,s.cn)("group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",e),...a})},"CardContent",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"card-content",className:(0,s.cn)("px-(--card-spacing)",e),...r})},"CardDescription",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"card-description",className:(0,s.cn)("text-sm text-muted-foreground",e),...r})},"CardHeader",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"card-header",className:(0,s.cn)("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",e),...r})},"CardTitle",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"card-title",className:(0,s.cn)("font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",e),...r})}])},91153,e=>{"use strict";var t=e.i(96341);let s=(...e)=>e.filter((e,t,s)=>!!e&&""!==e.trim()&&s.indexOf(e)===t).join(" ").trim(),r={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"},a=(0,t.createContext)({}),n=(0,t.forwardRef)(({color:e,size:n,width:i,height:o,strokeWidth:l,absoluteStrokeWidth:c,nonScalingStroke:d,className:h="",children:u,iconNode:p=[],icon:x={node:p,aliases:[],size:24},...m},g)=>{let{size:y=24,strokeWidth:f=2,absoluteStrokeWidth:b=!1,nonScalingStroke:w=!1,color:N="currentColor",className:C=""}=(0,t.useContext)(a)??{},k=!!u||(e=>{for(let t in e)if(t.startsWith("aria-")||"role"===t||"title"===t)return!0;return!1})(m),[j,v,I=[]]=function(e,t={}){return function(e,t={}){let a=t.attributeNames??{},n=e=>a[e]??e,i=e.size??e.width??r.width,o=e.size??e.height??r.height,l=e.aliases?.filter(e=>"string"==typeof e&&""!==e.trim()).map(e=>`lucide-${e}`)??[],c=[...e.name?[`lucide-${e.name}`]:[],...l],d=t.className?.split(" ").filter(Boolean)??[],h=!1===t.includeDefaultClasses?s(...d):s("lucide",...c,...d),u=t.absoluteStrokeWidth?Number(t.strokeWidth??r["stroke-width"])*Number(e.size??e.width??r.width)/Number(t.size??t.width??r.width):t.strokeWidth??r["stroke-width"];return["svg",{...Object.entries(r).reduce((e,[t,s])=>(e[n(t)]=s,e),{}),..."color"in t&&t.color&&{[n("stroke")]:t.color},..."size"in t&&null!=t.size&&{[n("width")]:t.size,[n("height")]:t.size},..."width"in t&&null!=t.width&&{[n("width")]:t.width},..."height"in t&&null!=t.height&&{[n("height")]:t.height},[n("stroke-width")]:u,...h&&{[n("class")]:h},[n("viewBox")]:`0 0 ${i} ${o}`,...!1===t.hasA11yProp?{[n("aria-hidden")]:"true"}:{},..."attributes"in t&&t.attributes},e.node.map(e=>{let[s,r,a]=e,i=t.nonScalingStroke?{[n("vector-effect")]:"non-scaling-stroke",...r}:r;return a?[s,i,a]:[s,i]})]}(e,{...t,attributeNames:{...t.attributeNames,class:"className","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-linejoin":"strokeLinejoin","vector-effect":"vectorEffect"}})}(x,{color:e??N,width:i??n??y,height:o??n??y,strokeWidth:l??f,absoluteStrokeWidth:c??b,nonScalingStroke:d??w,className:s(C,h),hasA11yProp:k,attributes:m});return(0,t.createElement)(j,{ref:g,...v},[...I.map(([e,s])=>(0,t.createElement)(e,s)),...Array.isArray(u)?u:[u]])});e.s(["default",0,n],91153)}]);