@burdenoff/website-sdk 0.0.0-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +357 -0
  3. package/dist/analytics/index.d.mts +27 -0
  4. package/dist/analytics/index.d.ts +27 -0
  5. package/dist/analytics/index.js +36 -0
  6. package/dist/analytics/index.js.map +1 -0
  7. package/dist/analytics/index.mjs +34 -0
  8. package/dist/analytics/index.mjs.map +1 -0
  9. package/dist/client/index.d.mts +29 -0
  10. package/dist/client/index.d.ts +29 -0
  11. package/dist/client/index.js +261 -0
  12. package/dist/client/index.js.map +1 -0
  13. package/dist/client/index.mjs +255 -0
  14. package/dist/client/index.mjs.map +1 -0
  15. package/dist/components/contact.d.mts +144 -0
  16. package/dist/components/contact.d.ts +144 -0
  17. package/dist/components/contact.js +806 -0
  18. package/dist/components/contact.js.map +1 -0
  19. package/dist/components/contact.mjs +780 -0
  20. package/dist/components/contact.mjs.map +1 -0
  21. package/dist/components/electron-download.d.mts +32 -0
  22. package/dist/components/electron-download.d.ts +32 -0
  23. package/dist/components/electron-download.js +131 -0
  24. package/dist/components/electron-download.js.map +1 -0
  25. package/dist/components/electron-download.mjs +108 -0
  26. package/dist/components/electron-download.mjs.map +1 -0
  27. package/dist/components/launch-countdown.d.mts +15 -0
  28. package/dist/components/launch-countdown.d.ts +15 -0
  29. package/dist/components/launch-countdown.js +89 -0
  30. package/dist/components/launch-countdown.js.map +1 -0
  31. package/dist/components/launch-countdown.mjs +87 -0
  32. package/dist/components/launch-countdown.mjs.map +1 -0
  33. package/dist/components/newsletter.d.mts +155 -0
  34. package/dist/components/newsletter.d.ts +155 -0
  35. package/dist/components/newsletter.js +880 -0
  36. package/dist/components/newsletter.js.map +1 -0
  37. package/dist/components/newsletter.mjs +854 -0
  38. package/dist/components/newsletter.mjs.map +1 -0
  39. package/dist/components/partners.d.mts +88 -0
  40. package/dist/components/partners.d.ts +88 -0
  41. package/dist/components/partners.js +1169 -0
  42. package/dist/components/partners.js.map +1 -0
  43. package/dist/components/partners.mjs +1143 -0
  44. package/dist/components/partners.mjs.map +1 -0
  45. package/dist/components/pricing.d.mts +194 -0
  46. package/dist/components/pricing.d.ts +194 -0
  47. package/dist/components/pricing.js +813 -0
  48. package/dist/components/pricing.js.map +1 -0
  49. package/dist/components/pricing.mjs +791 -0
  50. package/dist/components/pricing.mjs.map +1 -0
  51. package/dist/components/problems-solved.d.mts +37 -0
  52. package/dist/components/problems-solved.d.ts +37 -0
  53. package/dist/components/problems-solved.js +157 -0
  54. package/dist/components/problems-solved.js.map +1 -0
  55. package/dist/components/problems-solved.mjs +135 -0
  56. package/dist/components/problems-solved.mjs.map +1 -0
  57. package/dist/components/resource-links.d.mts +28 -0
  58. package/dist/components/resource-links.d.ts +28 -0
  59. package/dist/components/resource-links.js +229 -0
  60. package/dist/components/resource-links.js.map +1 -0
  61. package/dist/components/resource-links.mjs +227 -0
  62. package/dist/components/resource-links.mjs.map +1 -0
  63. package/dist/components/social-links.d.mts +37 -0
  64. package/dist/components/social-links.d.ts +37 -0
  65. package/dist/components/social-links.js +268 -0
  66. package/dist/components/social-links.js.map +1 -0
  67. package/dist/components/social-links.mjs +266 -0
  68. package/dist/components/social-links.mjs.map +1 -0
  69. package/dist/components/unsubscribe.d.mts +14 -0
  70. package/dist/components/unsubscribe.d.ts +14 -0
  71. package/dist/components/unsubscribe.js +538 -0
  72. package/dist/components/unsubscribe.js.map +1 -0
  73. package/dist/components/unsubscribe.mjs +517 -0
  74. package/dist/components/unsubscribe.mjs.map +1 -0
  75. package/dist/components/waitlist.d.mts +70 -0
  76. package/dist/components/waitlist.d.ts +70 -0
  77. package/dist/components/waitlist.js +864 -0
  78. package/dist/components/waitlist.js.map +1 -0
  79. package/dist/components/waitlist.mjs +841 -0
  80. package/dist/components/waitlist.mjs.map +1 -0
  81. package/dist/components/website-switcher.d.mts +27 -0
  82. package/dist/components/website-switcher.d.ts +27 -0
  83. package/dist/components/website-switcher.js +168 -0
  84. package/dist/components/website-switcher.js.map +1 -0
  85. package/dist/components/website-switcher.mjs +146 -0
  86. package/dist/components/website-switcher.mjs.map +1 -0
  87. package/dist/content/index.d.mts +247 -0
  88. package/dist/content/index.d.ts +247 -0
  89. package/dist/content/index.js +2458 -0
  90. package/dist/content/index.js.map +1 -0
  91. package/dist/content/index.mjs +2428 -0
  92. package/dist/content/index.mjs.map +1 -0
  93. package/dist/index.d.mts +72 -0
  94. package/dist/index.d.ts +72 -0
  95. package/dist/index.js +6273 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/index.mjs +6204 -0
  98. package/dist/index.mjs.map +1 -0
  99. package/dist/product/index.d.mts +94 -0
  100. package/dist/product/index.d.ts +94 -0
  101. package/dist/product/index.js +282 -0
  102. package/dist/product/index.js.map +1 -0
  103. package/dist/product/index.mjs +278 -0
  104. package/dist/product/index.mjs.map +1 -0
  105. package/dist/provider-D7Rij9UM.d.mts +86 -0
  106. package/dist/provider-D7Rij9UM.d.ts +86 -0
  107. package/dist/seo/index.d.mts +64 -0
  108. package/dist/seo/index.d.ts +64 -0
  109. package/dist/seo/index.js +61 -0
  110. package/dist/seo/index.js.map +1 -0
  111. package/dist/seo/index.mjs +59 -0
  112. package/dist/seo/index.mjs.map +1 -0
  113. package/dist/utils/index.d.mts +21 -0
  114. package/dist/utils/index.d.ts +21 -0
  115. package/dist/utils/index.js +12 -0
  116. package/dist/utils/index.js.map +1 -0
  117. package/dist/utils/index.mjs +10 -0
  118. package/dist/utils/index.mjs.map +1 -0
  119. package/package.json +168 -0
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2025 Burdenoff Consultancy Services Pvt. Ltd.
4
+
5
+ All rights reserved.
6
+
7
+ This software and associated documentation files (the "Software") are the
8
+ proprietary and confidential information of Burdenoff Consultancy Services Pvt. Ltd.
9
+
10
+ The Software is licensed, not sold. You may use the Software only if you have a
11
+ valid license from Burdenoff Consultancy Services Pvt. Ltd.
12
+
13
+ Unauthorized copying, distribution, modification, public display, or public
14
+ performance of this Software is strictly prohibited.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+
24
+ For licensing inquiries, please contact: contact@burdenoff.com
package/README.md ADDED
@@ -0,0 +1,357 @@
1
+ # @burdenoff/website-sdk
2
+
3
+ Reusable React components and utilities for Burdenoff product websites.
4
+
5
+ > Published automatically using npm trusted publishers (OIDC) - no long-lived tokens needed!
6
+
7
+ ## Features
8
+
9
+ - 🎨 **Pre-built Components**: Contact forms, newsletter subscriptions, pricing tables
10
+ - 🎯 **SEO Optimized**: Built-in meta tag management with React Helmet
11
+ - 🔧 **Fully Configurable**: All components accept props for complete customization
12
+ - 📱 **Responsive Design**: Mobile-first, works on all screen sizes
13
+ - 🎭 **Theme Support**: Built with Tailwind CSS and semantic tokens
14
+ - ✅ **Type Safe**: Written in TypeScript with full type definitions
15
+ - 🚀 **Tree Shakeable**: ESM and CJS builds for optimal bundle size
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @burdenoff/website-sdk
21
+ ```
22
+
23
+ ### Peer Dependencies
24
+
25
+ This package requires the following peer dependencies:
26
+
27
+ ```bash
28
+ npm install react react-dom react-helmet-async react-hook-form @hookform/resolvers zod sonner
29
+ ```
30
+
31
+ For UI components (if using separately):
32
+
33
+ ```bash
34
+ npm install @radix-ui/react-label @radix-ui/react-slot class-variance-authority clsx tailwind-merge
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ### Contact Page
40
+
41
+ ```tsx
42
+ import { ContactPage } from '@burdenoff/website-sdk/components/contact'
43
+
44
+ function Contact() {
45
+ return (
46
+ <ContactPage
47
+ productName="MyProduct"
48
+ apiBaseUrl="https://api.myproduct.com"
49
+ recaptchaSiteKey="your-recaptcha-site-key"
50
+ contactEmail="contact@myproduct.com"
51
+ contactPhone="+1 234 567 8900"
52
+ officeAddress={{
53
+ street: '123 Main St',
54
+ city: 'San Francisco',
55
+ state: 'CA',
56
+ zip: '94102',
57
+ country: 'United States',
58
+ }}
59
+ // Optional SEO props
60
+ seoTitle="Contact Us"
61
+ seoDescription="Get in touch with our team"
62
+ />
63
+ )
64
+ }
65
+ ```
66
+
67
+ ### Newsletter Page
68
+
69
+ ```tsx
70
+ import { NewsletterPage } from '@burdenoff/website-sdk/components/newsletter'
71
+
72
+ function Newsletter() {
73
+ return (
74
+ <NewsletterPage
75
+ productName="MyProduct"
76
+ apiBaseUrl="https://api.myproduct.com"
77
+ defaultEmail="newsletter@myproduct.com"
78
+ layout="centered" // or "split"
79
+ heroHeading="Stay Updated"
80
+ heroSubtitle="Subscribe to our newsletter"
81
+ />
82
+ )
83
+ }
84
+ ```
85
+
86
+ ### Pricing Page
87
+
88
+ ```tsx
89
+ import { PricingPage } from '@burdenoff/website-sdk/components/pricing'
90
+
91
+ function Pricing() {
92
+ return (
93
+ <PricingPage
94
+ productName="MyProduct"
95
+ productId="myproduct-123"
96
+ apiBaseUrl="https://api.myproduct.com"
97
+ appLoginUrl="https://app.myproduct.com/login"
98
+ contactUrl="/contact"
99
+ fallbackFeatures={{
100
+ basic: ['Up to 5 dashboards', '10 data sources', 'Email support'],
101
+ professional: ['Unlimited dashboards', 'API access', 'Priority support'],
102
+ enterprise: ['Everything in Professional', 'Dedicated support', 'SLA guarantee'],
103
+ }}
104
+ seoTitle="Pricing Plans"
105
+ seoDescription="Choose the perfect plan for your needs"
106
+ />
107
+ )
108
+ }
109
+ ```
110
+
111
+ ### SEO Component
112
+
113
+ ```tsx
114
+ import { PageHead } from '@burdenoff/website-sdk/seo'
115
+
116
+ function AboutPage() {
117
+ return (
118
+ <>
119
+ <PageHead
120
+ title="About Us"
121
+ description="Learn about our mission and team"
122
+ productName="MyProduct"
123
+ keywords="about, team, mission"
124
+ image="/og-about.png"
125
+ url="https://myproduct.com/about"
126
+ />
127
+ <div>{/* Page content */}</div>
128
+ </>
129
+ )
130
+ }
131
+ ```
132
+
133
+ ### UI Components
134
+
135
+ ```tsx
136
+ import { Button, Input, Label, Textarea } from '@burdenoff/website-sdk/ui'
137
+
138
+ function Form() {
139
+ return (
140
+ <form>
141
+ <div>
142
+ <Label htmlFor="name">Name</Label>
143
+ <Input id="name" type="text" placeholder="Your name" />
144
+ </div>
145
+ <div>
146
+ <Label htmlFor="message">Message</Label>
147
+ <Textarea id="message" placeholder="Your message" />
148
+ </div>
149
+ <Button type="submit">Send</Button>
150
+ </form>
151
+ )
152
+ }
153
+ ```
154
+
155
+ ### Utilities
156
+
157
+ ```tsx
158
+ import { cn } from '@burdenoff/website-sdk/utils'
159
+
160
+ // Merge Tailwind CSS classes
161
+ const className = cn('px-4 py-2', isActive && 'bg-blue-500', 'rounded-lg')
162
+ ```
163
+
164
+ ## API Integration
165
+
166
+ All components that require API integration expect the following endpoints:
167
+
168
+ ### Contact Form: `POST /api/contact`
169
+
170
+ **Request:**
171
+ ```json
172
+ {
173
+ "name": "John Doe",
174
+ "email": "john@example.com",
175
+ "phone": "+1 234 567 8900",
176
+ "subject": "Inquiry",
177
+ "message": "Hello, I have a question...",
178
+ "recaptchaToken": "token-here"
179
+ }
180
+ ```
181
+
182
+ **Response:**
183
+ ```json
184
+ {
185
+ "success": true,
186
+ "message": "Message sent successfully"
187
+ }
188
+ ```
189
+
190
+ ### Newsletter: `POST /api/newsletter/subscribe`
191
+
192
+ **Request:**
193
+ ```json
194
+ {
195
+ "email": "john@example.com"
196
+ }
197
+ ```
198
+
199
+ **Response:**
200
+ ```json
201
+ {
202
+ "success": true,
203
+ "message": "Successfully subscribed!"
204
+ }
205
+ ```
206
+
207
+ ### Pricing: `GET /api/plans`
208
+
209
+ **Headers:**
210
+ ```
211
+ x-product-id: your-product-id
212
+ ```
213
+
214
+ **Response:**
215
+ ```json
216
+ {
217
+ "success": true,
218
+ "data": [
219
+ {
220
+ "id": "plan-1",
221
+ "name": "Basic",
222
+ "description": "Perfect for individuals",
223
+ "price": 9.99,
224
+ "currency": "USD",
225
+ "duration": "monthly",
226
+ "features": [...],
227
+ "isActive": true
228
+ }
229
+ ]
230
+ }
231
+ ```
232
+
233
+ ## TypeScript
234
+
235
+ All components are fully typed. Import types as needed:
236
+
237
+ ```tsx
238
+ import type { ContactPageProps } from '@burdenoff/website-sdk/components/contact'
239
+ import type { NewsletterPageProps } from '@burdenoff/website-sdk/components/newsletter'
240
+ import type { PricingProps, PlanCard } from '@burdenoff/website-sdk/components/pricing'
241
+ import type { PageHeadProps } from '@burdenoff/website-sdk/seo'
242
+ import type { ButtonProps } from '@burdenoff/website-sdk/ui'
243
+ ```
244
+
245
+ ## Styling
246
+
247
+ This SDK uses Tailwind CSS for styling. Ensure your project has Tailwind configured with the following in your `tailwind.config.js`:
248
+
249
+ ```js
250
+ module.exports = {
251
+ content: [
252
+ './src/**/*.{js,ts,jsx,tsx}',
253
+ './node_modules/@burdenoff/website-sdk/**/*.{js,mjs}',
254
+ ],
255
+ // ... rest of your config
256
+ }
257
+ ```
258
+
259
+ ### Required CSS Variables
260
+
261
+ Add these CSS variables to your global stylesheet for proper theming:
262
+
263
+ ```css
264
+ @layer base {
265
+ :root {
266
+ --background: 0 0% 100%;
267
+ --foreground: 222.2 84% 4.9%;
268
+ --card: 0 0% 100%;
269
+ --card-foreground: 222.2 84% 4.9%;
270
+ --popover: 0 0% 100%;
271
+ --popover-foreground: 222.2 84% 4.9%;
272
+ --primary: 222.2 47.4% 11.2%;
273
+ --primary-foreground: 210 40% 98%;
274
+ --secondary: 210 40% 96.1%;
275
+ --secondary-foreground: 222.2 47.4% 11.2%;
276
+ --muted: 210 40% 96.1%;
277
+ --muted-foreground: 215.4 16.3% 46.9%;
278
+ --accent: 210 40% 96.1%;
279
+ --accent-foreground: 222.2 47.4% 11.2%;
280
+ --destructive: 0 84.2% 60.2%;
281
+ --destructive-foreground: 210 40% 98%;
282
+ --border: 214.3 31.8% 91.4%;
283
+ --input: 214.3 31.8% 91.4%;
284
+ --ring: 222.2 84% 4.9%;
285
+ --radius: 0.5rem;
286
+ }
287
+
288
+ .dark {
289
+ --background: 222.2 84% 4.9%;
290
+ --foreground: 210 40% 98%;
291
+ --card: 222.2 84% 4.9%;
292
+ --card-foreground: 210 40% 98%;
293
+ --popover: 222.2 84% 4.9%;
294
+ --popover-foreground: 210 40% 98%;
295
+ --primary: 210 40% 98%;
296
+ --primary-foreground: 222.2 47.4% 11.2%;
297
+ --secondary: 217.2 32.6% 17.5%;
298
+ --secondary-foreground: 210 40% 98%;
299
+ --muted: 217.2 32.6% 17.5%;
300
+ --muted-foreground: 215 20.2% 65.1%;
301
+ --accent: 217.2 32.6% 17.5%;
302
+ --accent-foreground: 210 40% 98%;
303
+ --destructive: 0 62.8% 30.6%;
304
+ --destructive-foreground: 210 40% 98%;
305
+ --border: 217.2 32.6% 17.5%;
306
+ --input: 217.2 32.6% 17.5%;
307
+ --ring: 212.7 26.8% 83.9%;
308
+ }
309
+ }
310
+ ```
311
+
312
+ ## Component Documentation
313
+
314
+ ### ContactPage
315
+
316
+ Full-featured contact form with reCAPTCHA v3 integration.
317
+
318
+ **Props:**
319
+ - `productName` (required): Product name for branding
320
+ - `apiBaseUrl` (required): Base URL for API calls
321
+ - `recaptchaSiteKey` (required): Google reCAPTCHA v3 site key
322
+ - `contactEmail` (required): Contact email address
323
+ - `contactPhone` (required): Contact phone number
324
+ - `officeAddress` (required): Office address object
325
+ - `seoTitle`, `seoDescription`, etc.: SEO metadata (optional)
326
+
327
+ ### NewsletterPage
328
+
329
+ Newsletter subscription component with rate limiting.
330
+
331
+ **Props:**
332
+ - `productName` (required): Product name
333
+ - `apiBaseUrl` (required): API base URL
334
+ - `defaultEmail` (required): Default contact email
335
+ - `layout`: 'centered' or 'split' (default: 'centered')
336
+ - `rateLimitAttempts`: Number of attempts before rate limiting (default: 3)
337
+ - `rateLimitWindowMinutes`: Rate limit window in minutes (default: 15)
338
+
339
+ ### PricingPage / PricingSection
340
+
341
+ Dynamic pricing tables with API integration and billing cycle toggle.
342
+
343
+ **Props:**
344
+ - `productName` (required): Product name
345
+ - `productId` (required): Product ID for API requests
346
+ - `apiBaseUrl` (required): API base URL
347
+ - `appLoginUrl` (required): App login URL for signup
348
+ - `contactUrl`: Contact page URL (default: '/contact')
349
+ - `fallbackFeatures`: Fallback features when API doesn't provide them
350
+
351
+ ## License
352
+
353
+ Proprietary - Copyright Burdenoff Consultancy Services Pvt. Ltd. 2025
354
+
355
+ ## Support
356
+
357
+ For support, email contact@burdenoff.com or visit https://burdenoff.com
@@ -0,0 +1,27 @@
1
+ interface RybbitAnalyticsProps {
2
+ /**
3
+ * Rybbit site ID (obtained from the Rybbit dashboard)
4
+ */
5
+ siteId: string;
6
+ /**
7
+ * Rybbit script URL (defaults to the self-hosted instance)
8
+ * @default "https://analytics.burdenoff.com/api/script.js"
9
+ */
10
+ scriptUrl?: string;
11
+ /**
12
+ * Whether to enable tracking (useful for disabling in development)
13
+ * @default true
14
+ */
15
+ enabled?: boolean;
16
+ }
17
+ /**
18
+ * RybbitAnalytics - Embeds the Rybbit analytics tracking script.
19
+ *
20
+ * The script is loaded asynchronously with `defer` to avoid blocking page load.
21
+ * It automatically tracks page views and user interactions.
22
+ *
23
+ * In development mode (when `enabled` is false), no script is loaded.
24
+ */
25
+ declare function RybbitAnalytics({ siteId, scriptUrl, enabled, }: RybbitAnalyticsProps): null;
26
+
27
+ export { RybbitAnalytics, type RybbitAnalyticsProps };
@@ -0,0 +1,27 @@
1
+ interface RybbitAnalyticsProps {
2
+ /**
3
+ * Rybbit site ID (obtained from the Rybbit dashboard)
4
+ */
5
+ siteId: string;
6
+ /**
7
+ * Rybbit script URL (defaults to the self-hosted instance)
8
+ * @default "https://analytics.burdenoff.com/api/script.js"
9
+ */
10
+ scriptUrl?: string;
11
+ /**
12
+ * Whether to enable tracking (useful for disabling in development)
13
+ * @default true
14
+ */
15
+ enabled?: boolean;
16
+ }
17
+ /**
18
+ * RybbitAnalytics - Embeds the Rybbit analytics tracking script.
19
+ *
20
+ * The script is loaded asynchronously with `defer` to avoid blocking page load.
21
+ * It automatically tracks page views and user interactions.
22
+ *
23
+ * In development mode (when `enabled` is false), no script is loaded.
24
+ */
25
+ declare function RybbitAnalytics({ siteId, scriptUrl, enabled, }: RybbitAnalyticsProps): null;
26
+
27
+ export { RybbitAnalytics, type RybbitAnalyticsProps };
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ function RybbitAnalytics({
6
+ siteId,
7
+ scriptUrl = "https://analytics.burdenoff.com/api/script.js",
8
+ enabled = true
9
+ }) {
10
+ react.useEffect(() => {
11
+ if (!enabled || !siteId) return;
12
+ const existingScript = document.querySelector(
13
+ `script[data-site-id="${siteId}"]`
14
+ );
15
+ if (existingScript) return;
16
+ const script = document.createElement("script");
17
+ script.src = scriptUrl;
18
+ script.defer = true;
19
+ script.crossOrigin = "anonymous";
20
+ script.setAttribute("data-site-id", siteId);
21
+ document.head.appendChild(script);
22
+ return () => {
23
+ const scriptToRemove = document.querySelector(
24
+ `script[data-site-id="${siteId}"]`
25
+ );
26
+ if (scriptToRemove) {
27
+ document.head.removeChild(scriptToRemove);
28
+ }
29
+ };
30
+ }, [siteId, scriptUrl, enabled]);
31
+ return null;
32
+ }
33
+
34
+ exports.RybbitAnalytics = RybbitAnalytics;
35
+ //# sourceMappingURL=index.js.map
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/analytics/rybbit.tsx"],"names":["useEffect"],"mappings":";;;;AAoDO,SAAS,eAAA,CAAgB;AAAA,EAC9B,MAAA;AAAA,EACA,SAAA,GAAY,+CAAA;AAAA,EACZ,OAAA,GAAU;AACZ,CAAA,EAAyB;AACvB,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,EAAQ;AAGzB,IAAA,MAAM,iBAAiB,QAAA,CAAS,aAAA;AAAA,MAC9B,wBAAwB,MAAM,CAAA,EAAA;AAAA,KAChC;AACA,IAAA,IAAI,cAAA,EAAgB;AAQpB,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GAAM,SAAA;AACb,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,WAAA,GAAc,WAAA;AACrB,IAAA,MAAA,CAAO,YAAA,CAAa,gBAAgB,MAAM,CAAA;AAC1C,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAGhC,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,iBAAiB,QAAA,CAAS,aAAA;AAAA,QAC9B,wBAAwB,MAAM,CAAA,EAAA;AAAA,OAChC;AACA,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,QAAA,CAAS,IAAA,CAAK,YAAY,cAAc,CAAA;AAAA,MAC1C;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAC,CAAA;AAG/B,EAAA,OAAO,IAAA;AACT","file":"index.js","sourcesContent":["/**\n * Rybbit Analytics Component\n *\n * Injects the Rybbit tracking script into the page head.\n * Works with both Vite (CSR) and Next.js (SSR/CSR) applications.\n *\n * @example\n * ```tsx\n * // In your app layout or root component\n * import { RybbitAnalytics } from '@burdenoff/website-sdk/analytics'\n *\n * function App() {\n * return (\n * <>\n * <RybbitAnalytics siteId=\"1\" />\n * <Router>...</Router>\n * </>\n * )\n * }\n * ```\n */\n\"use client\";\n\nimport { useEffect } from \"react\";\n\nexport interface RybbitAnalyticsProps {\n /**\n * Rybbit site ID (obtained from the Rybbit dashboard)\n */\n siteId: string;\n\n /**\n * Rybbit script URL (defaults to the self-hosted instance)\n * @default \"https://analytics.burdenoff.com/api/script.js\"\n */\n scriptUrl?: string;\n\n /**\n * Whether to enable tracking (useful for disabling in development)\n * @default true\n */\n enabled?: boolean;\n}\n\n/**\n * RybbitAnalytics - Embeds the Rybbit analytics tracking script.\n *\n * The script is loaded asynchronously with `defer` to avoid blocking page load.\n * It automatically tracks page views and user interactions.\n *\n * In development mode (when `enabled` is false), no script is loaded.\n */\nexport function RybbitAnalytics({\n siteId,\n scriptUrl = \"https://analytics.burdenoff.com/api/script.js\",\n enabled = true,\n}: RybbitAnalyticsProps) {\n useEffect(() => {\n if (!enabled || !siteId) return;\n\n // Check if script already exists\n const existingScript = document.querySelector(\n `script[data-site-id=\"${siteId}\"]`,\n );\n if (existingScript) return;\n\n // Create and inject the script. `crossOrigin=\"anonymous\"` puts the\n // request in CORS-no-credentials mode so the browser does not include\n // any third-party cookies the visitor may have on the analytics origin\n // (e.g. `app.rybbit.io`'s own dashboard session cookie). Without this,\n // Lighthouse `third-party-cookies` audit flags the page even though we\n // never read those cookies ourselves.\n const script = document.createElement(\"script\");\n script.src = scriptUrl;\n script.defer = true;\n script.crossOrigin = \"anonymous\";\n script.setAttribute(\"data-site-id\", siteId);\n document.head.appendChild(script);\n\n // Cleanup on unmount\n return () => {\n const scriptToRemove = document.querySelector(\n `script[data-site-id=\"${siteId}\"]`,\n );\n if (scriptToRemove) {\n document.head.removeChild(scriptToRemove);\n }\n };\n }, [siteId, scriptUrl, enabled]);\n\n // This component renders nothing - it only manages the script tag\n return null;\n}\n"]}
@@ -0,0 +1,34 @@
1
+ import { useEffect } from 'react';
2
+
3
+ function RybbitAnalytics({
4
+ siteId,
5
+ scriptUrl = "https://analytics.burdenoff.com/api/script.js",
6
+ enabled = true
7
+ }) {
8
+ useEffect(() => {
9
+ if (!enabled || !siteId) return;
10
+ const existingScript = document.querySelector(
11
+ `script[data-site-id="${siteId}"]`
12
+ );
13
+ if (existingScript) return;
14
+ const script = document.createElement("script");
15
+ script.src = scriptUrl;
16
+ script.defer = true;
17
+ script.crossOrigin = "anonymous";
18
+ script.setAttribute("data-site-id", siteId);
19
+ document.head.appendChild(script);
20
+ return () => {
21
+ const scriptToRemove = document.querySelector(
22
+ `script[data-site-id="${siteId}"]`
23
+ );
24
+ if (scriptToRemove) {
25
+ document.head.removeChild(scriptToRemove);
26
+ }
27
+ };
28
+ }, [siteId, scriptUrl, enabled]);
29
+ return null;
30
+ }
31
+
32
+ export { RybbitAnalytics };
33
+ //# sourceMappingURL=index.mjs.map
34
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/analytics/rybbit.tsx"],"names":[],"mappings":";;AAoDO,SAAS,eAAA,CAAgB;AAAA,EAC9B,MAAA;AAAA,EACA,SAAA,GAAY,+CAAA;AAAA,EACZ,OAAA,GAAU;AACZ,CAAA,EAAyB;AACvB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,EAAQ;AAGzB,IAAA,MAAM,iBAAiB,QAAA,CAAS,aAAA;AAAA,MAC9B,wBAAwB,MAAM,CAAA,EAAA;AAAA,KAChC;AACA,IAAA,IAAI,cAAA,EAAgB;AAQpB,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GAAM,SAAA;AACb,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,WAAA,GAAc,WAAA;AACrB,IAAA,MAAA,CAAO,YAAA,CAAa,gBAAgB,MAAM,CAAA;AAC1C,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAGhC,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,iBAAiB,QAAA,CAAS,aAAA;AAAA,QAC9B,wBAAwB,MAAM,CAAA,EAAA;AAAA,OAChC;AACA,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,QAAA,CAAS,IAAA,CAAK,YAAY,cAAc,CAAA;AAAA,MAC1C;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAC,CAAA;AAG/B,EAAA,OAAO,IAAA;AACT","file":"index.mjs","sourcesContent":["/**\n * Rybbit Analytics Component\n *\n * Injects the Rybbit tracking script into the page head.\n * Works with both Vite (CSR) and Next.js (SSR/CSR) applications.\n *\n * @example\n * ```tsx\n * // In your app layout or root component\n * import { RybbitAnalytics } from '@burdenoff/website-sdk/analytics'\n *\n * function App() {\n * return (\n * <>\n * <RybbitAnalytics siteId=\"1\" />\n * <Router>...</Router>\n * </>\n * )\n * }\n * ```\n */\n\"use client\";\n\nimport { useEffect } from \"react\";\n\nexport interface RybbitAnalyticsProps {\n /**\n * Rybbit site ID (obtained from the Rybbit dashboard)\n */\n siteId: string;\n\n /**\n * Rybbit script URL (defaults to the self-hosted instance)\n * @default \"https://analytics.burdenoff.com/api/script.js\"\n */\n scriptUrl?: string;\n\n /**\n * Whether to enable tracking (useful for disabling in development)\n * @default true\n */\n enabled?: boolean;\n}\n\n/**\n * RybbitAnalytics - Embeds the Rybbit analytics tracking script.\n *\n * The script is loaded asynchronously with `defer` to avoid blocking page load.\n * It automatically tracks page views and user interactions.\n *\n * In development mode (when `enabled` is false), no script is loaded.\n */\nexport function RybbitAnalytics({\n siteId,\n scriptUrl = \"https://analytics.burdenoff.com/api/script.js\",\n enabled = true,\n}: RybbitAnalyticsProps) {\n useEffect(() => {\n if (!enabled || !siteId) return;\n\n // Check if script already exists\n const existingScript = document.querySelector(\n `script[data-site-id=\"${siteId}\"]`,\n );\n if (existingScript) return;\n\n // Create and inject the script. `crossOrigin=\"anonymous\"` puts the\n // request in CORS-no-credentials mode so the browser does not include\n // any third-party cookies the visitor may have on the analytics origin\n // (e.g. `app.rybbit.io`'s own dashboard session cookie). Without this,\n // Lighthouse `third-party-cookies` audit flags the page even though we\n // never read those cookies ourselves.\n const script = document.createElement(\"script\");\n script.src = scriptUrl;\n script.defer = true;\n script.crossOrigin = \"anonymous\";\n script.setAttribute(\"data-site-id\", siteId);\n document.head.appendChild(script);\n\n // Cleanup on unmount\n return () => {\n const scriptToRemove = document.querySelector(\n `script[data-site-id=\"${siteId}\"]`,\n );\n if (scriptToRemove) {\n document.head.removeChild(scriptToRemove);\n }\n };\n }, [siteId, scriptUrl, enabled]);\n\n // This component renders nothing - it only manages the script tag\n return null;\n}\n"]}
@@ -0,0 +1,29 @@
1
+ export { W as WebSDKClient, a as WebSDKClientConfig, b as WebSDKProvider, c as WebSDKProviderProps, u as useWebSDK, d as useWebSDKConfig } from '../provider-D7Rij9UM.mjs';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
4
+
5
+ /**
6
+ * Runtime gateway URL resolution for product marketing websites.
7
+ *
8
+ * Mirrors the app shell pattern from @burdenoff/fe-libs/shared/config/gatewayUrls
9
+ * but scoped to the website SDK's needs (global gateway only, no workspace gateway).
10
+ *
11
+ * Resolution priority:
12
+ * 1. Explicit `gatewayUrl` passed in config — used as-is only if it is a valid
13
+ * absolute, non-localhost URL (relative/invalid values fall through)
14
+ * 2. Hostname-based auto-detection:
15
+ * - Production domains (vibecontrols.com, bigconsole.com, ...) → prod gateway
16
+ * - Alpha domains (alpha.vibecontrols.com, ...) → alpha gateway
17
+ * - Everything else (localhost, *.local.burdenoff.com) → relative `/global/graphql`
18
+ */
19
+ /**
20
+ * Resolve the global gateway URL at runtime based on the current hostname.
21
+ *
22
+ * @param explicitUrl - URL explicitly passed in SDK config. Honored only when
23
+ * it is a valid absolute, non-localhost URL; relative/invalid values are
24
+ * ignored so hostname auto-detection can resolve the correct gateway.
25
+ * @returns Resolved gateway URL
26
+ */
27
+ declare function resolveGatewayUrl(explicitUrl?: string): string;
28
+
29
+ export { resolveGatewayUrl };
@@ -0,0 +1,29 @@
1
+ export { W as WebSDKClient, a as WebSDKClientConfig, b as WebSDKProvider, c as WebSDKProviderProps, u as useWebSDK, d as useWebSDKConfig } from '../provider-D7Rij9UM.js';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
4
+
5
+ /**
6
+ * Runtime gateway URL resolution for product marketing websites.
7
+ *
8
+ * Mirrors the app shell pattern from @burdenoff/fe-libs/shared/config/gatewayUrls
9
+ * but scoped to the website SDK's needs (global gateway only, no workspace gateway).
10
+ *
11
+ * Resolution priority:
12
+ * 1. Explicit `gatewayUrl` passed in config — used as-is only if it is a valid
13
+ * absolute, non-localhost URL (relative/invalid values fall through)
14
+ * 2. Hostname-based auto-detection:
15
+ * - Production domains (vibecontrols.com, bigconsole.com, ...) → prod gateway
16
+ * - Alpha domains (alpha.vibecontrols.com, ...) → alpha gateway
17
+ * - Everything else (localhost, *.local.burdenoff.com) → relative `/global/graphql`
18
+ */
19
+ /**
20
+ * Resolve the global gateway URL at runtime based on the current hostname.
21
+ *
22
+ * @param explicitUrl - URL explicitly passed in SDK config. Honored only when
23
+ * it is a valid absolute, non-localhost URL; relative/invalid values are
24
+ * ignored so hostname auto-detection can resolve the correct gateway.
25
+ * @returns Resolved gateway URL
26
+ */
27
+ declare function resolveGatewayUrl(explicitUrl?: string): string;
28
+
29
+ export { resolveGatewayUrl };