Skip to content

Conversation

@lindesvard
Copy link
Contributor

@lindesvard lindesvard commented Dec 15, 2025

Summary by CodeRabbit

  • Documentation

    • Added full Nuxt, React, and Vue SDK guides with installation, configuration, usage examples, and server-side guidance.
  • New Features

    • Released a Nuxt SDK: client plugin exposing $openpanel/useOpenPanel, auto-imported composable, event tracking, identification, global properties, revenue and increment/decrement helpers, and server-side tracking.
    • Optional proxy mode to route events via an app endpoint to improve adblocker reliability.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 15, 2025

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

Project Deployment Review Updated (UTC)
openpanel-public Error Error Dec 15, 2025 9:27pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 15, 2025

Walkthrough

Adds a new Nuxt SDK package and documentation for Nuxt, React, and Vue. The Nuxt SDK includes a Nuxt module, client plugin, composable, server proxy route, types, and packaging/configuration files enabling client and optional proxied server-side event forwarding.

Changes

Cohort / File(s) Change Summary
SDK Documentation
apps/public/content/docs/(tracking)/sdks/nuxt.mdx, apps/public/content/docs/(tracking)/sdks/react.mdx, apps/public/content/docs/(tracking)/sdks/vue.mdx
New or expanded MDX guides for Nuxt, React, and Vue integrating OpenPanel: installation, config options, usage examples (track, identify, properties, revenue), client and server guidance. Nuxt doc describes proxy mode.
Nuxt SDK Package Config
packages/sdks/nuxt/package.json, packages/sdks/nuxt/build.config.ts, packages/sdks/nuxt/tsconfig.json, packages/sdks/nuxt/index.ts
New package metadata and build/dev scripts, unbuild config (failOnWarn: false), TypeScript config and a dev-only index re-exporting the module and ModuleOptions type.
Nuxt Module & Types
packages/sdks/nuxt/src/module.ts, packages/sdks/nuxt/src/types.d.ts
New Nuxt module (default export) and ModuleOptions type (extends OpenPanelOptions, adds optional proxy?). Module sets runtime public config, always registers client plugin and composable auto-import, and conditionally registers a server proxy route when proxy enabled. Type declarations augment NuxtApp and Vue ComponentCustomProperties with $openpanel.
Client Runtime Plugin
packages/sdks/nuxt/src/runtime/plugin.client.ts
Client plugin that initializes OpenPanel from runtimeConfig.public.openpanel, injects it as $openpanel into Nuxt app and Vue components, and provides types augmentation.
Composable
packages/sdks/nuxt/src/runtime/composables/useOpenPanel.ts
Adds useOpenPanel() composable that returns the injected $openpanel instance via useNuxtApp().
Server Proxy Route
packages/sdks/nuxt/src/runtime/server/api/[...openpanel].ts
New server API handler that proxies /api/openpanel/** (notably /track) to https://api.openpanel.dev. Builds client headers (Content-Type, openpanel-client-id, origin inference, user-agent, client IP), forwards body/method, propagates response status and JSON/text body, and handles errors/404s.

Sequence Diagram

sequenceDiagram
    participant App as Nuxt App / Component
    participant Composable as useOpenPanel()
    participant Plugin as Client Plugin
    participant SDK as OpenPanel SDK (browser)
    participant Proxy as Nuxt Server Proxy (/api/openpanel)
    participant API as OpenPanel API (api.openpanel.dev)

    Note over App,SDK: Direct client-side flow
    App->>Composable: op = useOpenPanel()
    Composable->>Plugin: obtain injected $openpanel
    Composable-->>App: return op
    App->>SDK: op.track(event)
    SDK->>API: POST /track
    API-->>SDK: 200 OK

    Note over App,API: Via server proxy (proxy enabled)
    App->>SDK: op.track(event) (apiUrl -> /api/openpanel/track)
    SDK->>Proxy: POST /api/openpanel/track
    Proxy->>Proxy: getClientHeaders() (origin, client-id, ip, ua)
    Proxy->>API: POST https://api.openpanel.dev/track (forwarded headers/body)
    API-->>Proxy: 200 OK
    Proxy-->>SDK: 200 OK
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Review the server proxy handler: header assembly (origin inference, IP extraction), method/body forwarding, and content-type handling.
  • Verify module registration logic: conditional proxy route, runtime config exposure, and auto-imports.
  • Check typings and declaration merges for NuxtApp and Vue ComponentCustomProperties.
  • Validate plugin initialization from runtimeConfig and provide/inject behavior.
  • Confirm package.json exports, workspace dependency wiring, and build scripts.

Poem

🐰 I hopped in with a module and key,
I brought a plugin and composable handy for thee,
I proxy and type and document too,
Track events near, or forward them through—
A little rabbit cheering: “Nuxt, go track free!”

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add nuxt sdk' directly describes the primary change: introducing a new Nuxt SDK with comprehensive module setup, runtime components, and documentation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/nuxt-sdk

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 684cba9 and ba86316.

📒 Files selected for processing (1)
  • packages/sdks/nuxt/src/runtime/server/api/[...openpanel].ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/sdks/nuxt/src/runtime/server/api/[...openpanel].ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (8)
packages/sdks/nuxt/tsconfig.json (1)

1-17: Align TypeScript types with Nuxt 3/4 target

You’re targeting Nuxt ^3.0.0 || ^4.0.0 but using @nuxt/types (Nuxt 2) in both types and devDependencies. For Nuxt 3+ modules it’s more typical to rely on nuxt/schema and @nuxt/kit types rather than @nuxt/types.

Consider:

  • Dropping @nuxt/types if it’s not needed.
  • Switching types to the Nuxt 3+ recommendations (e.g. ["@types/node", "nuxt/schema"]) if compatible with your existing base config.

This avoids mixed Nuxt 2/3 typings that can confuse tooling.

apps/public/content/docs/(tracking)/sdks/vue.mdx (1)

5-219: Tidy up unused MDX imports and consider using warning components

The Vue docs content looks solid and examples are consistent with the @openpanel/web API. Two small cleanups:

  • Link from next/link, DeviceIdWarning, and PersonalDataWarning are imported but not used anywhere in this page.
  • If you intend to show device‑ID / personal‑data notices (as in other SDK docs), consider actually rendering <PersonalDataWarning /> (and/or <DeviceIdWarning />) in an appropriate section; otherwise, drop the imports.

Purely cosmetic, but it keeps the MDX lean and clearer.

apps/public/content/docs/(tracking)/sdks/react.mdx (1)

5-245: Add missing useEffect imports in examples and clean up unused MDX imports

The React docs read well and mirror the Vue guide, but a couple of polish points:

  • Several snippets use useEffect (MyComponent, App, hook example) without showing import { useEffect } from 'react';. For copy‑paste friendliness, I’d add that import to at least the first snippet that uses useEffect.
  • PersonalDataWarning is imported but not rendered. Either add a short privacy callout with <PersonalDataWarning /> (similar to other docs) or remove the import.

This keeps examples directly runnable and MDX imports aligned with usage.

packages/sdks/nuxt/package.json (1)

1-40: Check Nuxt typings and devDep alignment with supported Nuxt versions

The packaging setup (exports, main, scripts, files) looks sane for a Nuxt module.

Given peerDependencies.nuxt is ^3.0.0 || ^4.0.0, keeping @nuxt/types@^2.18.1 as a devDependency can be misleading and may pull in Nuxt 2 type assumptions alongside Nuxt 3+.

Consider:

  • Removing @nuxt/types if it’s unused in this package.
  • Relying on @nuxt/kit and Nuxt 3+ typings (nuxt/schema) for module development instead.

This will keep the module’s type story aligned with the supported Nuxt versions.

packages/sdks/nuxt/src/runtime/composables/useOpenPanel.ts (1)

1-6: Composable is correct; optional typing/guards for ergonomics

Implementation is idiomatic for a Nuxt 3 composable and matches the plugin’s $openpanel injection.

If you want tighter typing and clearer failure modes, consider:

  • Explicit return type:
import type { OpenPanel } from '@openpanel/web';

export function useOpenPanel(): OpenPanel {
  const { $openpanel } = useNuxtApp();
  return $openpanel;
}
  • Optionally, throw or warn if $openpanel is missing (e.g. when the module/plugin isn’t registered or used on the server by mistake).

Not required, but it can improve DX.

packages/sdks/nuxt/src/runtime/plugin.client.ts (1)

1-30: Nuxt plugin wiring looks solid; consider a clearer misconfiguration guard

The plugin correctly:

  • Runs on the client (plugin.client.ts),
  • Reads public.openpanel as ModuleOptions,
  • Instantiates OpenPanel once,
  • Provides it under openpanel, matching the $openpanel access pattern,
  • Augments NuxtApp and Vue component types.

One optional DX improvement: add a lightweight guard around config before constructing OpenPanel so misconfigurations (e.g. missing clientId) fail with a clear message instead of a less obvious runtime error, for example:

setup() {
  const config = useRuntimeConfig().public.openpanel as ModuleOptions | undefined;

  if (!config?.clientId) {
    console.warn('[openpanel] Missing clientId in runtimeConfig.public.openpanel – OpenPanel will not be initialized.');
    return;
  }

  const op = new OpenPanel(config);

  return {
    provide: { openpanel: op },
  };
}

Not strictly necessary, but it makes module misconfiguration easier to diagnose.

packages/sdks/nuxt/src/runtime/server/api/[...openpanel].ts (1)

12-79: Strong proxy implementation; consider tightening event typing

The routing, header construction, /track gating, body forwarding, and response handling all look correct for this proxy. The only rough edge is the untyped event.

You can improve safety and editor support by using the concrete H3Event type:

-import {
-  createError,
-  defineEventHandler,
-  getHeader,
-  getRequestURL,
-  readBody,
-  setResponseStatus,
-} from 'h3';
+import {
+  createError,
+  defineEventHandler,
+  getHeader,
+  getRequestURL,
+  readBody,
+  setResponseStatus,
+} from 'h3';
+import type { H3Event } from 'h3';
@@
-const API_URL = 'https://api.openpanel.dev';
+const API_URL = 'https://api.openpanel.dev';
@@
-function getClientHeaders(event: any): Headers {
+function getClientHeaders(event: H3Event): Headers {
@@
-export default defineEventHandler(async (event) => {
+export default defineEventHandler(async (event: H3Event) => {

This keeps behavior identical while giving you proper typing on event.context, event.method, etc.

apps/public/content/docs/(tracking)/sdks/nuxt.mdx (1)

20-23: Minor wording/grammar polish in docs

The docs are clear and align with the implementation; a few small language tweaks would make them read more smoothly:

  • Use “server-side” (hyphenated) as an adjective.
  • Prefer “ad blockers” or “ad-blockers” spelling.

For example:

-Read more about server side tracking in the [Server Side Tracking](#track-server-events) section.
+Read more about server-side tracking in the [Server-Side Tracking](#track-server-events) section.
@@
-## Server side
+## Server-side
@@
-With the `proxy` option enabled, you can proxy your events through your server, which ensures all events are tracked since many adblockers block requests to third-party domains.
+With the `proxy` option enabled, you can proxy your events through your server, which ensures all events are tracked since many ad blockers block requests to third-party domains.

Feel free to adjust exact phrasing to match your documentation style.

Also applies to: 193-193, 239-256

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e7dc16 and 684cba9.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • apps/public/content/docs/(tracking)/sdks/nuxt.mdx (1 hunks)
  • apps/public/content/docs/(tracking)/sdks/react.mdx (1 hunks)
  • apps/public/content/docs/(tracking)/sdks/vue.mdx (1 hunks)
  • packages/sdks/nuxt/build.config.ts (1 hunks)
  • packages/sdks/nuxt/index.ts (1 hunks)
  • packages/sdks/nuxt/package.json (1 hunks)
  • packages/sdks/nuxt/src/module.ts (1 hunks)
  • packages/sdks/nuxt/src/runtime/composables/useOpenPanel.ts (1 hunks)
  • packages/sdks/nuxt/src/runtime/plugin.client.ts (1 hunks)
  • packages/sdks/nuxt/src/runtime/server/api/[...openpanel].ts (1 hunks)
  • packages/sdks/nuxt/src/types.d.ts (1 hunks)
  • packages/sdks/nuxt/tsconfig.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

When writing ClickHouse queries, always use the custom query builder from ./packages/db/src/clickhouse/query-builder.ts and ./packages/db/src/clickhouse/query-functions.ts

Files:

  • packages/sdks/nuxt/src/types.d.ts
  • packages/sdks/nuxt/src/runtime/plugin.client.ts
  • packages/sdks/nuxt/src/runtime/composables/useOpenPanel.ts
  • packages/sdks/nuxt/src/module.ts
  • packages/sdks/nuxt/src/runtime/server/api/[...openpanel].ts
  • packages/sdks/nuxt/build.config.ts
  • packages/sdks/nuxt/index.ts
🧬 Code graph analysis (3)
packages/sdks/nuxt/src/types.d.ts (2)
packages/sdks/nuxt/index.ts (1)
  • ModuleOptions (2-2)
packages/sdks/nuxt/src/module.ts (1)
  • ModuleOptions (10-10)
packages/sdks/nuxt/src/runtime/plugin.client.ts (3)
packages/sdks/nuxt/index.ts (1)
  • ModuleOptions (2-2)
packages/sdks/nuxt/src/module.ts (1)
  • ModuleOptions (10-10)
packages/sdks/nuxt/src/types.d.ts (1)
  • ModuleOptions (3-5)
packages/sdks/nuxt/src/module.ts (2)
packages/sdks/nuxt/index.ts (1)
  • ModuleOptions (2-2)
packages/sdks/nuxt/src/types.d.ts (1)
  • ModuleOptions (3-5)
🪛 LanguageTool
apps/public/content/docs/(tracking)/sdks/nuxt.mdx

[grammar] ~22-~22: Use a hyphen to join words.
Context: ...s on the client! Read more about server side tracking in the [Server Side Tracki...

(QB_NEW_EN_HYPHEN)


[grammar] ~22-~22: Use a hyphen to join words.
Context: ...bout server side tracking in the Server Side Tracking sec...

(QB_NEW_EN_HYPHEN)


[grammar] ~193-~193: Use a hyphen to join words.
Context: ...); op.clear(); </script> ``` ## Server side If you want to track server-side e...

(QB_NEW_EN_HYPHEN)


[grammar] ~256-~256: Ensure spelling is correct
Context: ... through your server This helps bypass adblockers that might block requests to `api.openp...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (4)
packages/sdks/nuxt/build.config.ts (1)

1-5: Minimal unbuild config looks fine

Config is straightforward and appropriate for this package; disabling failOnWarn is OK as long as you’re comfortable not failing CI on build warnings.

packages/sdks/nuxt/index.ts (1)

1-2: Index re-export looks good

Re‑exporting the module and ModuleOptions from ./src/module is a clean dev entry pattern and aligns with the build pipeline described in the comments.

packages/sdks/nuxt/src/module.ts (1)

12-55: Nuxt module wiring and proxy behavior look coherent

The module metadata, defaults (including proxy), runtimeConfig exposure, client plugin registration, conditional server handler, and useOpenPanel auto-import are all consistent and align well with the documented behavior; I don’t see functional issues here.

packages/sdks/nuxt/src/types.d.ts (1)

1-20: Type surface and app/component augmentation are well-structured

ModuleOptions cleanly extends the web SDK options with proxy, and the Nuxt/Vue augmentations for $openpanel match how the client plugin is intended to be consumed; the empty export is a good touch to keep typings scoped.

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.

2 participants