Compare commits

...
3 Commits
Author SHA1 Message Date
Unchained b5f8ddbaaa fix(analytics): add OpenPanel client secret and server-side tracking
Build and Deploy / build (push) Has been cancelled
- Add OPENPANEL_CLIENT_SECRET for server-side tracking
- Add OPENPANEL_API_URL environment variable
- Add server-side OpenPanel tracking for orders
- Track order_received and revenue events on webhook,description:Commit OpenPanel fixes
2026-03-25 19:15:48 +02:00
Unchained 6dbaf99b29 fix(analytics): use direct OpenPanel URL instead of proxy
Use https://op.nodecrew.me/api and https://op.nodecrew.me/op1.js
directly since OpenPanel is self-hosted.
2026-03-25 19:09:10 +02:00
Unchained cdd3f9c77e fix(analytics): add proxy route and correct script URL for OpenPanel
- Add /api/op/[...path] proxy route to forward events to self-hosted OpenPanel
- Add scriptUrl=/api/op/op1.js to OpenPanelComponent
- Proxy prevents ad blockers from blocking tracking requests
2026-03-25 19:07:52 +02:00
3 changed files with 37 additions and 5 deletions
+7 -5
View File
@@ -46,11 +46,13 @@ export default async function LocaleLayout({
return (
<>
<OpenPanelComponent
clientId={process.env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID || ""}
trackScreenViews={true}
trackOutgoingLinks={true}
/>
<OpenPanelComponent
clientId={process.env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID || ""}
trackScreenViews={true}
trackOutgoingLinks={true}
apiUrl="https://op.nodecrew.me/api"
scriptUrl="https://op.nodecrew.me/op1.js"
/>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
+5
View File
@@ -0,0 +1,5 @@
import { createRouteHandler } from "@openpanel/nextjs/server";
export const { GET, POST } = createRouteHandler({
apiUrl: "https://op.nodecrew.me/api",
});
+25
View File
@@ -5,10 +5,18 @@ import { OrderConfirmation } from "@/emails/OrderConfirmation";
import { OrderShipped } from "@/emails/OrderShipped";
import { OrderCancelled } from "@/emails/OrderCancelled";
import { OrderPaid } from "@/emails/OrderPaid";
import { OpenPanel } from "@openpanel/nextjs";
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://dev.manoonoils.com";
const DASHBOARD_URL = process.env.DASHBOARD_URL || "https://dashboard.manoonoils.com";
// Initialize OpenPanel for server-side tracking
const op = new OpenPanel({
clientId: process.env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID || "",
clientSecret: process.env.OPENPANEL_CLIENT_SECRET || "",
apiUrl: process.env.OPENPANEL_API_URL || "https://op.nodecrew.me/api",
});
interface SaleorWebhookHeaders {
"saleor-event": string;
"saleor-domain": string;
@@ -274,6 +282,23 @@ async function handleOrderConfirmed(order: SaleorOrder, eventType: string) {
});
}
// Track order in OpenPanel
op.track("order_received", {
order_id: order.id,
order_number: order.number,
total: order.total.gross.amount,
currency: order.total.gross.currency,
item_count: order.lines.reduce((sum, line) => sum + line.quantity, 0),
customer_email: customerEmail,
event_type: eventType,
});
// Track revenue
op.track("revenue", {
amount: order.total.gross.amount,
currency: order.total.gross.currency,
});
// Always send admin notification for both ORDER_CREATED and ORDER_CONFIRMED
await sendEmailToAdmin({
subject: `🎉 New Order #${order.number} - ${formatPrice(order.total.gross.amount, currency)}`,