-
Notifications
You must be signed in to change notification settings - Fork 273
feat: add nuxt sdk #260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add nuxt sdk #260
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds 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
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
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. Comment |
There was a problem hiding this 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 targetYou’re targeting Nuxt
^3.0.0 || ^4.0.0but using@nuxt/types(Nuxt 2) in bothtypesanddevDependencies. For Nuxt 3+ modules it’s more typical to rely onnuxt/schemaand@nuxt/kittypes rather than@nuxt/types.Consider:
- Dropping
@nuxt/typesif it’s not needed.- Switching
typesto 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 componentsThe Vue docs content looks solid and examples are consistent with the
@openpanel/webAPI. Two small cleanups:
Linkfromnext/link,DeviceIdWarning, andPersonalDataWarningare 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 missinguseEffectimports in examples and clean up unused MDX importsThe React docs read well and mirror the Vue guide, but a couple of polish points:
- Several snippets use
useEffect(MyComponent,App, hook example) without showingimport { useEffect } from 'react';. For copy‑paste friendliness, I’d add that import to at least the first snippet that usesuseEffect.PersonalDataWarningis 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 versionsThe packaging setup (exports, main, scripts, files) looks sane for a Nuxt module.
Given
peerDependencies.nuxtis^3.0.0 || ^4.0.0, keeping@nuxt/types@^2.18.1as a devDependency can be misleading and may pull in Nuxt 2 type assumptions alongside Nuxt 3+.Consider:
- Removing
@nuxt/typesif it’s unused in this package.- Relying on
@nuxt/kitand 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 ergonomicsImplementation is idiomatic for a Nuxt 3 composable and matches the plugin’s
$openpanelinjection.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
$openpanelis 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 guardThe plugin correctly:
- Runs on the client (
plugin.client.ts),- Reads
public.openpanelasModuleOptions,- Instantiates
OpenPanelonce,- Provides it under
openpanel, matching the$openpanelaccess pattern,- Augments NuxtApp and Vue component types.
One optional DX improvement: add a lightweight guard around
configbefore constructingOpenPanelso misconfigurations (e.g. missingclientId) 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 tighteningeventtypingThe routing, header construction,
/trackgating, body forwarding, and response handling all look correct for this proxy. The only rough edge is the untypedevent.You can improve safety and editor support by using the concrete
H3Eventtype:-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 docsThe 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis 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.tsand./packages/db/src/clickhouse/query-functions.ts
Files:
packages/sdks/nuxt/src/types.d.tspackages/sdks/nuxt/src/runtime/plugin.client.tspackages/sdks/nuxt/src/runtime/composables/useOpenPanel.tspackages/sdks/nuxt/src/module.tspackages/sdks/nuxt/src/runtime/server/api/[...openpanel].tspackages/sdks/nuxt/build.config.tspackages/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 fineConfig is straightforward and appropriate for this package; disabling
failOnWarnis 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 goodRe‑exporting the module and
ModuleOptionsfrom./src/moduleis 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 coherentThe module metadata, defaults (including
proxy), runtimeConfig exposure, client plugin registration, conditional server handler, anduseOpenPanelauto-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
ModuleOptionscleanly extends the web SDK options withproxy, and the Nuxt/Vue augmentations for$openpanelmatch how the client plugin is intended to be consumed; the empty export is a good touch to keep typings scoped.
Summary by CodeRabbit
Documentation
New Features
✏️ Tip: You can customize this high-level summary in your review settings.