Skip to content

Add Vercel Web Analytics to Next.js - #9

Draft
vercel[bot] wants to merge 1 commit into
mainfrom
vercel/vercel-web-analytics-to-nextjs-pt921e
Draft

Add Vercel Web Analytics to Next.js#9
vercel[bot] wants to merge 1 commit into
mainfrom
vercel/vercel-web-analytics-to-nextjs-pt921e

Conversation

@vercel

@vercel vercel Bot commented Feb 18, 2026

Copy link
Copy Markdown

Vercel Web Analytics Implementation

Successfully installed and configured Vercel Web Analytics for the FormaOS Next.js application.

Changes Made

1. Installed Package:

  • Added @vercel/analytics@^1.6.1 to dependencies using npm
  • Updated package-lock.json with the new dependency

2. Modified Files:

  • app/layout.tsx - Root layout file for the Next.js App Router

Implementation Details

In app/layout.tsx:

  • Added import: import { Analytics } from '@vercel/analytics/next';
  • Added <Analytics /> component inside the <body> tag, after the <ThemeProvider>{children}</ThemeProvider> component
  • Preserved all existing code structure, fonts, metadata, and theme provider configuration

Verification Completed

ESLint: Linter ran successfully with no errors related to our changes
TypeScript: Type checking passed without errors
Build: Next.js build completed successfully, generating all routes properly
Dependencies: package-lock.json properly updated with new dependency tree

Project Details

  • Router Type: App Router (using app directory)
  • Package Manager: npm
  • Layout Location: app/layout.tsx (root layout)
  • Framework: Next.js 16.1.1

The Analytics component is now properly configured and will automatically track page views and web vitals when the application is deployed to Vercel.


View Project · Web Analytics

Created by ejay-dev with Vercel Agent

## Vercel Web Analytics Implementation

Successfully installed and configured Vercel Web Analytics for the FormaOS Next.js application.

### Changes Made

**1. Installed Package:**
- Added `@vercel/analytics@^1.6.1` to dependencies using npm
- Updated package-lock.json with the new dependency

**2. Modified Files:**
- `app/layout.tsx` - Root layout file for the Next.js App Router

### Implementation Details

**In app/layout.tsx:**
- Added import: `import { Analytics } from '@vercel/analytics/next';`
- Added `<Analytics />` component inside the `<body>` tag, after the `<ThemeProvider>{children}</ThemeProvider>` component
- Preserved all existing code structure, fonts, metadata, and theme provider configuration

### Verification Completed

✅ **ESLint**: Linter ran successfully with no errors related to our changes
✅ **TypeScript**: Type checking passed without errors
✅ **Build**: Next.js build completed successfully, generating all routes properly
✅ **Dependencies**: package-lock.json properly updated with new dependency tree

### Project Details

- **Router Type**: App Router (using app directory)
- **Package Manager**: npm
- **Layout Location**: app/layout.tsx (root layout)
- **Framework**: Next.js 16.1.1

The Analytics component is now properly configured and will automatically track page views and web vitals when the application is deployed to Vercel.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
@vercel

vercel Bot commented Feb 18, 2026

Copy link
Copy Markdown
Author

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
forma-os Ready Ready Preview, Comment Feb 18, 2026 6:10am

