@getfluxly/next
v0.1.1
Published
GetFluxly Next.js SDK — drop-in <GFluxScript>, server-side track/identify/alias for Server Actions and Route Handlers, request-aware middleware, and type-safe env reading.
Downloads
237
Maintainers
Readme
@getfluxly/next
GetFluxly's Next.js SDK. Drop-in client for App Router and Pages Router. Provides:
- A
<GFluxScript>component that loads the browser SDK throughnext/scriptwith the right strategy and nonce passthrough. - All five React hooks via re-export from
@getfluxly/react. - Server-side
track / identify / aliasfor Server Actions and Route Handlers. - A middleware wrapper (
withGFluxMiddleware) that forwards client IP into downstream handlers. - Type-safe env reading (
gfluxEnv).
Install
npm i @getfluxly/next @getfluxly/react @getfluxly/browser @getfluxly/nodereact and next are peer dependencies — already in your project. The four @getfluxly/* packages are peers too; install them all so npm dedupes the runtime.
60-second quickstart
1. Set env vars
# .env.local
NEXT_PUBLIC_GFLUX_API_KEY=gflux_pub_...
GFLUX_SERVER_TOKEN=gflux_secret_...2. Mount the script in app/layout.tsx
import { GFluxScript } from "@getfluxly/next/client";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<GFluxScript apiKey={process.env.NEXT_PUBLIC_GFLUX_API_KEY!} />
{children}
</body>
</html>
);
}That's it for client-side autocapture (pageviews, clicks, forms, errors). Open the GetFluxly dashboard live feed and you'll see events arrive within a second.
3. (Optional) Track from a Server Action
"use server";
import { track } from "@getfluxly/next/server";
export async function signUpAction(formData: FormData) {
const user = await createUser(formData);
await track("user_signed_up", {
externalId: user.id,
properties: { plan: user.plan },
});
return { ok: true };
}The server helper flushes immediately — appropriate for short-lived serverless invocations. For long-running servers, call getServerClient() and manage the lifecycle yourself.
API
Client (@getfluxly/next/client)
Re-exports from @getfluxly/react: GFluxProvider, useGFlux, useTrack, useIdentify, usePage, useConsent. Plus:
<GFluxScript apiKey nonce? strategy?>
Renders a <script> tag (via next/script) that loads @getfluxly/browser's IIFE bundle from jsDelivr, pinned to whatever browser SDK version this package's peer dependency points at.
| Prop | Type | Description |
|---|---|---|
| apiKey | string | Publishable key (gflux_pub_*). Renders nothing when missing — mainly useful in development. |
| apiHost | string | API base URL. Defaults to https://api.getfluxly.com. |
| nonce | string | CSP nonce, passed through to <script>. |
| strategy | "afterInteractive" \| "lazyOnload" | next/script strategy. Defaults to "afterInteractive". |
Use either <GFluxScript> for the script-tag pattern (autocapture, no React state needed) or <GFluxProvider> for the React-hooks pattern. Don't mount both — they each construct their own client and you'd send every event twice.
Server (@getfluxly/next/server)
This subpath is gated to Node-only via the package's exports map. Importing it from a client component will fail Next's build with a server-only error.
getServerClient(opts?): GFluxNodeClient
Returns the singleton @getfluxly/node client for this process. Cached on globalThis.__gflux_node__ so Next's hot-reload doesn't leak background flush timers.
import { getServerClient } from "@getfluxly/next/server";
const client = getServerClient();
await client.track("invoice_paid", { externalId: "user_42", properties: {...} });
await client.flush();track / identify / alias
Convenience helpers on top of the singleton. They flush immediately, which is the right default for serverless functions. Customer code that wants batching should use getServerClient() directly.
import { track, identify, alias } from "@getfluxly/next/server";
await track("event_name", { externalId, properties });
await identify({ externalId, anonymousId, traits });
await alias({ userId, previousId });Middleware (@getfluxly/next/middleware)
withGFluxMiddleware(handler, { forwardIp?, forwardGeo? })
Wraps a Next middleware. Mutates the incoming request headers BEFORE calling the underlying handler so downstream Server Components or Route Handlers can read them.
import { withGFluxMiddleware } from "@getfluxly/next/middleware";
import { NextResponse } from "next/server";
export default withGFluxMiddleware(
async (request) => {
return NextResponse.next();
},
{ forwardIp: true, forwardGeo: true },
);
export const config = { matcher: "/((?!_next/static|_next/image|favicon.ico).*)" };Headers added (when enabled):
| Header | Source | Notes |
|---|---|---|
| x-gflux-ip | request.ip or x-real-ip | Off by default (changes data semantics). |
| x-gflux-country | request.geo.country | Off by default. |
| x-gflux-region | request.geo.region | Off by default. |
Nothing is forwarded by default. Opt in only if you intend to enrich server-side events with the client's network identity.
gfluxEnv(options?)
Type-safe reader for the three Next env vars.
import { gfluxEnv } from "@getfluxly/next";
const env = gfluxEnv({ requireServerToken: true });
// env.publicKey, env.serverToken, env.apiHost| Option | Behavior |
|---|---|
| requirePublicKey | Throw if NEXT_PUBLIC_GFLUX_API_KEY is missing. |
| requireServerToken | Throw if GFLUX_SERVER_TOKEN is missing. |
The error message names the missing variable explicitly.
Privacy and consent
Inherited from @getfluxly/browser: GPC respected by default, EU consent banner shown when consentMode resolves to "explicit", no PII in default context. See the browser SDK README for the full posture.
Server-side calls assume the customer has already obtained consent before invoking track / identify / alias. The server SDK does not check.
Errors
The browser SDK is fire-and-forget — track/identify/page from React hooks never throw to caller code. The server SDK wraps every error in GFluxNodeError per the error taxonomy standard.
Identity model
Two sentences: GetFluxly stitches three IDs (anonymous, external, previous). Browser hooks set the anonymous ID automatically; you set the external ID via useIdentify() after sign-in, and the server-side alias() merges previous anonymous IDs into the canonical user ID.
Full reference: identity stitching standard.
Links
- Dashboard: https://app.getfluxly.com
- Docs: https://docs.getfluxly.com/sdks/next
- Issues: https://github.com/dineshmiriyala/getfluxly/issues
- Security: see
SECURITY.md
