Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion PROMPTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ on the server and in the browser, so traces, errors, and replays all carry
it.
- Database spans for the Postgres queries in `lib/db`.
- Session replay in the browser, so a failed chat turn links to what the
user saw.
user saw. Record the page as the shopper saw it, but mask their name and
email.
- Full trace sampling for the workshop.
Use the 11.0 release candidate of the Sentry SDK, npm tag `next`. Add only
what these points need; no edge runtime config, no extra error boundaries.
Expand Down
3 changes: 2 additions & 1 deletion labs/02-instrument-storefront.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ Undo the change: `git checkout -- . && git clean -fd` in `apps/storefront`.
> carry it.
> - Database spans for the Postgres queries in `lib/db`.
> - Session replay in the browser, so a failed chat turn links to what the
> user saw.
> user saw. Record the page as the shopper saw it, but mask their name and
> email.
> - Full trace sampling for the workshop.
> Use the 11.0 release candidate of the Sentry SDK, npm tag `next`. Add only
> what these points need; no edge runtime config, no extra error boundaries.
Expand Down
5 changes: 4 additions & 1 deletion solutions/02-storefront/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
- `instrumentation.ts` — loads the server config for the Node.js runtime only;
wires `onRequestError` for Server Component and proxy errors.
- `instrumentation-client.ts` — browser init with session replay and router
transition tracing.
transition tracing. Replay records page text, inputs, and images as the
shopper saw them; only elements marked `data-sentry-mask` stay masked.
- `components/assistant/account-card.tsx` — marks the shopper's name and
email with `data-sentry-mask`.
- `next.config.ts` — wraps the config with `withSentryConfig` (imported from
`@sentry/nextjs/config`) for source map upload, skipped when
`SENTRY_AUTH_TOKEN` is unset.
Expand Down
31 changes: 29 additions & 2 deletions solutions/02-storefront/instrumentation.patch
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,47 @@ index 0000000..0000000 100644
});

return createUIMessageStreamResponse({
diff --git a/apps/storefront/components/assistant/account-card.tsx b/apps/storefront/components/assistant/account-card.tsx
index 0000000..0000000 100644
--- a/apps/storefront/components/assistant/account-card.tsx
+++ b/apps/storefront/components/assistant/account-card.tsx
@@ -24,9 +24,12 @@ export function AccountCard({ customer, orders }: AccountInfo) {
<div className="w-full overflow-hidden rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-black">
<div className="flex items-center justify-between gap-3 border-b border-neutral-200 p-3 dark:border-neutral-800">
<div className="min-w-0">
- <h4 className="truncate text-sm font-medium">{customer.name}</h4>
+ <h4 data-sentry-mask className="truncate text-sm font-medium">
+ {customer.name}
+ </h4>
<p className="truncate text-xs text-neutral-500 dark:text-neutral-400">
- {customer.email} · member since {customer.memberSince}
+ <span data-sentry-mask>{customer.email}</span> · member since{" "}
+ {customer.memberSince}
</p>
</div>
<span className="shrink-0 rounded-full bg-blue-600 px-2.5 py-1 text-xs font-semibold text-white">
diff --git a/apps/storefront/instrumentation-client.ts b/apps/storefront/instrumentation-client.ts
new file mode 100644
index 0000000..0000000
--- /dev/null
+++ b/apps/storefront/instrumentation-client.ts
@@ -0,0 +1,15 @@
@@ -0,0 +1,23 @@
+import * as Sentry from "@sentry/nextjs";
+import { DEMO_USER } from "lib/demo-user";
+
+Sentry.init({
+ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
+ tracesSampleRate: 1,
+ replaysSessionSampleRate: 1,
+ integrations: [Sentry.replayIntegration()],
+ integrations: [
+ // Records the page as the shopper saw it. Elements marked
+ // data-sentry-mask (the account card's name and email) stay masked.
+ Sentry.replayIntegration({
+ maskAllText: false,
+ maskAllInputs: false,
+ blockAllMedia: false,
+ }),
+ ],
+});
+
+// The store has no sign-in; a real app calls setUser after the user signs in.
Expand Down
Loading