ejay-dev added a commit that referenced this pull request May 12, 2026
…ma (#58)

The OpenAPI Error schema declares `error` as a string:

    Error:
      type: object
      properties:
        error: { type: string }
        message: { type: string }

But twelve v1 route handlers were returning the nested `{ error: { message: '...' } }` shape. Callers following the OpenAPI contract null-deref on `.error.message`; callers reading the live API see two different shapes depending on which endpoint they hit.

Audit doc finding #9 cited the four most-visible offenders; the grep
turned up eight more in the same area, all the same shape. Fixing
them all in one mechanical pass — splitting per-route would leave the
contract half-broken between merges.

Routes updated (all v1):
  - /forms (POST validation + GET/POST 500)
  - /forms/[formId] (GET/DELETE 404, PATCH 500)
  - /forms/[formId]/duplicate (500)
  - /forms/[formId]/publish (500)
  - /forms/[formId]/submissions (GET 500, POST 422 validation + 500)
  - /forms/[formId]/submissions/[submissionId] (GET 404, PATCH 400 + 500)
  - /forms/[formId]/submissions/export (400 + 500 + 404 + 500)
  - /forms/[formId]/analytics (403 entitlement + 500)
  - /analytics/trends (400 + 500)
  - /reports/custom (GET 500, POST 400 + 500)
  - /reports/custom/_entitlement helper (403)
  - /ai/usage (500)

The 422 validation response on /submissions keeps its `details: err.validationErrors` sibling — flat-shape plus a domain-specific extra is consistent with the spec; the nested wrapper added no value.

Verified:
  - grep across app/api/v1/ for `error: {` returns zero hits.
  - npx tsc --noEmit -p tsconfig.typecheck.json: clean.
  - npx jest __tests__/api/v1: 36/36 pass.
  - No test asserted the nested shape (the two `error: { message }`
    references in v1 tests are Supabase-DB-error mocks, not API
    response assertions).

Co-authored-by: ejaz <ejaz@local>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
ejay-dev added a commit that referenced this pull request May 12, 2026
Phase A (audit dimensions) is now walked end-to-end. This PR adds:

  §9b — Dead-entitlement removals (records the #57 deletion of
  soc2_certification + executive_rollup; closes audit row #14).

  §9c — A→B→C data flow findings (4 verified rows: HIGH role-change
  surface gap, HIGH trial-state stale Zustand, MED org-name client
  cache, MED revokeInvitation org-id input-trust gap). Plus 12
  rejected-with-reason rows from the data-flow agent pass that
  did not survive direct inspection (force-dynamic at /app/* layout
  killed most of the "stale SSR cache" claims; the Stripe webhook
  already calls revalidatePath; the email-mismatch invite-accept
  scenario is explicitly guarded; "if a user is added to multiple
  orgs in the future" is speculative not actual).

Also reclassifies:

  #19 (onboarding framework provisioning race) HIGH → MED. The
  proposed audit fix doesn't actually close the race; the real
  fix is a "provisioning in progress" state on /app/compliance/
  frameworks/[slug], which is a different surface from onboarding.

  #9 (v1 error-shape consistency) — added "scope larger than first
  cited" note since the grep found 12 files, all flattened in #58.

PR refs added to rows #9 and #14. The audit now records 36 verified
findings; the open HIGH set is #19 (reclassified MED), #33 (no
role-change action), #34 (trial state stale in Zustand).

Co-authored-by: ejaz <ejaz@local>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
ejay-dev pushed a commit that referenced this pull request May 13, 2026
Closes marketing-audit finding D — /compliance and /care return 404
on the live site.

Per the user's brief, the first job was to determine rename vs
accidental delete. Reality on direct inspection:

  - app/(marketing)/compliance/ and app/(marketing)/care/ directories
    do not exist on this branch, and git log --all --diff-filter=D
    against either path returns zero history. Neither route was
    ever built in this repo.
  - grep across the codebase for '/compliance' and '/care' as link
    targets (href / Link / mailto exclusion) returns zero hits in
    app/, components/, config/, lib/. There are no inbound links to
    fix.
  - app/sitemap.ts does not list either URL.

So D is not a rename gone-wrong or an accidental delete — it's a
gap in the URL space. The audit found them by checking the brief's
checklist of "expected" marketing URLs against the live site, and
substituted /trust (compliance hub) and /healthcare-compliance
(closest care landing) for the rest of the dynamic walk
(2026-05-13 marketing audit, §11).

The pragmatic fix is a temporary 307 redirect for each to the
substituted equivalent: any buyer who URL-types one of these (or
follows a stale external mention) lands on a useful page instead of
the marketing 404. permanent: false keeps the door open for an
intentional /compliance or /care landing later — the audit's §3
cross-cutting #9 already flags URL cannibalization across
overlapping industry pages, so resolving that taxonomy may want
these slugs for canonical hubs.

Verified:
  - tsc --noEmit -p tsconfig.typecheck.json: clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ejay-dev added a commit that referenced this pull request May 13, 2026
…#71)

Closes marketing-audit finding D — /compliance and /care return 404
on the live site.

Per the user's brief, the first job was to determine rename vs
accidental delete. Reality on direct inspection:

  - app/(marketing)/compliance/ and app/(marketing)/care/ directories
    do not exist on this branch, and git log --all --diff-filter=D
    against either path returns zero history. Neither route was
    ever built in this repo.
  - grep across the codebase for '/compliance' and '/care' as link
    targets (href / Link / mailto exclusion) returns zero hits in
    app/, components/, config/, lib/. There are no inbound links to
    fix.
  - app/sitemap.ts does not list either URL.

So D is not a rename gone-wrong or an accidental delete — it's a
gap in the URL space. The audit found them by checking the brief's
checklist of "expected" marketing URLs against the live site, and
substituted /trust (compliance hub) and /healthcare-compliance
(closest care landing) for the rest of the dynamic walk
(2026-05-13 marketing audit, §11).

The pragmatic fix is a temporary 307 redirect for each to the
substituted equivalent: any buyer who URL-types one of these (or
follows a stale external mention) lands on a useful page instead of
the marketing 404. permanent: false keeps the door open for an
intentional /compliance or /care landing later — the audit's §3
cross-cutting #9 already flags URL cannibalization across
overlapping industry pages, so resolving that taxonomy may want
these slugs for canonical hubs.

Verified:
  - tsc --noEmit -p tsconfig.typecheck.json: clean.

Co-authored-by: ejaz <ejaz@local>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
ejay-dev added a commit that referenced this pull request May 14, 2026
Audit row #9 — 8 marketing pages targeted overlapping search intents
(3 healthcare, 3 NDIS, 2 financial) and each carried a self-canonical,
so Google could not pick a primary. User chose full 308 consolidation
with explicit link-safety guardrails.

Canonical winners (the buyer-facing industry money pages, which carry
the rich IndustryHero + dashboard mock):

- Healthcare:  /healthcare-compliance
- NDIS:        /ndis-providers
- Financial:   /financial-services-compliance

The 5 duplicates 308 to the primary:

- /healthcare-compliance-platform -> /healthcare-compliance
- /use-cases/healthcare            -> /healthcare-compliance
- /ndis-compliance-system          -> /ndis-providers
- /use-cases/ndis-aged-care        -> /ndis-providers
- /use-cases/financial-services    -> /financial-services-compliance

Permanent (308) so search engines transfer link equity to the canonical
and deindex the duplicates over time.

Link-safety sweep (so internal nav does not pay a redirect hop):

- next.config.ts: 5 new redirect entries with a block comment
  explaining the audit rationale.
- 5 page directories deleted (page.tsx, content components, the OG
  wrappers added in #86). Existing media in public/marketing-media/
  kept on disk in case the routes return.
- Internal references rewritten to canonicals: Industries homepage,
  ComparePageTemplate, AuditEvidenceContent, WhatIsCosContent.
- app/sitemap.ts: 5 entries removed with explanatory comment so the
  next sitemap regenerator does not silently re-add them.
- lib/marketing/background-media.ts: 5 ROUTE_MEDIA entries removed.
- 3 E2E specs (marketing-screenshots, healthcare-ndis-positioning,
  full-user-journey) point at canonicals so URL-assertion paths do
  not break after redirect.
- docs/audit/2026-05-13-marketing-audit.md row #9 annotated with the
  shipped resolution.

Verified: tsc --noEmit clean. Zero remaining .tsx/.ts internal
references to the 5 retired paths outside next.config.ts (the
redirect sources, intentional) and sitemap.ts (the explanatory
comments, intentional).

Co-authored-by: ejaz <ejaz@local>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants