· বাংলাদেশ সময়
Next.js ইন্টিগ্রেশন
Next.js শপ EcomSolveBD-তে কানেক্ট করুন
- ১
অ্যাকাউন্ট খুলুন
আপনি- ecomsolvebd.com এ রেজিস্টার / লগইন
- ড্যাশবোর্ডে ঢুকুন
- ২
Custom / Headless → Next.js
আপনি- Integrations → Custom / Headless → Next.js
- শপ URL দিন — https://myshop.com
- চাইলে GA4 ID (G-…)
- Connect Next.js চাপুন
Tracking Merchant ID + Webhook Secret কপি করুন — Secret এখনই সেভ করুন।
- ৩
ডেভেলপারকে পাঠান
আপনি- Tracking Merchant ID
- Webhook Secret
- লাইভ শপ URL
- ৪
ডেভেলপার: SDK কন্ট্রাক্ট
ডেভেলপার- npm install @ecomsolvebd/next
- Path contract: collect + attribution-config + order-status
- Root layout: EsbTracker (funnelAuto={false} recommended)
- Host maps checkout → postOrder + esbTrack call sites
- নিচের SDK reference — ডেমো শপ কপি নয়
প্রতি স্টোরের cart/ORM আলাদা — শুধু কন্ট্রাক্ট ইমপ্লিমেন্ট করুন।
↓ SDK রেফারেন্স - ৫
টেস্ট করুন
দুজনে- শপ হোম → Events-এ page_view
- টেস্ট অর্ডার → Dashboard → Orders
- SaaS স্ট্যাটাস বদলান → Next.js চেক
- https://yoursite.com/feed/products.xml
SDK রেফারেন্স
@ecomsolvebd/next — App Router
ইন্টিগ্রেশন SDK — path কন্ট্রাক্ট + factories। স্টোর বিল্ড (কার্ট, ORM, CMS, UI) হোস্টের। ডেমো শপ কপি করবেন না; কন্ট্রাক্ট ইমপ্লিমেন্ট করুন।
কন্ট্রাক্ট
Path contract (host must expose these; package does not inject files):
POST|GET /api/ecomsolvebd/collect
GET|POST /api/ecomsolvebd/attribution-config
POST /api/ecomsolvebd/order-status
Exports:
@ecomsolvebd/next → buildOrderPayload, OrderWebhookPoster, …
@ecomsolvebd/next/client → EsbTracker (sets window.esbTrack)
@ecomsolvebd/next/route-handlers → create*RouteHandlers factories
Out of scope for this SDK: your catalog UI, cart store, ORM, CMS, checkout UX.
Prefix paths with src/ when using src/app.
Identity: never fabricate visitor ids. Forward Cookie via buildOrderPayload(..., { cookieHeader }).১) ইনস্টল npm install @ecomsolvebd/next
2) Environment
Merchant Key + Webhook Secret ড্যাশবোর্ড Connect থেকে। Secret শুধু সার্ভার রানটাইমে।
.envECOMSOLVEBD_API_BASE=https://api.ecomsolvebd.com ECOMSOLVEBD_MERCHANT_KEY=<tracking_merchant_id> ECOMSOLVEBD_WEBHOOK_SECRET=<webhook_secret> ECOMSOLVEBD_GA4_MEASUREMENT_ID=G-XXXXXXXX # optional NEXT_PUBLIC_STORE_URL=https://your-store.example # ECOMSOLVEBD_DEPLOY_ENV=staging # when connected via staging dashboard
3) Browser tracker
EsbTracker transport মাউন্ট করে (window.esbTrack)। funnelAuto={false} = হোস্ট ইভেন্ট ওয়্যারিং।
root layout// Root layout — path may be app/layout.tsx or src/app/layout.tsx import { EsbTracker } from "@ecomsolvebd/next/client"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <EsbTracker merchantKey={process.env.ECOMSOLVEBD_MERCHANT_KEY!} // Public store origin (scheme + host). Used to build same-origin collect URL. storeBaseUrl={process.env.NEXT_PUBLIC_STORE_URL!} apiBase={process.env.ECOMSOLVEBD_API_BASE} deployEnv={process.env.ECOMSOLVEBD_DEPLOY_ENV} ga4MeasurementId={process.env.ECOMSOLVEBD_GA4_MEASUREMENT_ID} // Prefer explicit host events (see Events API section) funnelAuto={false} /> {children} </body> </html> ); }4) Collect proxy
First-party Auto ladder: browser → same-origin → API। Thin wrapper only.
app/api/ecomsolvebd/collect/route.ts// app/api/ecomsolvebd/collect/route.ts import { createCollectRouteHandlers } from "@ecomsolvebd/next/route-handlers"; export const { POST, GET } = createCollectRouteHandlers({ merchantKey: process.env.ECOMSOLVEBD_MERCHANT_KEY!, apiBase: process.env.ECOMSOLVEBD_API_BASE, deployEnv: process.env.ECOMSOLVEBD_DEPLOY_ENV, });5) Attribution config proxy
Same-origin attribution config — path ঠিক রাখুন।
app/api/ecomsolvebd/attribution-config/route.ts// app/api/ecomsolvebd/attribution-config/route.ts import { createAttributionConfigRouteHandlers } from "@ecomsolvebd/next/route-handlers"; export const { GET, POST } = createAttributionConfigRouteHandlers({ merchantKey: process.env.ECOMSOLVEBD_MERCHANT_KEY!, apiBase: process.env.ECOMSOLVEBD_API_BASE, deployEnv: process.env.ECOMSOLVEBD_DEPLOY_ENV, });6) Inbound order status
SaaS → store। findOrder / updateOrder আপনার persistence-এ ম্যাপ — ORM বাধ্যতামূলক নয়।
app/api/ecomsolvebd/order-status/route.ts// app/api/ecomsolvebd/order-status/route.ts (or src/app/…) import { createOrderStatusRouteHandlers } from "@ecomsolvebd/next/route-handlers"; // Wire find/update to YOUR persistence (Prisma, Drizzle, SQL, REST CMS, …). // The factory only needs: load by orderNumber → read status → write status. export const { POST } = createOrderStatusRouteHandlers({ webhookSecret: process.env.ECOMSOLVEBD_WEBHOOK_SECRET!, allowedStatuses: ["pending", "confirmed", "delivered", "cancelled", "returned"], findOrder: async (orderNumber) => { // return await db.orders.findByNumber(orderNumber) return null; // replace — null → handler reports not found }, getCurrentStatus: (order) => { // return order.status return (order as { status?: string }).status; }, updateOrder: async (order, update) => { // Prefer business key orderNumber over PK type (Int vs String/cuid). // await db.orders.updateStatus(order.orderNumber, update.status) void order; void update; }, });7) Order ingest
Checkout success call site (যেখানেই অর্ডার কমিট হয়)। Ads Purchase নয়।
call site · server// Call from YOUR checkout success path (Route Handler, Server Action, etc.) // Exact file path depends on your storefront — not prescribed by this SDK. import { cookies } from "next/headers"; import { buildOrderPayload, OrderWebhookPoster } from "@ecomsolvebd/next"; // 1) Persist the order in your own database first, then: const poster = new OrderWebhookPoster({ merchantKey: process.env.ECOMSOLVEBD_MERCHANT_KEY!, webhookSecret: process.env.ECOMSOLVEBD_WEBHOOK_SECRET!, apiBase: process.env.ECOMSOLVEBD_API_BASE, }); const payload = buildOrderPayload( { orderNumber: order.number, // Use your store currency (ISO 4217) — do not hardcode currency: order.currency, customer: { fullName: order.customerName, // name phone: order.phone, // email: order.email, }, items: order.lines.map((l) => ({ sku: l.sku, title: l.title, quantity: l.qty, unitPrice: String(l.unitPrice), // productId: l.productId, // variantTitle: l.variantTitle, })), // Shipping / address (uncomment when your checkout collects them) // district: order.district, // upazila: order.upazila, // address: order.address, // notes: order.notes, // Money (flat fields — not a nested totals object) // shippingTotal: String(order.shippingTotal), // discountTotal: String(order.discountTotal), // taxTotal: String(order.taxTotal), }, { cookieHeader: (await cookies()).toString() }, ); try { await poster.postOrder(payload); } catch (err) { console.error("[ecomsolvebd] postOrder failed", err); } // Ingest only — ads Purchase is sent later from the EcomSolveBD dashboard / courier flow.
নোট
- Client export: EsbTracker (@ecomsolvebd/next/client) — অন্য নাম নেই।
- Route handlers হোস্ট অ্যাপে thin wrappers; লজিক প্যাকেজে।
- Optional: /feed/[channel].xml + ProductFeedProvider — প্যাকেজ README।
- NEXT_PUBLIC_STORE_URL = পাবলিক origin (https://shop.example) — proxy URL বানাতে লাগে।
আরও ফিচার
অর্ডার স্ট্যাটাস
EcomSolveBD ও Next.js অ্যাডমিন স্ট্যাটাস সিঙ্ক করে।
- · SaaS → Next.js: order-status route handler
- · Next.js → SaaS: status webhook (প্যাকেজ)
- · Dashboard Create Order → Next.js: v1.0.1+ (`POST /api/ecomsolvebd/order-create`)
- · ম্যাপ: pending · confirmed · delivered · cancelled · returned
প্রোডাক্ট ফিড
চারটা XML — প্রোডাক্ট Next.js/API-তেই ম্যানেজ।
- /feed/products.xml — EcomSolveBD ক্যাটালগ
- /feed/facebook.xml — Meta
- /feed/tiktok.xml — TikTok (RSS/XML)
- /feed/google.xml — Google Merchant
First-party ট্র্যাকিং
ইভেন্ট আপনার ডোমেইন দিয়ে — অ্যাড ব্লকারে কম হারায়।
- · Auto: same-origin /api/ecomsolvebd/collect → API
- · Dashboard: CNAME → Verify DNS → tracking.{domain}
- · ডেভ: proxy routes; owner: DNS (কোড নয়)
কন্ট্রাক্ট
Transport (provided by EsbTracker in the root layout):
window.esbTrack?.(eventName, props?)
window.esbBindCheckoutForm?.(cssSelector, fieldMap?)
Host responsibility:
Map YOUR domain moments → event names below.
Do not invent visitor ids / fbp / gclid — collect + esb_vid handle identity.
Recommended: <EsbTracker funnelAuto={false} … /> so heuristics do not double-fire.
Call sites are yours (RSC, client page, cart store, Server Action, Route Handler).
This SDK does not prescribe routes, ORM, CMS, or UI libraries.পেজ ভিউ
স্ক্রিন/URL পরিবর্তনে হোস্ট থেকে ফায়ার। রুট স্ট্রাকচার SDK নির্ধারণ করে না।
// Client call site — whenever the visible URL / screen changes in your SPA
// Requires EsbTracker mounted so window.esbTrack exists.
window.esbTrack?.("page_view");
// App Router example (optional helper — adapt to your router):
// "use client";
// import { useEffect } from "react";
// import { usePathname, useSearchParams } from "next/navigation";
// export function TrackPageViews() {
// const pathname = usePathname();
// const search = useSearchParams();
// useEffect(() => { window.esbTrack?.("page_view"); }, [pathname, search]);
// return null;
// }SDK রেফারেন্স
Product feeds — host wiring
পাবলিক XML কন্ট্রাক্ট + ProductFeedProvider। ক্যাটালগ সোর্স হোস্টের — ডেমো শপ কপি নয়। কার্ডে ক্লিক → কপি।
কন্ট্রাক্ট
Public feed URLs (Woo parity — host must expose these GET endpoints):
GET {storeOrigin}/feed/products.xml → EcomSolveBD catalog sync
GET {storeOrigin}/feed/facebook.xml → Meta Commerce Manager
GET {storeOrigin}/feed/tiktok.xml → TikTok Ads catalog (RSS/XML)
GET {storeOrigin}/feed/google.xml → Google Merchant Center
SDK:
@ecomsolvebd/next/route-handlers → createFeedRouteHandlers
Host implements ProductFeedProvider (map YOUR catalog → DTO below).
Out of scope: SaaS does not CRUD remote products. Cost fields (buying_cost, …)
stay in EcomSolveBD DB — feed sync must not wipe them.
Skip rules (same as Woo): missing public http(s) image OR price ≤ 0 → omit item.
Google: identifier_exists=no when GTIN/MPN absent.Feed route
একটা dynamic route — চারটা channel। ORM/ফাইল ট্রি SDK নির্ধারণ করে না।
// Path contract (public): /feed/{products|facebook|tiktok|google}.xml
// Next.js cannot reliably match folders named [channel].xml — use:
// app/feed/[channel]/route.ts
// + next.config rewrite: /feed/:channel.xml → /feed/:channel
import type { NextRequest } from "next/server";
import { feedRouteGET } from "@ecomsolvebd/next/route-handlers";
import { productFeedProvider } from "@/lib/esb-product-feed"; // rename to your module
export async function GET(
_req: NextRequest,
ctx: { params: Promise<{ channel: string }> },
) {
const { channel } = await ctx.params;
return feedRouteGET(channel.replace(/\.xml$/i, ""), {
storeOrigin: process.env.NEXT_PUBLIC_STORE_URL!,
currency: process.env.ECOMSOLVEBD_CURRENCY || "BDT",
storeName: process.env.ECOMSOLVEBD_STORE_NAME || "Store",
provider: productFeedProvider,
});
}
// next.config.ts
// async rewrites() {
// return [{ source: "/feed/:channel.xml", destination: "/feed/:channel" }];
// }সাধারণ প্রশ্ন
- কোডিং জানি না — পারব?
- হ্যাঁ। ধাপ ১–৩ আপনি। ধাপ ৪ ডেভেলপার।
- প্রোডাক্ট EcomSolveBD থেকে এডিট?
- না। প্রোডাক্ট Next.js/API-তেই।
- অর্ডার কীভাবে আসে?
- চেকআউট সফলে সার্ভার webhook — ব্রাউজার purchase নয়। Dashboard Create Order (v1.0.1+) Next.js অ্যাডমিনেও যায়।
- Secret হারিয়ে গেলে?
- Integrations → Next.js আবার Connect, নতুন Secret।
সমস্যা হলে
page_view / ecommerce আসছে না
Collect proxy + EsbTracker। ecommerce: হোস্ট esbTrack call sites (Events API)।
tracker-config CORS লাল
Collect same-origin proxy দিয়ে চলে; tracker-config API Origin reflect করে (SaaS)। Hard-refresh করে আবার দেখুন।
অর্ডার আসছে না
Connect Next.js আগে। Secret মিলিয়ে postOrder() লগ চেক করুন।
স্ট্যাটাস সিঙ্ক নয়
order-status route + HTTPS base URL + order_number মিলছে কিনা।
· বাংলাদেশ সময়