@guideify/next 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,122 @@
1
+ Guideify SDK License
2
+
3
+ Copyright (c) 2026 Guideify. All rights reserved.
4
+
5
+ This software is proprietary. It is published to the public npm registry so a
6
+ build tool can install it, not because it is open source. The permission you
7
+ have to use it is written below, and there is no other.
8
+
9
+
10
+ 1. Definitions
11
+
12
+ "Software" means this package and every file it publishes.
13
+
14
+ "Service" means the Guideify hosted product at https://guideify.in.
15
+
16
+ "You" means the person or organisation installing the Software, and any
17
+ organisation You install it on behalf of.
18
+
19
+ "Your Application" means a product You develop and operate that integrates
20
+ the Service.
21
+
22
+
23
+ 2. Grant
24
+
25
+ Subject to Your compliance with this license, Guideify grants You a
26
+ non-exclusive, worldwide, royalty-free, non-transferable, revocable license
27
+ to:
28
+
29
+ (a) install, copy and use the Software in order to integrate the Service
30
+ into Your Application;
31
+
32
+ (b) incorporate the Software into Your Application, including compiling,
33
+ bundling, minifying and otherwise transforming it as an ordinary build
34
+ step does; and
35
+
36
+ (c) distribute the Software as an incorporated part of Your Application to
37
+ Your users, including by serving it from Your own origin or from a
38
+ content delivery network You use.
39
+
40
+ Paragraph (c) is the point of the whole document. A browser SDK reaches its
41
+ audience only by being served from Your pages, and a proprietary license that
42
+ omitted it would forbid the one thing every user of this package must do.
43
+
44
+
45
+ 3. Conditions
46
+
47
+ (a) You may not distribute the Software on its own, or inside anything whose
48
+ purpose is to make the Software available to others. It travels inside
49
+ Your Application or not at all.
50
+
51
+ (b) You may not remove or alter a copyright, license or attribution notice in
52
+ the Software. A build step that strips comments from bundled output is
53
+ not a breach of this paragraph.
54
+
55
+ (c) You may not sublicense the Software except as an inseparable part of Your
56
+ Application, on terms no more permissive than these.
57
+
58
+
59
+ 4. Restrictions
60
+
61
+ (a) You may not modify the Software, or use it, to connect to or interoperate
62
+ with any service other than the Service.
63
+
64
+ (b) You may not use the Software, or knowledge gained from studying it, to
65
+ build a product that competes with the Service.
66
+
67
+ (c) You may not reverse engineer, decompile or disassemble the Software,
68
+ except where that restriction is prohibited by applicable law, or where
69
+ it is necessary to exercise a right applicable law grants You that cannot
70
+ be waived by contract.
71
+
72
+ Nothing in this section restricts what You may do with the Software's public
73
+ API, with its documented behaviour, or with the data the Service returns to
74
+ You about Your own product.
75
+
76
+
77
+ 5. Reservation of rights
78
+
79
+ All rights not expressly granted are reserved. The Software is licensed,
80
+ never sold, and this license transfers no ownership.
81
+
82
+
83
+ 6. Term and termination
84
+
85
+ This license takes effect when You install the Software. It ends when You
86
+ stop using the Service, or if You breach a term and do not remedy the breach
87
+ within thirty days of being told about it.
88
+
89
+ On termination You must stop distributing new copies of the Software. Copies
90
+ already embedded in versions of Your Application that You have already
91
+ distributed are unaffected, and You do not have to recall them.
92
+
93
+
94
+ 7. No warranty
95
+
96
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
97
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
98
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
99
+
100
+
101
+ 8. Limitation of liability
102
+
103
+ TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE
104
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
105
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
106
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
107
+
108
+ Nothing here excludes a liability that applicable law does not permit to be
109
+ excluded.
110
+
111
+
112
+ 9. Relationship to the Terms of Service
113
+
114
+ The Guideify Terms of Service at https://guideify.in/terms govern the
115
+ Service. This license governs the Software.
116
+
117
+ It stands on its own: it is granted by the copyright holder directly, and it
118
+ does not depend on those terms being in force. Copyright exists without
119
+ incorporation, and so does a license over it.
120
+
121
+
122
+ Questions about this license: hello@guideify.in
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @guideify/next
2
+
3
+ App Router wrapper. It handles the one thing plain React cannot: the CSP nonce.
4
+
5
+ ```bash
6
+ npm i @guideify/next
7
+ ```
8
+
9
+ ```tsx
10
+ // app/layout.tsx
11
+ import { Guideify } from '@guideify/next';
12
+
13
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
14
+ return (
15
+ <html>
16
+ <body>
17
+ <Guideify apiKey={process.env.NEXT_PUBLIC_GUIDEIFY_KEY!}>{children}</Guideify>
18
+ </body>
19
+ </html>
20
+ );
21
+ }
22
+ ```
23
+
24
+ ```tsx
25
+ 'use client';
26
+ import { useGuideify, GuideifyTarget } from '@guideify/next';
27
+ ```
28
+
29
+ ## What it adds over `@guideify/react`
30
+
31
+ `GuideifyProvider` is already a client component and works in a Next app
32
+ unchanged. What it cannot do is read the request — and a CSP nonce only exists
33
+ there.
34
+
35
+ `<Guideify>` is a **server** component that reads the nonce and hands it down.
36
+ Without it, a page served with `script-src 'nonce-…'` drops the injected tag:
37
+ no tours, nothing in the console naming us, and a customer who concludes the
38
+ product does not work.
39
+
40
+ It reads the nonce from the request's own `content-security-policy` header
41
+ rather than from the custom request header Next's nonce recipe suggests, because
42
+ that header's *name* is your choice. Depending on it would work for apps that
43
+ picked ours and fail invisibly for the rest.
44
+
45
+ Awaiting `headers()` opts the tree into dynamic rendering. That is unavoidable:
46
+ a nonce is per-request by definition, and a statically rendered page would bake
47
+ in a stale one that every policy refuses. Pass `nonce` yourself to override.
48
+
49
+ `useGuideify` and `GuideifyTarget` are re-exported from `@guideify/react` unchanged
50
+ — there is no Next-specific version of either, and one import beats two.
51
+
52
+ ## What it does not bundle
53
+
54
+ `@guideify/react` stays external, so your app has one provider and one context.
55
+ Inlining it would give the provider one context to write to and the hook another
56
+ to read — which presents as "the core never arrived" in an app where it did.
57
+ `test/boundary.test.mjs` fails the build if that changes.
58
+
59
+ The core is not here either, at one remove: it arrives from the CDN through the
60
+ loader tag, which is what keeps a canary (R-03) and the kill switch (R-04) able
61
+ to reach you.
62
+
63
+ ## License
64
+
65
+ Proprietary — see [LICENSE](./LICENSE). You may bundle this into your own
66
+ application and serve it to your users; you may not redistribute it on its own.
package/dist/index.cjs ADDED
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ var react = require('@guideify/react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/index.ts
7
+
8
+ // src/nonce.ts
9
+ function readNonce(csp) {
10
+ if (!csp) return void 0;
11
+ const match = csp.match(/'nonce-([^']+)'/);
12
+ return match?.[1];
13
+ }
14
+ async function Guideify({ children, nonce, ...options }) {
15
+ const resolved = nonce ?? await requestNonce();
16
+ return /* @__PURE__ */ jsxRuntime.jsx(react.GuideifyProvider, { ...options, nonce: resolved, children });
17
+ }
18
+ async function requestNonce() {
19
+ const { headers } = await import('next/headers');
20
+ const store = await headers();
21
+ return readNonce(store.get("content-security-policy"));
22
+ }
23
+
24
+ Object.defineProperty(exports, "DEFAULT_CDN", {
25
+ enumerable: true,
26
+ get: function () { return react.DEFAULT_CDN; }
27
+ });
28
+ Object.defineProperty(exports, "GuideifyTarget", {
29
+ enumerable: true,
30
+ get: function () { return react.GuideifyTarget; }
31
+ });
32
+ Object.defineProperty(exports, "useGuideify", {
33
+ enumerable: true,
34
+ get: function () { return react.useGuideify; }
35
+ });
36
+ exports.Guideify = Guideify;
37
+ exports.readNonce = readNonce;
@@ -0,0 +1,71 @@
1
+ import { SnippetOptions } from '@guideify/react';
2
+ export { DEFAULT_CDN, GuideifyApi, GuideifyEvent, GuideifyTarget, GuideifyTargetProps, SnippetOptions, Unsubscribe, useGuideify } from '@guideify/react';
3
+ import { ReactNode } from 'react';
4
+
5
+ interface GuideifyProps extends Omit<SnippetOptions, 'nonce'> {
6
+ /**
7
+ * Supply it to override what the request's CSP says. Rarely needed — the
8
+ * point of this component is not having to.
9
+ */
10
+ nonce?: string | undefined;
11
+ children: ReactNode;
12
+ }
13
+ /**
14
+ * Guideify for the App Router — F-06, BUILD_REPORT §6.4.
15
+ *
16
+ * ```tsx
17
+ * // app/layout.tsx
18
+ * import { Guideify } from '@guideify/next';
19
+ *
20
+ * export default function RootLayout({ children }: { children: React.ReactNode }) {
21
+ * return (
22
+ * <html>
23
+ * <body>
24
+ * <Guideify apiKey={process.env.NEXT_PUBLIC_GUIDEIFY_KEY!}>{children}</Guideify>
25
+ * </body>
26
+ * </html>
27
+ * );
28
+ * }
29
+ * ```
30
+ *
31
+ * **A server component wrapping a client one, and that split is the whole
32
+ * package.** `GuideifyProvider` is `'use client'` and works in a Next app
33
+ * unchanged; what it cannot do is read the request, and the CSP nonce only
34
+ * exists there. So this reads the nonce on the server and hands it down — the
35
+ * one thing an App Router application genuinely needs that plain React cannot
36
+ * give it.
37
+ *
38
+ * Without it the failure is silent in the way that costs the most: a page served
39
+ * with `script-src 'nonce-…'` drops the injected tag, no tours run, and nothing
40
+ * in the customer's console names us.
41
+ *
42
+ * `headers()` is awaited, which opts the tree into dynamic rendering. That is
43
+ * unavoidable and not incidental — a nonce is per-request by definition, and a
44
+ * statically rendered page that baked one in would serve a stale nonce every
45
+ * policy refuses.
46
+ */
47
+ declare function Guideify({ children, nonce, ...options }: GuideifyProps): Promise<ReactNode>;
48
+
49
+ /**
50
+ * The CSP nonce for this request, or undefined when the app does not use one.
51
+ *
52
+ * **Reads the request's own `content-security-policy` header rather than a
53
+ * header the middleware had to be told to set.** Next's documented pattern for
54
+ * nonces is middleware that generates one, puts it in the outgoing CSP, and
55
+ * forwards it on a custom request header — and the name of that custom header is
56
+ * the application's choice. Depending on it would make this work only for people
57
+ * who picked the same name we did, and fail silently for everybody else: the tag
58
+ * loads without a nonce, the browser drops it, and no tours run for a reason
59
+ * nothing reports.
60
+ *
61
+ * The CSP header itself is not a matter of taste. If the middleware set a nonce,
62
+ * it is in there, spelled `'nonce-…'`, because that is what makes the policy
63
+ * work at all.
64
+ *
65
+ * Returns undefined for a policy without one, which is correct rather than a
66
+ * fallback: a page with no nonce directive does not need the attribute, and
67
+ * inventing one would produce a tag that *every* policy refuses.
68
+ */
69
+ declare function readNonce(csp: string | null | undefined): string | undefined;
70
+
71
+ export { Guideify, type GuideifyProps, readNonce };
@@ -0,0 +1,71 @@
1
+ import { SnippetOptions } from '@guideify/react';
2
+ export { DEFAULT_CDN, GuideifyApi, GuideifyEvent, GuideifyTarget, GuideifyTargetProps, SnippetOptions, Unsubscribe, useGuideify } from '@guideify/react';
3
+ import { ReactNode } from 'react';
4
+
5
+ interface GuideifyProps extends Omit<SnippetOptions, 'nonce'> {
6
+ /**
7
+ * Supply it to override what the request's CSP says. Rarely needed — the
8
+ * point of this component is not having to.
9
+ */
10
+ nonce?: string | undefined;
11
+ children: ReactNode;
12
+ }
13
+ /**
14
+ * Guideify for the App Router — F-06, BUILD_REPORT §6.4.
15
+ *
16
+ * ```tsx
17
+ * // app/layout.tsx
18
+ * import { Guideify } from '@guideify/next';
19
+ *
20
+ * export default function RootLayout({ children }: { children: React.ReactNode }) {
21
+ * return (
22
+ * <html>
23
+ * <body>
24
+ * <Guideify apiKey={process.env.NEXT_PUBLIC_GUIDEIFY_KEY!}>{children}</Guideify>
25
+ * </body>
26
+ * </html>
27
+ * );
28
+ * }
29
+ * ```
30
+ *
31
+ * **A server component wrapping a client one, and that split is the whole
32
+ * package.** `GuideifyProvider` is `'use client'` and works in a Next app
33
+ * unchanged; what it cannot do is read the request, and the CSP nonce only
34
+ * exists there. So this reads the nonce on the server and hands it down — the
35
+ * one thing an App Router application genuinely needs that plain React cannot
36
+ * give it.
37
+ *
38
+ * Without it the failure is silent in the way that costs the most: a page served
39
+ * with `script-src 'nonce-…'` drops the injected tag, no tours run, and nothing
40
+ * in the customer's console names us.
41
+ *
42
+ * `headers()` is awaited, which opts the tree into dynamic rendering. That is
43
+ * unavoidable and not incidental — a nonce is per-request by definition, and a
44
+ * statically rendered page that baked one in would serve a stale nonce every
45
+ * policy refuses.
46
+ */
47
+ declare function Guideify({ children, nonce, ...options }: GuideifyProps): Promise<ReactNode>;
48
+
49
+ /**
50
+ * The CSP nonce for this request, or undefined when the app does not use one.
51
+ *
52
+ * **Reads the request's own `content-security-policy` header rather than a
53
+ * header the middleware had to be told to set.** Next's documented pattern for
54
+ * nonces is middleware that generates one, puts it in the outgoing CSP, and
55
+ * forwards it on a custom request header — and the name of that custom header is
56
+ * the application's choice. Depending on it would make this work only for people
57
+ * who picked the same name we did, and fail silently for everybody else: the tag
58
+ * loads without a nonce, the browser drops it, and no tours run for a reason
59
+ * nothing reports.
60
+ *
61
+ * The CSP header itself is not a matter of taste. If the middleware set a nonce,
62
+ * it is in there, spelled `'nonce-…'`, because that is what makes the policy
63
+ * work at all.
64
+ *
65
+ * Returns undefined for a policy without one, which is correct rather than a
66
+ * fallback: a page with no nonce directive does not need the attribute, and
67
+ * inventing one would produce a tag that *every* policy refuses.
68
+ */
69
+ declare function readNonce(csp: string | null | undefined): string | undefined;
70
+
71
+ export { Guideify, type GuideifyProps, readNonce };
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ import { GuideifyProvider } from '@guideify/react';
2
+ export { DEFAULT_CDN, GuideifyTarget, useGuideify } from '@guideify/react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ // src/index.ts
6
+
7
+ // src/nonce.ts
8
+ function readNonce(csp) {
9
+ if (!csp) return void 0;
10
+ const match = csp.match(/'nonce-([^']+)'/);
11
+ return match?.[1];
12
+ }
13
+ async function Guideify({ children, nonce, ...options }) {
14
+ const resolved = nonce ?? await requestNonce();
15
+ return /* @__PURE__ */ jsx(GuideifyProvider, { ...options, nonce: resolved, children });
16
+ }
17
+ async function requestNonce() {
18
+ const { headers } = await import('next/headers');
19
+ const store = await headers();
20
+ return readNonce(store.get("content-security-policy"));
21
+ }
22
+
23
+ export { Guideify, readNonce };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@guideify/next",
3
+ "version": "0.1.0",
4
+ "license": "SEE LICENSE IN LICENSE",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "dev": "tsup --watch",
22
+ "typecheck": "tsc --noEmit",
23
+ "test": "node --test \"test/*.test.mjs\"",
24
+ "verify": "npm run typecheck && npm run build && npm run test",
25
+ "verify:package": "node ../../scripts/verify-package.mjs next",
26
+ "prepublishOnly": "npm run verify && npm run verify:package"
27
+ },
28
+ "dependencies": {
29
+ "@guideify/react": "^0.1.0"
30
+ },
31
+ "peerDependencies": {
32
+ "next": ">=14",
33
+ "react": ">=18"
34
+ },
35
+ "devDependencies": {
36
+ "@types/react": "^19.2.0",
37
+ "next": "^16.3.1",
38
+ "react": "^19.2.8",
39
+ "tsup": "^8.5.0",
40
+ "typescript": "^5.7.3"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/vikasOzark/guidely.git",
48
+ "directory": "packages/next"
49
+ }
50
+ }