@preprio/prepr-nextjs 2.0.0-alpha.10 → 2.0.0-alpha.13
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.
- package/README.md +248 -38
- package/dist/chunk-6FNC3XMI.js +45 -0
- package/dist/chunk-DI26GYQY.js +201 -0
- package/dist/chunk-MKSF2TOK.js +2 -0
- package/dist/chunk-MKSF2TOK.js.map +1 -0
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/middleware/index.cjs +1 -1
- package/dist/middleware/index.cjs.map +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/react/index.cjs +6 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +47 -9
- package/dist/react/index.d.ts +47 -9
- package/dist/react/index.js +6 -1
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +2 -2
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +14 -3
- package/dist/server/index.d.ts +14 -3
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/types/index.d.cts +3 -3
- package/dist/types/index.d.ts +3 -3
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +6 -2
- package/dist/utils/index.d.ts +6 -2
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +8 -17
- package/dist/chunk-LVXDK2EY.js +0 -2
- package/dist/chunk-LVXDK2EY.js.map +0 -1
package/README.md
CHANGED
|
@@ -29,23 +29,27 @@ export function middleware(request: NextRequest) {
|
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Add
|
|
32
|
+
Add toolbar and tracking to your layout:
|
|
33
33
|
|
|
34
34
|
```typescript
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
35
|
+
import { getToolbarProps, extractAccessToken } from '@preprio/prepr-nextjs/server'
|
|
36
|
+
import { PreprToolbar, PreprToolbarProvider, PreprTrackingPixel } from '@preprio/prepr-nextjs/react'
|
|
37
37
|
import '@preprio/prepr-nextjs/index.css'
|
|
38
38
|
|
|
39
39
|
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
|
40
|
-
const
|
|
40
|
+
const toolbarProps = await getToolbarProps(process.env.PREPR_GRAPHQL_URL!)
|
|
41
|
+
const accessToken = extractAccessToken(process.env.PREPR_GRAPHQL_URL!)
|
|
41
42
|
|
|
42
43
|
return (
|
|
43
44
|
<html>
|
|
45
|
+
<head>
|
|
46
|
+
{accessToken && <PreprTrackingPixel accessToken={accessToken!} />}
|
|
47
|
+
</head>
|
|
44
48
|
<body>
|
|
45
|
-
<
|
|
46
|
-
<
|
|
49
|
+
<PreprToolbarProvider props={toolbarProps}>
|
|
50
|
+
<PreprToolbar />
|
|
47
51
|
{children}
|
|
48
|
-
</
|
|
52
|
+
</PreprToolbarProvider>
|
|
49
53
|
</body>
|
|
50
54
|
</html>
|
|
51
55
|
)
|
|
@@ -68,12 +72,17 @@ Before installing, ensure you have:
|
|
|
68
72
|
2. **Get your GraphQL URL**:
|
|
69
73
|
- Go to Settings → Access tokens
|
|
70
74
|
- Find your GraphQL Preview access token
|
|
75
|
+
|
|
76
|
+

|
|
77
|
+
|
|
71
78
|
- Copy the full GraphQL URL (e.g., `https://graphql.prepr.io/e6f7a0521f11e5149ce65b0e9f372ced2dfc923490890e7f225da1db84cxxxxx`)
|
|
72
79
|
- The URL format is always `https://graphql.prepr.io/{YOUR_ACCESS_TOKEN}`
|
|
73
|
-
3. **Enable edit mode** (for
|
|
80
|
+
3. **Enable edit mode** (for toolbar):
|
|
74
81
|
- Open your GraphQL Preview access token
|
|
75
82
|
- Check "Enable edit mode"
|
|
76
83
|
- Save the token
|
|
84
|
+
|
|
85
|
+

|
|
77
86
|
|
|
78
87
|
## 🔧 Installation & Setup
|
|
79
88
|
|
|
@@ -278,13 +287,54 @@ export function middleware(request: NextRequest) {
|
|
|
278
287
|
|
|
279
288
|
#### App Router (Next.js 13+)
|
|
280
289
|
|
|
290
|
+
The toolbar should only be rendered in preview environments to avoid showing development tools in production. Here are several approaches for conditional rendering:
|
|
291
|
+
|
|
292
|
+
##### Basic Conditional Rendering
|
|
293
|
+
|
|
281
294
|
Update your `app/layout.tsx`:
|
|
282
295
|
|
|
283
296
|
```typescript
|
|
284
|
-
import {
|
|
297
|
+
import { getToolbarProps } from '@preprio/prepr-nextjs/server'
|
|
298
|
+
import {
|
|
299
|
+
PreprToolbar,
|
|
300
|
+
PreprToolbarProvider
|
|
301
|
+
} from '@preprio/prepr-nextjs/react'
|
|
302
|
+
import '@preprio/prepr-nextjs/index.css'
|
|
303
|
+
|
|
304
|
+
export default async function RootLayout({
|
|
305
|
+
children,
|
|
306
|
+
}: {
|
|
307
|
+
children: React.ReactNode
|
|
308
|
+
}) {
|
|
309
|
+
const isPreview = process.env.PREPR_ENV === 'preview'
|
|
310
|
+
const toolbarProps = isPreview ? await getToolbarProps(process.env.PREPR_GRAPHQL_URL!) : null
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<html lang="en">
|
|
314
|
+
<body>
|
|
315
|
+
{isPreview && toolbarProps ? (
|
|
316
|
+
<PreprToolbarProvider props={toolbarProps}>
|
|
317
|
+
<PreprToolbar />
|
|
318
|
+
{children}
|
|
319
|
+
</PreprToolbarProvider>
|
|
320
|
+
) : (
|
|
321
|
+
children
|
|
322
|
+
)}
|
|
323
|
+
</body>
|
|
324
|
+
</html>
|
|
325
|
+
)
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
##### Advanced Conditional Rendering with Error Handling
|
|
330
|
+
|
|
331
|
+
For production applications, you may want more robust error handling:
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { getToolbarProps } from '@preprio/prepr-nextjs/server'
|
|
285
335
|
import {
|
|
286
|
-
|
|
287
|
-
|
|
336
|
+
PreprToolbar,
|
|
337
|
+
PreprToolbarProvider
|
|
288
338
|
} from '@preprio/prepr-nextjs/react'
|
|
289
339
|
import '@preprio/prepr-nextjs/index.css'
|
|
290
340
|
|
|
@@ -293,22 +343,163 @@ export default async function RootLayout({
|
|
|
293
343
|
}: {
|
|
294
344
|
children: React.ReactNode
|
|
295
345
|
}) {
|
|
296
|
-
const
|
|
346
|
+
const isPreview = process.env.PREPR_ENV === 'preview'
|
|
347
|
+
const graphqlUrl = process.env.PREPR_GRAPHQL_URL
|
|
348
|
+
|
|
349
|
+
// Only fetch toolbar props in preview mode with valid URL
|
|
350
|
+
let toolbarProps = null
|
|
351
|
+
if (isPreview && graphqlUrl) {
|
|
352
|
+
try {
|
|
353
|
+
toolbarProps = await getToolbarProps(graphqlUrl)
|
|
354
|
+
} catch (error) {
|
|
355
|
+
console.error('Failed to load toolbar:', error)
|
|
356
|
+
// Continue without toolbar instead of breaking the app
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return (
|
|
361
|
+
<html lang="en">
|
|
362
|
+
<body>
|
|
363
|
+
{isPreview && toolbarProps ? (
|
|
364
|
+
<PreprToolbarProvider props={toolbarProps}>
|
|
365
|
+
<PreprToolbar />
|
|
366
|
+
{children}
|
|
367
|
+
</PreprToolbarProvider>
|
|
368
|
+
) : (
|
|
369
|
+
children
|
|
370
|
+
)}
|
|
371
|
+
</body>
|
|
372
|
+
</html>
|
|
373
|
+
)
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
##### Component-Level Conditional Rendering
|
|
378
|
+
|
|
379
|
+
For better separation of concerns, create a dedicated component:
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
// components/PreviewWrapper.tsx
|
|
383
|
+
import { getToolbarProps } from '@preprio/prepr-nextjs/server'
|
|
384
|
+
import {
|
|
385
|
+
PreprToolbar,
|
|
386
|
+
PreprToolbarProvider
|
|
387
|
+
} from '@preprio/prepr-nextjs/react'
|
|
388
|
+
|
|
389
|
+
interface PreviewWrapperProps {
|
|
390
|
+
children: React.ReactNode
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export default async function PreviewWrapper({ children }: PreviewWrapperProps) {
|
|
394
|
+
const isPreview = process.env.PREPR_ENV === 'preview'
|
|
395
|
+
|
|
396
|
+
if (!isPreview) {
|
|
397
|
+
return <>{children}</>
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const toolbarProps = await getToolbarProps(process.env.PREPR_GRAPHQL_URL!)
|
|
401
|
+
|
|
402
|
+
return (
|
|
403
|
+
<PreprToolbarProvider props={toolbarProps}>
|
|
404
|
+
<PreprToolbar />
|
|
405
|
+
{children}
|
|
406
|
+
</PreprToolbarProvider>
|
|
407
|
+
)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// app/layout.tsx
|
|
411
|
+
import PreviewWrapper from '@/components/PreviewWrapper'
|
|
412
|
+
import '@preprio/prepr-nextjs/index.css'
|
|
297
413
|
|
|
414
|
+
export default function RootLayout({
|
|
415
|
+
children,
|
|
416
|
+
}: {
|
|
417
|
+
children: React.ReactNode
|
|
418
|
+
}) {
|
|
298
419
|
return (
|
|
299
420
|
<html lang="en">
|
|
300
421
|
<body>
|
|
301
|
-
<
|
|
302
|
-
<PreprPreviewBar />
|
|
422
|
+
<PreviewWrapper>
|
|
303
423
|
{children}
|
|
304
|
-
</
|
|
424
|
+
</PreviewWrapper>
|
|
425
|
+
</body>
|
|
426
|
+
</html>
|
|
427
|
+
)
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
#### Why Conditional Rendering Matters
|
|
432
|
+
|
|
433
|
+
1. **Performance**: Prevents unnecessary API calls in production
|
|
434
|
+
2. **Security**: Avoids exposing preview functionality to end users
|
|
435
|
+
3. **Bundle Size**: Excludes toolbar code from production builds
|
|
436
|
+
4. **User Experience**: Ensures clean production UI without development tools
|
|
437
|
+
|
|
438
|
+
#### Best Practices for Conditional Rendering
|
|
439
|
+
|
|
440
|
+
- **Environment Variables**: Always use environment variables to control preview mode
|
|
441
|
+
- **Error Boundaries**: Wrap preview components in error boundaries to prevent crashes
|
|
442
|
+
- **Fallback UI**: Always provide a fallback when toolbar fails to load
|
|
443
|
+
- **TypeScript Safety**: Use proper type guards when checking conditions
|
|
444
|
+
- **Bundle Optimization**: Consider dynamic imports for preview-only code
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
// Dynamic import example for advanced optimization
|
|
448
|
+
const ToolbarDynamic = dynamic(
|
|
449
|
+
() => import('@preprio/prepr-nextjs/react').then(mod => mod.PreprToolbar),
|
|
450
|
+
{
|
|
451
|
+
ssr: false,
|
|
452
|
+
loading: () => <div>Loading preview tools...</div>
|
|
453
|
+
}
|
|
454
|
+
)
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### 5. User Tracking Setup
|
|
458
|
+
|
|
459
|
+
The tracking pixel is essential for collecting user interaction data and enabling personalization features. It should be included in all environments (both preview and production).
|
|
460
|
+
|
|
461
|
+
#### Basic Setup
|
|
462
|
+
|
|
463
|
+
Add the tracking pixel to your layout's `<head>` section:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import { extractAccessToken } from '@preprio/prepr-nextjs/server'
|
|
467
|
+
import { PreprTrackingPixel } from '@preprio/prepr-nextjs/react'
|
|
468
|
+
|
|
469
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
470
|
+
const accessToken = extractAccessToken(process.env.PREPR_GRAPHQL_URL!)
|
|
471
|
+
|
|
472
|
+
return (
|
|
473
|
+
<html>
|
|
474
|
+
<head>
|
|
475
|
+
{accessToken && <PreprTrackingPixel accessToken={accessToken!} />}
|
|
476
|
+
</head>
|
|
477
|
+
<body>{children}</body>
|
|
478
|
+
</html>
|
|
479
|
+
)
|
|
480
|
+
}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
#### Alternative: Body Placement
|
|
484
|
+
|
|
485
|
+
You can also place the tracking pixel in the body if needed:
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
489
|
+
const accessToken = extractAccessToken(process.env.PREPR_GRAPHQL_URL!)
|
|
490
|
+
|
|
491
|
+
return (
|
|
492
|
+
<html>
|
|
493
|
+
<body>
|
|
494
|
+
{accessToken && <PreprTrackingPixel accessToken={accessToken!} />}
|
|
495
|
+
{children}
|
|
305
496
|
</body>
|
|
306
497
|
</html>
|
|
307
498
|
)
|
|
308
499
|
}
|
|
309
500
|
```
|
|
310
501
|
|
|
311
|
-
###
|
|
502
|
+
### 6. API Integration
|
|
312
503
|
|
|
313
504
|
Use the `getPreprHeaders()` helper function in your data fetching to enable personalization and A/B testing:
|
|
314
505
|
|
|
@@ -407,13 +598,13 @@ const variant = await getActiveVariant()
|
|
|
407
598
|
// Returns: 'A' | 'B' | null
|
|
408
599
|
```
|
|
409
600
|
|
|
410
|
-
#### `
|
|
411
|
-
Fetches all necessary props for the
|
|
601
|
+
#### `getToolbarProps()`
|
|
602
|
+
Fetches all necessary props for the toolbar component.
|
|
412
603
|
|
|
413
604
|
```typescript
|
|
414
|
-
import {
|
|
605
|
+
import { getToolbarProps } from '@preprio/prepr-nextjs/server'
|
|
415
606
|
|
|
416
|
-
const props = await
|
|
607
|
+
const props = await getToolbarProps(process.env.PREPR_GRAPHQL_URL!)
|
|
417
608
|
// Returns: { activeSegment, activeVariant, data }
|
|
418
609
|
```
|
|
419
610
|
|
|
@@ -437,26 +628,45 @@ const isPreview = isPreviewMode()
|
|
|
437
628
|
// Returns: boolean
|
|
438
629
|
```
|
|
439
630
|
|
|
631
|
+
#### `extractAccessToken()`
|
|
632
|
+
Extracts the access token from a Prepr GraphQL URL.
|
|
633
|
+
|
|
634
|
+
```typescript
|
|
635
|
+
import { extractAccessToken } from '@preprio/prepr-nextjs/server'
|
|
636
|
+
|
|
637
|
+
const token = extractAccessToken('https://graphql.prepr.io/abc123')
|
|
638
|
+
// Returns: 'abc123' or null
|
|
639
|
+
```
|
|
640
|
+
|
|
440
641
|
### React Components
|
|
441
642
|
|
|
442
|
-
#### `
|
|
443
|
-
Context provider that wraps your app with
|
|
643
|
+
#### `PreprToolbarProvider`
|
|
644
|
+
Context provider that wraps your app with toolbar functionality.
|
|
444
645
|
|
|
445
646
|
```typescript
|
|
446
|
-
import {
|
|
647
|
+
import { PreprToolbarProvider } from '@preprio/prepr-nextjs/react'
|
|
447
648
|
|
|
448
|
-
<
|
|
649
|
+
<PreprToolbarProvider props={toolbarProps}>
|
|
449
650
|
{children}
|
|
450
|
-
</
|
|
651
|
+
</PreprToolbarProvider>
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
#### `PreprToolbar`
|
|
655
|
+
The main toolbar component.
|
|
656
|
+
|
|
657
|
+
```typescript
|
|
658
|
+
import { PreprToolbar } from '@preprio/prepr-nextjs/react'
|
|
659
|
+
|
|
660
|
+
<PreprToolbar />
|
|
451
661
|
```
|
|
452
662
|
|
|
453
|
-
#### `
|
|
454
|
-
|
|
663
|
+
#### `PreprTrackingPixel`
|
|
664
|
+
User tracking component that loads the Prepr tracking script.
|
|
455
665
|
|
|
456
666
|
```typescript
|
|
457
|
-
import {
|
|
667
|
+
import { PreprTrackingPixel } from '@preprio/prepr-nextjs/react'
|
|
458
668
|
|
|
459
|
-
<
|
|
669
|
+
<PreprTrackingPixel accessToken="your-access-token" />
|
|
460
670
|
```
|
|
461
671
|
|
|
462
672
|
## 🔧 Configuration Options
|
|
@@ -482,11 +692,11 @@ createPreprMiddleware(request, response, {
|
|
|
482
692
|
})
|
|
483
693
|
```
|
|
484
694
|
|
|
485
|
-
###
|
|
695
|
+
### Toolbar Options
|
|
486
696
|
|
|
487
697
|
```typescript
|
|
488
|
-
<
|
|
489
|
-
props={
|
|
698
|
+
<PreprToolbarProvider
|
|
699
|
+
props={toolbarProps}
|
|
490
700
|
options={{
|
|
491
701
|
debug: true // Enable debug logging
|
|
492
702
|
}}
|
|
@@ -497,7 +707,7 @@ createPreprMiddleware(request, response, {
|
|
|
497
707
|
|
|
498
708
|
### Common Issues
|
|
499
709
|
|
|
500
|
-
####
|
|
710
|
+
#### Toolbar Not Showing
|
|
501
711
|
- **Check environment**: Ensure `PREPR_ENV=preview` is set
|
|
502
712
|
- **Verify GraphQL URL**: Make sure `PREPR_GRAPHQL_URL` is correct and follows the format `https://graphql.prepr.io/YOUR_ACCESS_TOKEN`
|
|
503
713
|
- **Check token permissions**: Ensure "Enable edit mode" is checked in Prepr
|
|
@@ -537,8 +747,8 @@ try {
|
|
|
537
747
|
Enable debug logging in development:
|
|
538
748
|
|
|
539
749
|
```typescript
|
|
540
|
-
<
|
|
541
|
-
props={
|
|
750
|
+
<PreprToolbarProvider
|
|
751
|
+
props={toolbarProps}
|
|
542
752
|
options={{ debug: true }}
|
|
543
753
|
>
|
|
544
754
|
```
|
|
@@ -554,9 +764,9 @@ The middleware automatically:
|
|
|
554
764
|
4. **Processes A/B tests**: Manages variant assignments
|
|
555
765
|
5. **Sets headers**: Adds necessary headers for API calls
|
|
556
766
|
|
|
557
|
-
###
|
|
767
|
+
### Toolbar Features
|
|
558
768
|
|
|
559
|
-
The
|
|
769
|
+
The toolbar provides:
|
|
560
770
|
- **Segment selection**: Switch between different audience segments
|
|
561
771
|
- **A/B testing**: Toggle between variants A and B
|
|
562
772
|
- **Edit mode**: Visual content editing capabilities
|
|
@@ -582,4 +792,4 @@ MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
|
582
792
|
|
|
583
793
|
- **Documentation**: [Prepr Documentation](https://docs.prepr.io)
|
|
584
794
|
- **Issues**: [GitHub Issues](https://github.com/preprio/prepr-nextjs/issues)
|
|
585
|
-
- **
|
|
795
|
+
- **Support**: [Prepr Support](https://prepr.io/support)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __async = (__this, __arguments, generator) => {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
var fulfilled = (value) => {
|
|
23
|
+
try {
|
|
24
|
+
step(generator.next(value));
|
|
25
|
+
} catch (e) {
|
|
26
|
+
reject(e);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var rejected = (value) => {
|
|
30
|
+
try {
|
|
31
|
+
step(generator.throw(value));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
reject(e);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
__spreadValues,
|
|
43
|
+
__spreadProps,
|
|
44
|
+
__async
|
|
45
|
+
};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// src/middleware/index.ts
|
|
2
|
+
import { ipAddress } from "@vercel/functions";
|
|
3
|
+
import { NextResponse } from "next/server";
|
|
4
|
+
|
|
5
|
+
// package.json
|
|
6
|
+
var version = "2.0.0-alpha.12";
|
|
7
|
+
var package_default = {
|
|
8
|
+
name: "@preprio/prepr-nextjs",
|
|
9
|
+
version,
|
|
10
|
+
description: "Next.js package for Prepr CMS preview functionality with advanced debugging and visual editing capabilities",
|
|
11
|
+
main: "dist/react/index.cjs",
|
|
12
|
+
types: "./dist/react/index.d.ts",
|
|
13
|
+
module: "./dist/react/index.js",
|
|
14
|
+
type: "module",
|
|
15
|
+
scripts: {
|
|
16
|
+
build: "tsup",
|
|
17
|
+
dev: "tsup --watch",
|
|
18
|
+
clean: "rm -rf dist",
|
|
19
|
+
check: 'tsc --noEmit && eslint src --ext .ts,.tsx && prettier --check "src/**/*.{ts,tsx,js,jsx,json,md}"',
|
|
20
|
+
fix: 'eslint src --ext .ts,.tsx --fix && prettier --write "src/**/*.{ts,tsx,js,jsx,json,md}"',
|
|
21
|
+
changeset: "changeset",
|
|
22
|
+
version: "changeset version",
|
|
23
|
+
release: "pnpm run build && changeset publish",
|
|
24
|
+
prepublishOnly: "pnpm run check && pnpm run build"
|
|
25
|
+
},
|
|
26
|
+
exports: {
|
|
27
|
+
"./middleware": {
|
|
28
|
+
import: "./dist/middleware/index.js",
|
|
29
|
+
types: "./dist/middleware/index.d.ts",
|
|
30
|
+
require: "./dist/middleware/index.cjs"
|
|
31
|
+
},
|
|
32
|
+
"./server": {
|
|
33
|
+
import: "./dist/server/index.js",
|
|
34
|
+
types: "./dist/server/index.d.ts",
|
|
35
|
+
require: "./dist/server/index.cjs"
|
|
36
|
+
},
|
|
37
|
+
"./react": {
|
|
38
|
+
import: "./dist/react/index.js",
|
|
39
|
+
types: "./dist/react/index.d.ts",
|
|
40
|
+
require: "./dist/react/index.cjs"
|
|
41
|
+
},
|
|
42
|
+
"./utils": {
|
|
43
|
+
import: "./dist/utils/index.js",
|
|
44
|
+
types: "./dist/utils/index.d.ts",
|
|
45
|
+
require: "./dist/utils/index.cjs"
|
|
46
|
+
},
|
|
47
|
+
"./types": {
|
|
48
|
+
import: "./dist/types/index.js",
|
|
49
|
+
types: "./dist/types/index.d.ts",
|
|
50
|
+
require: "./dist/types/index.cjs"
|
|
51
|
+
},
|
|
52
|
+
"./index.css": {
|
|
53
|
+
import: "./dist/index.css",
|
|
54
|
+
require: "./dist/index.css"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
files: [
|
|
58
|
+
"dist",
|
|
59
|
+
"package.json"
|
|
60
|
+
],
|
|
61
|
+
keywords: [
|
|
62
|
+
"prepr",
|
|
63
|
+
"cms",
|
|
64
|
+
"nextjs",
|
|
65
|
+
"preview",
|
|
66
|
+
"visual-editing",
|
|
67
|
+
"headless-cms",
|
|
68
|
+
"react",
|
|
69
|
+
"typescript",
|
|
70
|
+
"debug",
|
|
71
|
+
"stega"
|
|
72
|
+
],
|
|
73
|
+
author: "Preprio",
|
|
74
|
+
license: "MIT",
|
|
75
|
+
packageManager: "pnpm@10.5.2",
|
|
76
|
+
devDependencies: {
|
|
77
|
+
"@changesets/cli": "^2.29.5",
|
|
78
|
+
"@eslint/js": "^9.25.1",
|
|
79
|
+
"@types/node": "^20.11.5",
|
|
80
|
+
"@types/react": "19.1.0",
|
|
81
|
+
"@types/react-dom": "19.1.2",
|
|
82
|
+
"@typescript-eslint/eslint-plugin": "^8.31.1",
|
|
83
|
+
"@typescript-eslint/parser": "^8.31.1",
|
|
84
|
+
autoprefixer: "^10.4.21",
|
|
85
|
+
cssnano: "^7.0.7",
|
|
86
|
+
eslint: "^9.25.1",
|
|
87
|
+
"eslint-config-prettier": "^10.1.2",
|
|
88
|
+
"eslint-plugin-prettier": "^5.2.6",
|
|
89
|
+
"eslint-plugin-react": "^7.37.2",
|
|
90
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
91
|
+
next: "15.3.1",
|
|
92
|
+
postcss: "^8",
|
|
93
|
+
prettier: "^3.5.3",
|
|
94
|
+
"prettier-plugin-tailwindcss": "^0.5.12",
|
|
95
|
+
react: "^19.1.0",
|
|
96
|
+
"react-dom": "^19.1.0",
|
|
97
|
+
tailwindcss: "^3.4.17",
|
|
98
|
+
tsup: "^8.5.0",
|
|
99
|
+
typescript: "^5.8.3"
|
|
100
|
+
},
|
|
101
|
+
peerDependencies: {
|
|
102
|
+
next: "^15.0.0 || ^14.0.0 || ^13.0.0",
|
|
103
|
+
react: "^19.0.0 || ^18.0.0 || ^17.0.0 ",
|
|
104
|
+
"react-dom": "^19.0.0 || ^18.0.0 || ^17.0.0"
|
|
105
|
+
},
|
|
106
|
+
dependencies: {
|
|
107
|
+
"@headlessui/react": "^2.2.0",
|
|
108
|
+
"@vercel/functions": "^2.0.0",
|
|
109
|
+
"@vercel/stega": "^0.1.2",
|
|
110
|
+
clsx: "^2.1.1",
|
|
111
|
+
"postcss-cli": "^11.0.1",
|
|
112
|
+
"tailwind-merge": "^3.0.1"
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/middleware/index.ts
|
|
117
|
+
function createPreprMiddleware(request, responseOrOptions, options) {
|
|
118
|
+
var _a, _b, _c, _d;
|
|
119
|
+
let response;
|
|
120
|
+
let finalOptions;
|
|
121
|
+
if (responseOrOptions && "headers" in responseOrOptions) {
|
|
122
|
+
response = responseOrOptions;
|
|
123
|
+
finalOptions = options;
|
|
124
|
+
} else {
|
|
125
|
+
response = NextResponse.next();
|
|
126
|
+
finalOptions = responseOrOptions;
|
|
127
|
+
}
|
|
128
|
+
if (!process.env.PREPR_GRAPHQL_URL) {
|
|
129
|
+
console.error("PREPR_GRAPHQL_URL is not set");
|
|
130
|
+
}
|
|
131
|
+
request.nextUrl.searchParams.forEach((value, key) => {
|
|
132
|
+
switch (key) {
|
|
133
|
+
case "utm_source":
|
|
134
|
+
response.headers.set("Prepr-Context-utm_source", value);
|
|
135
|
+
break;
|
|
136
|
+
case "utm_medium":
|
|
137
|
+
response.headers.set("Prepr-Context-utm_medium", value);
|
|
138
|
+
break;
|
|
139
|
+
case "utm_term":
|
|
140
|
+
response.headers.set("Prepr-Context-utm_term", value);
|
|
141
|
+
break;
|
|
142
|
+
case "utm_content":
|
|
143
|
+
response.headers.set("Prepr-Context-utm_content", value);
|
|
144
|
+
break;
|
|
145
|
+
case "utm_campaign":
|
|
146
|
+
response.headers.set("Prepr-Context-utm_campaign", value);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
const referrer = request.headers.get("referer");
|
|
151
|
+
if (referrer) {
|
|
152
|
+
response.headers.set("Prepr-Context-initial_referral", referrer);
|
|
153
|
+
}
|
|
154
|
+
response.headers.set("Prepr-Package", version);
|
|
155
|
+
const ip = ipAddress(request);
|
|
156
|
+
if (ip) {
|
|
157
|
+
response.headers.set("Prepr-Visitor-IP", ip);
|
|
158
|
+
}
|
|
159
|
+
const hutkCookie = (_a = request.cookies.get("hubspotutk")) == null ? void 0 : _a.value;
|
|
160
|
+
if (hutkCookie) {
|
|
161
|
+
response.headers.set("Prepr-Hubspot-Id", hutkCookie);
|
|
162
|
+
}
|
|
163
|
+
let cookie = (_b = request.cookies.get("__prepr_uid")) == null ? void 0 : _b.value;
|
|
164
|
+
if (!cookie) {
|
|
165
|
+
cookie = crypto.randomUUID();
|
|
166
|
+
response.cookies.set("__prepr_uid", cookie, {
|
|
167
|
+
maxAge: 1 * 365 * 24 * 60
|
|
168
|
+
// Set for one year
|
|
169
|
+
});
|
|
170
|
+
response.headers.set("Prepr-Customer-Id-Created", "true");
|
|
171
|
+
}
|
|
172
|
+
response.headers.set("Prepr-Customer-Id", cookie);
|
|
173
|
+
if (!(finalOptions == null ? void 0 : finalOptions.preview) || process.env.PREPR_ENV !== "preview") {
|
|
174
|
+
return response;
|
|
175
|
+
}
|
|
176
|
+
response.headers.set("Prepr-Preview-Bar", "true");
|
|
177
|
+
const segmentCookie = (_c = request.cookies.get("Prepr-Segments")) == null ? void 0 : _c.value;
|
|
178
|
+
if (segmentCookie) {
|
|
179
|
+
response.headers.set("Prepr-Segments", segmentCookie);
|
|
180
|
+
}
|
|
181
|
+
const abCookie = (_d = request.cookies.get("Prepr-ABtesting")) == null ? void 0 : _d.value;
|
|
182
|
+
if (abCookie) {
|
|
183
|
+
response.headers.set("Prepr-ABtesting", abCookie);
|
|
184
|
+
}
|
|
185
|
+
request.nextUrl.searchParams.forEach((value, key) => {
|
|
186
|
+
if (key === "prepr_preview_ab") {
|
|
187
|
+
response.headers.set("Prepr-ABtesting", value);
|
|
188
|
+
response.cookies.set("Prepr-ABtesting", value);
|
|
189
|
+
}
|
|
190
|
+
if (key === "prepr_preview_segment") {
|
|
191
|
+
response.headers.set("Prepr-Segments", value);
|
|
192
|
+
response.cookies.set("Prepr-Segments", value);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return response;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export {
|
|
199
|
+
package_default,
|
|
200
|
+
createPreprMiddleware
|
|
201
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {ipAddress}from'@vercel/functions';import {NextResponse}from'next/server';var h="2.0.0-alpha.13";var v={name:"@preprio/prepr-nextjs",version:h,description:"Next.js package for Prepr CMS preview functionality with advanced debugging and visual editing capabilities",main:"dist/react/index.cjs",types:"./dist/react/index.d.ts",module:"./dist/react/index.js",type:"module",scripts:{build:"tsup",dev:"tsup --watch",clean:"rm -rf dist",check:'tsc --noEmit && eslint src --ext .ts,.tsx && prettier --check "src/**/*.{ts,tsx,js,jsx,json,md}"',fix:'eslint src --ext .ts,.tsx --fix && prettier --write "src/**/*.{ts,tsx,js,jsx,json,md}"',changeset:"changeset",version:"changeset version",release:"pnpm run build && changeset publish",prepublishOnly:"pnpm run check && pnpm run build"},exports:{"./middleware":{import:"./dist/middleware/index.js",types:"./dist/middleware/index.d.ts",require:"./dist/middleware/index.cjs"},"./server":{import:"./dist/server/index.js",types:"./dist/server/index.d.ts",require:"./dist/server/index.cjs"},"./react":{import:"./dist/react/index.js",types:"./dist/react/index.d.ts",require:"./dist/react/index.cjs"},"./utils":{import:"./dist/utils/index.js",types:"./dist/utils/index.d.ts",require:"./dist/utils/index.cjs"},"./types":{import:"./dist/types/index.js",types:"./dist/types/index.d.ts",require:"./dist/types/index.cjs"},"./index.css":{import:"./dist/index.css",require:"./dist/index.css"}},files:["dist","package.json"],keywords:["prepr","cms","nextjs","preview","visual-editing","headless-cms","react","typescript","debug","stega"],author:"Preprio",license:"MIT",packageManager:"pnpm@10.5.2",devDependencies:{"@changesets/cli":"^2.29.5","@eslint/js":"^9.25.1","@types/node":"^20.11.5","@types/react":"19.1.0","@types/react-dom":"19.1.2","@typescript-eslint/eslint-plugin":"^8.31.1","@typescript-eslint/parser":"^8.31.1",autoprefixer:"^10.4.21",cssnano:"^7.0.7",eslint:"^9.25.1","eslint-config-prettier":"^10.1.2","eslint-plugin-prettier":"^5.2.6","eslint-plugin-react":"^7.37.2","eslint-plugin-react-hooks":"^5.0.0",next:"15.3.1",postcss:"^8",prettier:"^3.5.3","prettier-plugin-tailwindcss":"^0.5.12",react:"^19.1.0","react-dom":"^19.1.0",tailwindcss:"^3.4.17",tsup:"^8.5.0",typescript:"^5.8.3"},peerDependencies:{next:"^15.0.0 || ^14.0.0 || ^13.0.0",react:"^19.0.0 || ^18.0.0 || ^17.0.0 ","react-dom":"^19.0.0 || ^18.0.0 || ^17.0.0"},dependencies:{"@headlessui/react":"^2.2.0","@vercel/functions":"^2.0.0","@vercel/stega":"^0.1.2",clsx:"^2.1.1","postcss-cli":"^11.0.1","tailwind-merge":"^3.0.1"}};function _(s,i,f){var u,m,x,P;let e,r;i&&"headers"in i?(e=i,r=f):(e=NextResponse.next(),r=i),process.env.PREPR_GRAPHQL_URL||console.error("PREPR_GRAPHQL_URL is not set"),s.nextUrl.searchParams.forEach((t,p)=>{switch(p){case "utm_source":e.headers.set("Prepr-Context-utm_source",t);break;case "utm_medium":e.headers.set("Prepr-Context-utm_medium",t);break;case "utm_term":e.headers.set("Prepr-Context-utm_term",t);break;case "utm_content":e.headers.set("Prepr-Context-utm_content",t);break;case "utm_campaign":e.headers.set("Prepr-Context-utm_campaign",t);break}});let d=s.headers.get("referer");d&&e.headers.set("Prepr-Context-initial_referral",d),e.headers.set("Prepr-Package",h);let a=ipAddress(s);a&&e.headers.set("Prepr-Visitor-IP",a);let o=(u=s.cookies.get("hubspotutk"))==null?void 0:u.value;o&&e.headers.set("Prepr-Hubspot-Id",o);let n=(m=s.cookies.get("__prepr_uid"))==null?void 0:m.value;if(n||(n=crypto.randomUUID(),e.cookies.set("__prepr_uid",n,{maxAge:1*365*24*60}),e.headers.set("Prepr-Customer-Id-Created","true")),e.headers.set("Prepr-Customer-Id",n),!(r!=null&&r.preview)||process.env.PREPR_ENV!=="preview")return e;e.headers.set("Prepr-Preview-Bar","true");let c=(x=s.cookies.get("Prepr-Segments"))==null?void 0:x.value;c&&e.headers.set("Prepr-Segments",c);let l=(P=s.cookies.get("Prepr-ABtesting"))==null?void 0:P.value;return l&&e.headers.set("Prepr-ABtesting",l),s.nextUrl.searchParams.forEach((t,p)=>{p==="prepr_preview_ab"&&(e.headers.set("Prepr-ABtesting",t),e.cookies.set("Prepr-ABtesting",t)),p==="prepr_preview_segment"&&(e.headers.set("Prepr-Segments",t),e.cookies.set("Prepr-Segments",t));}),e}export{v as a,_ as b};//# sourceMappingURL=chunk-MKSF2TOK.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-MKSF2TOK.js.map
|