{"_id":"@econneq/apollo-next-multitenancy","_rev":"5-8faf9edd71d7cff930631d507d01f9d8","name":"@econneq/apollo-next-multitenancy","dist-tags":{"latest":"1.0.5"},"versions":{"1.0.1":{"name":"@econneq/apollo-next-multitenancy","version":"1.0.1","keywords":["apollo","nextjs","graphql","multitenant","bff","app-router","server-components","typescript"],"license":"MIT","_id":"@econneq/apollo-next-multitenancy@1.0.1","maintainers":[{"name":"e-conneq","email":"wemoov13@gmail.com"}],"homepage":"https://github.com/your-org/apollo-next-multitenancy#readme","bugs":{"url":"https://github.com/your-org/apollo-next-multitenancy/issues"},"dist":{"shasum":"638783f880fd57e479f4acd75486856a7208f4ab","tarball":"https://registry.npmjs.org/@econneq/apollo-next-multitenancy/-/apollo-next-multitenancy-1.0.1.tgz","fileCount":26,"integrity":"sha512-dmA+jlcOUJEyRjiEJ2KFr0N4QtBaNiqkm+dhKj0B8GBnxyJJ1HXnoMm1fU4+6qwo8nT9t/yutEHh/K/ojMb7Mw==","signatures":[{"sig":"MEYCIQDlp0ed6v3/hmj/OgY2rXV1dlmmai4D2c/qbklDGiEWIwIhAMtPJtSFAYj1OXPIjDQtYneGBVJqchPB46OTH43HBjXd","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":142177},"main":"./dist/index.js","_from":"file:econneq-apollo-next-multitenancy-1.0.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./bff":{"types":"./dist/bff/index.d.ts","import":"./dist/bff/index.mjs","require":"./dist/bff/index.js"},"./client":{"types":"./dist/client/index.d.ts","import":"./dist/client/index.mjs","require":"./dist/client/index.js"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.mjs","require":"./dist/server/index.js"}},"scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts,.tsx","build":"tsup","type-check":"tsc --noEmit"},"_npmUser":{"name":"e-conneq","email":"wemoov13@gmail.com"},"_resolved":"C:\\Users\\e-con\\AppData\\Local\\Temp\\44f31973712b9409ef85d77d502c62d2\\econneq-apollo-next-multitenancy-1.0.1.tgz","_integrity":"sha512-dmA+jlcOUJEyRjiEJ2KFr0N4QtBaNiqkm+dhKj0B8GBnxyJJ1HXnoMm1fU4+6qwo8nT9t/yutEHh/K/ojMb7Mw==","repository":{"url":"git+https://github.com/your-org/apollo-next-multitenancy.git","type":"git"},"_npmVersion":"11.8.0","description":"Industrial-grade Apollo abstraction for Next.js App Router with multi-tenancy support. Auto-detects server/client context, injects x-tenant-id, and routes through BFF or direct backend.","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/react":"^18.0.0"},"peerDependencies":{"next":">=14.0.0","react":">=18.0.0","graphql":">=16.0.0","@apollo/client":">=3.8.0","@apollo/experimental-nextjs-app-support":">=0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/apollo-next-multitenancy_1.0.1_1776474517585_0.5916106042213145","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@econneq/apollo-next-multitenancy","version":"1.0.2","keywords":["apollo","nextjs","graphql","multitenant","bff","app-router","server-components","typescript"],"license":"MIT","_id":"@econneq/apollo-next-multitenancy@1.0.2","maintainers":[{"name":"e-conneq","email":"wemoov13@gmail.com"}],"homepage":"https://github.com/your-org/apollo-next-multitenancy#readme","bugs":{"url":"https://github.com/your-org/apollo-next-multitenancy/issues"},"dist":{"shasum":"905d9b19fe41894eaac16603a8fec124f8e40103","tarball":"https://registry.npmjs.org/@econneq/apollo-next-multitenancy/-/apollo-next-multitenancy-1.0.2.tgz","fileCount":26,"integrity":"sha512-N0hjhTrccVuJ/OwO+qtylzK7kGkXaSuKN9D/PDNWL9KMgqmabCMIneX52+m/sOoetzUj9wvIremkFlJkr3TZdw==","signatures":[{"sig":"MEYCIQDyjoRikQ+rigemzHlcGOOgBHaXW2esv3H++yJvmOCSDgIhAPUje3ap86yM0fYC/Z3Ysc11MeKn6z7vEdds0z1CnRos","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":144929},"main":"./dist/index.js","_from":"file:econneq-apollo-next-multitenancy-1.0.2.tgz","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./bff":{"types":"./dist/bff/index.d.ts","import":"./dist/bff/index.mjs","require":"./dist/bff/index.js"},"./client":{"types":"./dist/client/index.d.ts","import":"./dist/client/index.mjs","require":"./dist/client/index.js"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.mjs","require":"./dist/server/index.js"}},"scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts,.tsx","build":"tsup","type-check":"tsc --noEmit"},"_npmUser":{"name":"e-conneq","email":"wemoov13@gmail.com"},"_resolved":"C:\\Users\\e-con\\AppData\\Local\\Temp\\9e76ae3699dae38ad44ce0be6fc37140\\econneq-apollo-next-multitenancy-1.0.2.tgz","_integrity":"sha512-N0hjhTrccVuJ/OwO+qtylzK7kGkXaSuKN9D/PDNWL9KMgqmabCMIneX52+m/sOoetzUj9wvIremkFlJkr3TZdw==","repository":{"url":"git+https://github.com/your-org/apollo-next-multitenancy.git","type":"git"},"_npmVersion":"11.8.0","description":"Industrial-grade Apollo abstraction for Next.js App Router with multi-tenancy support. Auto-detects server/client context, injects x-tenant-id, and routes through BFF or direct backend.","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/react":"^18.0.0"},"peerDependencies":{"next":">=14.0.0","react":">=18.0.0","graphql":">=16.0.0","@apollo/client":">=3.8.0","@apollo/experimental-nextjs-app-support":">=0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/apollo-next-multitenancy_1.0.2_1776476040243_0.8063621710472946","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@econneq/apollo-next-multitenancy","version":"1.0.3","keywords":["apollo","nextjs","graphql","multitenant","bff","app-router","server-components","typescript"],"license":"MIT","_id":"@econneq/apollo-next-multitenancy@1.0.3","maintainers":[{"name":"e-conneq","email":"wemoov13@gmail.com"}],"homepage":"https://github.com/your-org/apollo-next-multitenancy#readme","bugs":{"url":"https://github.com/your-org/apollo-next-multitenancy/issues"},"dist":{"shasum":"84073fd7abe4fca64c1ae0186fbd86d6ac97b057","tarball":"https://registry.npmjs.org/@econneq/apollo-next-multitenancy/-/apollo-next-multitenancy-1.0.3.tgz","fileCount":26,"integrity":"sha512-tYsNGzEAW/ZjsIAyA8/5ioIopv0P28/eElrWGF4ll0NBX1cYrLhSRwsGU/NBMarnGKr+XsVYSD91FkN3R7joAA==","signatures":[{"sig":"MEUCIFdjoBk5OLt1n1WyGJF7bafsfiJ3ZfOANLf+gBlRTn3BAiEAtA80T7CLFoXs96ji28pszHJ5qFv3e9eYeNG1t+uf2JM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":146835},"main":"./dist/index.js","_from":"file:econneq-apollo-next-multitenancy-1.0.3.tgz","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./bff":{"types":"./dist/bff/index.d.ts","import":"./dist/bff/index.mjs","require":"./dist/bff/index.js"},"./client":{"types":"./dist/client/index.d.ts","import":"./dist/client/index.mjs","require":"./dist/client/index.js"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.mjs","require":"./dist/server/index.js"}},"scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts,.tsx","build":"tsup","type-check":"tsc --noEmit"},"_npmUser":{"name":"e-conneq","email":"wemoov13@gmail.com"},"_resolved":"C:\\Users\\e-con\\AppData\\Local\\Temp\\ebb113fd51881dafa7dc0016ad447ccc\\econneq-apollo-next-multitenancy-1.0.3.tgz","_integrity":"sha512-tYsNGzEAW/ZjsIAyA8/5ioIopv0P28/eElrWGF4ll0NBX1cYrLhSRwsGU/NBMarnGKr+XsVYSD91FkN3R7joAA==","repository":{"url":"git+https://github.com/your-org/apollo-next-multitenancy.git","type":"git"},"_npmVersion":"11.8.0","description":"Industrial-grade Apollo abstraction for Next.js App Router with multi-tenancy support. Auto-detects server/client context, injects x-tenant-id, and routes through BFF or direct backend.","directories":{},"_nodeVersion":"24.13.0","dependencies":{"js-cookie":"^3.0.5"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/react":"^18.0.0","@types/js-cookie":"^3.0.6"},"peerDependencies":{"next":">=14.0.0","react":">=18.0.0","graphql":">=16.0.0","@apollo/client":">=3.8.0","@apollo/experimental-nextjs-app-support":">=0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/apollo-next-multitenancy_1.0.3_1776576611554_0.05400511408067987","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@econneq/apollo-next-multitenancy","version":"1.0.4","keywords":["apollo","nextjs","graphql","multitenant","bff","app-router","server-components","typescript"],"license":"MIT","_id":"@econneq/apollo-next-multitenancy@1.0.4","maintainers":[{"name":"e-conneq","email":"wemoov13@gmail.com"}],"homepage":"https://github.com/your-org/apollo-next-multitenancy#readme","bugs":{"url":"https://github.com/your-org/apollo-next-multitenancy/issues"},"dist":{"shasum":"1386ee47d5b59f76f3d3f45373f06072b410283b","tarball":"https://registry.npmjs.org/@econneq/apollo-next-multitenancy/-/apollo-next-multitenancy-1.0.4.tgz","fileCount":26,"integrity":"sha512-MnY8ypAoWaIkqzomM5eycj50p6BWDr3GZG21mDRTfeUI1R3y9lwWRYK4vBCOgTNJISuluwMHMKPLGIJRWyKePw==","signatures":[{"sig":"MEYCIQCZSKjK+TdAOMAOaqZQKcq+s7Kn9bOrlGYmmw4yeSk6ngIhAOiwgiOqLNSumdPixkpQimDx5TsZSH6hdB3aoXmQ56g6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":176297},"main":"./dist/index.js","_from":"file:econneq-apollo-next-multitenancy-1.0.4.tgz","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./bff":{"types":"./dist/bff/index.d.ts","import":"./dist/bff/index.mjs","require":"./dist/bff/index.js"},"./client":{"types":"./dist/client/index.d.ts","import":"./dist/client/index.mjs","require":"./dist/client/index.js"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.mjs","require":"./dist/server/index.js"}},"scripts":{"dev":"tsup --watch","lint":"eslint src --ext .ts,.tsx","build":"tsup","type-check":"tsc --noEmit"},"_npmUser":{"name":"e-conneq","email":"wemoov13@gmail.com"},"_resolved":"C:\\Users\\e-con\\AppData\\Local\\Temp\\aea57c82fef636840229ed511ced38f3\\econneq-apollo-next-multitenancy-1.0.4.tgz","_integrity":"sha512-MnY8ypAoWaIkqzomM5eycj50p6BWDr3GZG21mDRTfeUI1R3y9lwWRYK4vBCOgTNJISuluwMHMKPLGIJRWyKePw==","repository":{"url":"git+https://github.com/your-org/apollo-next-multitenancy.git","type":"git"},"_npmVersion":"11.8.0","description":"Industrial-grade Apollo abstraction for Next.js App Router with multi-tenancy support. Auto-detects server/client context, injects x-tenant-id, and routes through BFF or direct backend.","directories":{},"_nodeVersion":"24.13.0","dependencies":{"js-cookie":"^3.0.5"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/react":"^18.0.0","@types/js-cookie":"^3.0.6"},"peerDependencies":{"next":">=14.0.0","react":">=18.0.0","graphql":">=16.0.0","@apollo/client":">=3.8.0","@apollo/experimental-nextjs-app-support":">=0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/apollo-next-multitenancy_1.0.4_1776839744476_0.9271050050644367","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@econneq/apollo-next-multitenancy","version":"1.0.5","description":"Industrial-grade Apollo abstraction for Next.js App Router with multi-tenancy support. Auto-detects server/client context, injects x-tenant-id, and routes through BFF or direct backend.","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.mjs","require":"./dist/server/index.js"},"./client":{"types":"./dist/client/index.d.ts","import":"./dist/client/index.mjs","require":"./dist/client/index.js"},"./bff":{"types":"./dist/bff/index.d.ts","import":"./dist/bff/index.mjs","require":"./dist/bff/index.js"}},"keywords":["apollo","nextjs","graphql","multitenant","bff","app-router","server-components","typescript"],"peerDependencies":{"@apollo/client":">=3.8.0","@apollo/experimental-nextjs-app-support":">=0.5.0","graphql":">=16.0.0","next":">=14.0.0","react":">=18.0.0"},"devDependencies":{"@types/js-cookie":"^3.0.6","@types/node":"^20.0.0","@types/react":"^18.0.0","tsup":"^8.0.0","typescript":"^5.0.0"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/your-org/apollo-next-multitenancy.git"},"dependencies":{"js-cookie":"^3.0.5"},"scripts":{"build":"tsup","dev":"tsup --watch","lint":"eslint src --ext .ts,.tsx","type-check":"tsc --noEmit"},"_id":"@econneq/apollo-next-multitenancy@1.0.5","bugs":{"url":"https://github.com/your-org/apollo-next-multitenancy/issues"},"homepage":"https://github.com/your-org/apollo-next-multitenancy#readme","_integrity":"sha512-7xbAsjc7C77QiefVbC8y6bsnapFix3cB6cMh6Y9NkeikG/n1nX7DTKmcVW1CmZfHIDs+6NGK/j+rT1xSuRIm7w==","_resolved":"C:\\Users\\e-con\\AppData\\Local\\Temp\\76f37ba8de9bfc33714b985dc3b86f2b\\econneq-apollo-next-multitenancy-1.0.5.tgz","_from":"file:econneq-apollo-next-multitenancy-1.0.5.tgz","_nodeVersion":"24.13.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-7xbAsjc7C77QiefVbC8y6bsnapFix3cB6cMh6Y9NkeikG/n1nX7DTKmcVW1CmZfHIDs+6NGK/j+rT1xSuRIm7w==","shasum":"d63aaf1b9730caa2d63b27e0d7c05b65807706ab","tarball":"https://registry.npmjs.org/@econneq/apollo-next-multitenancy/-/apollo-next-multitenancy-1.0.5.tgz","fileCount":26,"unpackedSize":177111,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDLlE8MNosR/re+Ijkr91RgYceX9UQpRK7GSh8JCbXDsgIgGKXMYyRZYxnDo9NKG5DO77lk3fPTHZy7GdANG70NZwk="}]},"_npmUser":{"name":"e-conneq","email":"wemoov13@gmail.com"},"directories":{},"maintainers":[{"name":"e-conneq","email":"wemoov13@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/apollo-next-multitenancy_1.0.5_1776874511381_0.7101073428606717"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-18T01:08:37.472Z","modified":"2026-04-22T16:15:11.649Z","1.0.1":"2026-04-18T01:08:37.747Z","1.0.2":"2026-04-18T01:34:00.419Z","1.0.3":"2026-04-19T05:30:11.737Z","1.0.4":"2026-04-22T06:35:44.602Z","1.0.5":"2026-04-22T16:15:11.519Z"},"bugs":{"url":"https://github.com/your-org/apollo-next-multitenancy/issues"},"license":"MIT","homepage":"https://github.com/your-org/apollo-next-multitenancy#readme","keywords":["apollo","nextjs","graphql","multitenant","bff","app-router","server-components","typescript"],"repository":{"type":"git","url":"git+https://github.com/your-org/apollo-next-multitenancy.git"},"description":"Industrial-grade Apollo abstraction for Next.js App Router with multi-tenancy support. Auto-detects server/client context, injects x-tenant-id, and routes through BFF or direct backend.","maintainers":[{"name":"e-conneq","email":"wemoov13@gmail.com"}],"readme":"# @econneq/apollo-next-multitenancy\n\n> Industrial-grade Apollo abstraction for Next.js App Router with first-class multi-tenancy.\n\n## What it solves\n\n| Pain Point | How this package fixes it |\n|---|---|\n| Server vs Client Apollo setup | One factory per context — no boilerplate |\n| Forgetting `x-tenant-id` | Injected automatically on **every** request |\n| BFF wiring | `createBffHandler` is a one-liner proxy |\n| Middleware tenant extraction | `createTenantMiddleware` with 4 strategies |\n| Single vs multi-tenant | Config flag — same codebase for both |\n\n---\n\n## Architecture\n\n```\nBrowser (Client Component)\n    │  useQuery / useMutation  ← x-tenant-id auto-injected\n    ▼\n/api/graphql  (BFF)\n    │  createBffHandler        ← validates auth, enriches headers\n    ▼\nhttp://backend:8000/graphql   ← x-tenant-id forwarded\n\nServer Component / Server Action\n    │  query() / mutation()    ← x-tenant-id from next/headers\n    ▼\nhttp://backend:8000/graphql   ← direct call, no BFF hop\n```\n\n---\n\n## Installation\n\n```bash\nnpm install @econneq/apollo-next-multitenancy \\\n  @apollo/client \\\n  @apollo/experimental-nextjs-app-support \\\n  graphql\n```\nor\n\n```bash\npnpm add @econneq/apollo-next-multitenancy@latest @apollo/client @apollo/experimental-nextjs-app-support graphql next-auth --filter school-front-core\n```\n\n---\n\n## Quick Start (5 files)\n\n### 1. Middleware — extract tenant on every request\n\n**Option A — Simple (no existing middleware):**\n\nUse `createTenantMiddleware` when your app doesn't already have a custom middleware:\n\n```ts\n// middleware.ts\nimport { createTenantMiddleware } from \"@econneq/apollo-next-multitenancy/middleware\";\n\nexport const middleware = createTenantMiddleware({\n  strategy: \"subdomain\",  // acme.app.com → \"acme\"\n  fallback: \"default\",    // for localhost\n});\n\nexport const config = {\n  matcher: [\"/((?!_next/static|_next/image|favicon.ico).*)\"],\n};\n```\n\n**Option B — Custom middleware (already have i18n / URL rewriting):**\n\nIf you already have a middleware that handles subdomain extraction, locale detection,\nor URL rewriting — **skip `createTenantMiddleware` entirely**. Just stamp `x-tenant-id`\ndirectly inside your existing middleware:\n\n```ts\n// middleware.ts — inside your existing proxy/router middleware\nconst domain = extractSubdomain(request.headers.get('host') || '')\nconst response = NextResponse.rewrite(rewrittenUrl)\n\n// ── Add these lines — that's all the package needs ──\nconst tenantId = domain !== 'public'\n  ? domain\n  : process.env.TENANT_ID ?? null\n\nif (tenantId) {\n  // Read by BFF (createBffHandler)\n  response.headers.set('x-tenant-id', tenantId)\n  // Read by Server Components via next/headers()\n  response.headers.set('x-middleware-request-x-tenant-id', tenantId)\n}\n// ────────────────────────────────────────────────────\n```\n\n> **See `examples/with-custom-middleware/middleware.ts`** for a complete real-world\n> example with subdomain extraction, locale detection, and URL rewriting combined.\n\n---\n\n### 2. Server client — one-time setup\n\n```ts\n// lib/apollo-server.ts\nimport { createServerApolloClient } from \"@econneq/apollo-next-multitenancy/server\";\n\nexport const { query, mutation } = createServerApolloClient({\n  serverUrl: process.env.INTERNAL_GRAPHQL_URL,\n  // Option B (custom middleware): no tenant config needed —\n  // x-tenant-id is already in next/headers() from your middleware.\n  //\n  // Option A (createTenantMiddleware): add a resolver:\n  // tenant: { resolveTenantId: subdomainTenantResolver },\n});\n```\n\n### 3. BFF route\n\n```ts\n// app/api/graphql/route.ts\nimport { createBffHandler } from \"@econneq/apollo-next-multitenancy/bff\";\n\nconst { GET, POST } = createBffHandler({\n  upstreamUrl: process.env.INTERNAL_GRAPHQL_URL!,\n  // x-tenant-id is forwarded automatically from incoming request headers\n});\n\nexport { GET, POST };\n```\n\n### 4. Root layout — wrap with provider\n\nFor apps using a `[domain]` URL segment (from a custom middleware rewrite):\n\n```tsx\n// app/[locale]/[domain]/layout.tsx\nimport { headers } from \"next/headers\";\nimport { ApolloMultitenantProvider } from \"@econneq/apollo-next-multitenancy/client\";\n\nexport default async function DomainLayout({ children, params }) {\n  const { domain } = await params;\n  const headerStore = await headers();\n\n  // Prefer middleware header (authoritative), fall back to URL segment\n  const tenantId = headerStore.get(\"x-tenant-id\") ?? domain;\n\n  return (\n    <ApolloMultitenantProvider tenantId={tenantId} clientUrl=\"/api/graphql\">\n      {children}\n    </ApolloMultitenantProvider>\n  );\n}\n```\n\nFor apps using a flat layout (with `createTenantMiddleware`):\n\n```tsx\n// app/layout.tsx\nimport { headers } from \"next/headers\";\nimport { ApolloMultitenantProvider } from \"@econneq/apollo-next-multitenancy/client\";\n\nexport default async function RootLayout({ children }) {\n  const tenantId = (await headers()).get(\"x-tenant-id\");\n\n  return (\n    <html>\n      <body>\n        <ApolloMultitenantProvider tenantId={tenantId} clientUrl=\"/api/graphql\">\n          {children}\n        </ApolloMultitenantProvider>\n      </body>\n    </html>\n  );\n}\n```\n\n### 5. Use in Server and Client Components\n\n```tsx\n// app/dashboard/page.tsx (Server Component — direct backend call)\nimport { query } from \"@/lib/apollo-server\";\nimport { gql } from \"@apollo/client\";\n\nconst GET_DASHBOARD = gql`query GetDashboard { dashboard { tenantName plan } }`;\n\nexport default async function Page() {\n  const { data } = await query(GET_DASHBOARD);\n  return <h1>{data.dashboard.tenantName}</h1>;\n}\n```\n\n```tsx\n// components/UserList.tsx (Client Component — routes through BFF)\n\"use client\";\nimport { useQuery } from \"@econneq/apollo-next-multitenancy/client\";\nimport { gql } from \"@apollo/client\";\n\nconst GET_USERS = gql`query GetUsers { users { id name } }`;\n\nexport function UserList() {\n  const { data, loading } = useQuery(GET_USERS); // x-tenant-id injected automatically\n  if (loading) return <p>Loading...</p>;\n  return <ul>{data?.users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;\n}\n```\n\n---\n\n## Tenant Strategies\n\n| Strategy | Use case | Example |\n|---|---|---|\n| `subdomain` | `tenant.app.com` | SaaS with per-tenant subdomains |\n| `path` | `/tenant/page` | Path-based multi-tenancy |\n| `header` | Forward existing header | Behind API gateway |\n| `custom` | Any logic | Session, JWT, DB lookup |\n\n> **Already have a custom middleware?** You don't need any of these strategies.\n> Just set `x-tenant-id` and `x-middleware-request-x-tenant-id` headers directly\n> as shown in Option B above.\n\n### Single-tenant setup\n\n```ts\ncreateServerApolloClient({ tenant: { tenantId: \"my-company\" } });\ncreateBffHandler({ tenant: { tenantId: \"my-company\" }, upstreamUrl: \"...\" });\n<ApolloMultitenantProvider tenantId=\"my-company\" />;\n\n// Or via env var:\nTENANT_ID=my-company\n```\n\n---\n\n## BFF: Auth-gated proxy\n\n```ts\n// app/api/graphql/route.ts\nimport { getServerSession } from \"next-auth\";\nimport { createBffHandler } from \"@econneq/apollo-next-multitenancy/bff\";\n\nconst { POST, GET } = createBffHandler({\n  upstreamUrl: process.env.INTERNAL_GRAPHQL_URL!,\n\n  async onRequest(req) {\n    const session = await getServerSession();\n    if (!session) return Response.json({ error: \"Unauthorized\" }, { status: 401 });\n  },\n\n  async enrichHeaders(req, headers) {\n    const session = await getServerSession();\n    return { ...headers, \"x-user-id\": session?.user?.id ?? \"\" };\n  },\n});\n```\n\n---\n\n## Examples\n\nThe `examples/` folder contains copy-paste ready setups:\n\n| Folder | When to use |\n|---|---|\n| `examples/with-simple-middleware/` | New app, no existing middleware |\n| `examples/with-custom-middleware/` | Already have a proxy / i18n / rewrite middleware |\n\nThe `with-custom-middleware` example is based on a real production multi-tenant platform\nwith subdomain routing + locale detection. Copy the whole folder as a starting point.\n\n---\n\n## API Reference\n\n### `/server`\n\n| Export | Description |\n|---|---|\n| `createServerApolloClient(options)` | Returns `{ getClient, query, mutation }` |\n\n### `/client`\n\n| Export | Description |\n|---|---|\n| `ApolloMultitenantProvider` | Root layout wrapper |\n| `useQuery(doc, options?)` | Drop-in Apollo `useQuery` with tenant header |\n| `useMutation(doc, options?)` | Drop-in Apollo `useMutation` with tenant header |\n| `useTenantContext()` | Access `{ tenantId, headerName }` |\n\n### `/bff`\n\n| Export | Description |\n|---|---|\n| `createBffHandler(options)` | Returns `{ GET, POST }` for Next.js route handlers |\n\n### Main entry\n\n| Export | Description |\n|---|---|\n| `subdomainTenantResolver` | Built-in subdomain extractor |\n| `envTenantResolver` | Built-in env var resolver |\n| `resolveTenantId` | Core resolution logic |\n| All types | `TenantConfig`, `ApolloMultitenantOptions`, etc. |\n\n---\n\n## Environment Variables\n\n| Variable | Used by | Description |\n|---|---|---|\n| `INTERNAL_GRAPHQL_URL` | Server, BFF | Your backend GraphQL URL |\n| `NEXT_PUBLIC_GRAPHQL_URL` | Server (fallback) | Public GraphQL URL |\n| `TENANT_ID` | All | Fixed tenant ID (single-tenant) |\n| `NEXT_PUBLIC_TENANT_ID` | Client (fallback) | Fixed tenant ID (browser-visible) |\n| `NEXT_PUBLIC_ROOT_DOMAIN` | Custom middleware | Root domain for subdomain extraction |\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}