diff --git a/integrations/visitor-claims-webframe-demo/README.md b/integrations/visitor-claims-webframe-demo/README.md new file mode 100644 index 000000000..b2f37119d --- /dev/null +++ b/integrations/visitor-claims-webframe-demo/README.md @@ -0,0 +1,22 @@ +# Visitor Claims Webframe Demo + +Dev/test integration for validating that GitBook/GBX passes adaptive visitor context into ContentKit webframes. + +The integration exposes one block, `visitorClaimsWebframeDemo`, which renders a self-contained webframe at `/webframe`. The webframe displays: + +- The full posted ContentKit webframe state. +- `state.visitor`. +- `state.visitor.claims`. +- `state.visitor.isSet`. +- Regular webframe `data` values, including `label` and `mode`, as part of the full state. + +## Test + +1. Enable and configure adaptive content for the target site/space. +2. Install this integration in the target space. +3. Add the **Visitor Claims Demo** integration block to a space page. +4. Set visitor input/test values in the GitBook UI. +5. Confirm the webframe displays `visitor.claims` and `visitor.isSet`. +6. Open the browser console and check the `visitor-claims-webframe-demo: received state` log for the raw state object. + +If the webframe receives state without visitor context, it shows `No visitor context received.` while still rendering the full state JSON for debugging. diff --git a/integrations/visitor-claims-webframe-demo/assets/icon.png b/integrations/visitor-claims-webframe-demo/assets/icon.png new file mode 100644 index 000000000..3ceb32a6a Binary files /dev/null and b/integrations/visitor-claims-webframe-demo/assets/icon.png differ diff --git a/integrations/visitor-claims-webframe-demo/gitbook-manifest.yaml b/integrations/visitor-claims-webframe-demo/gitbook-manifest.yaml new file mode 100644 index 000000000..8bf0801f4 --- /dev/null +++ b/integrations/visitor-claims-webframe-demo/gitbook-manifest.yaml @@ -0,0 +1,20 @@ +name: visitor-claims-webframe-demo +title: Visitor Claims Webframe Demo +icon: ./assets/icon.png +organization: QkobkeMSkvQjA19eKq3n +description: Dev/test integration for inspecting ContentKit webframe visitor context. +summary: | + # Overview + + This development-only integration renders a ContentKit webframe and displays the full state GitBook posts into it. + + # How it works + + Add the Visitor Claims Webframe Demo block to a space page. The webframe displays regular ContentKit webframe data alongside any visitor context injected by GitBook, including `visitor.claims` and `visitor.isSet`. +visibility: private +script: ./src/index.tsx +scopes: ['site:visitor:claims'] +blocks: + - id: visitorClaimsWebframeDemo + title: Visitor Claims Demo + description: Inspect visitor claims passed into a ContentKit webframe. diff --git a/integrations/visitor-claims-webframe-demo/package.json b/integrations/visitor-claims-webframe-demo/package.json new file mode 100644 index 000000000..7efedf29f --- /dev/null +++ b/integrations/visitor-claims-webframe-demo/package.json @@ -0,0 +1,21 @@ +{ + "name": "@gitbook/integration-visitor-claims-webframe-demo", + "version": "0.0.0", + "private": true, + "dependencies": { + "@gitbook/api": "*", + "@gitbook/runtime": "*", + "itty-router": "^2.6.1" + }, + "devDependencies": { + "@gitbook/cli": "workspace:*", + "@gitbook/tsconfig": "workspace:*" + }, + "scripts": { + "typecheck": "tsc --noEmit", + "check": "gitbook check", + "publish-integrations": "gitbook publish .", + "publish-integrations-staging": "gitbook publish .", + "dev": "gitbook dev ." + } +} diff --git a/integrations/visitor-claims-webframe-demo/src/index.tsx b/integrations/visitor-claims-webframe-demo/src/index.tsx new file mode 100644 index 000000000..12a7857be --- /dev/null +++ b/integrations/visitor-claims-webframe-demo/src/index.tsx @@ -0,0 +1,66 @@ +import { Router } from 'itty-router'; + +import { + createComponent, + createIntegration, + FetchEventCallback, + RuntimeContext, +} from '@gitbook/runtime'; + +import { webFrameHTML } from './webframe'; + +const visitorClaimsWebframeDemo = createComponent({ + componentId: 'visitorClaimsWebframeDemo', + async render(_element, { environment }) { + const webframeURL = new URL(`${environment.integration.urls.publicEndpoint}/webframe`); + webframeURL.searchParams.set('v', String(environment.integration.version)); + + return ( + + + + ); + }, +}); + +const handleFetchEvent: FetchEventCallback = async (request, context) => { + const { environment } = context; + const router = Router({ + base: new URL( + environment.spaceInstallation?.urls?.publicEndpoint || + environment.installation?.urls.publicEndpoint || + environment.integration.urls.publicEndpoint, + ).pathname, + }); + + router.get( + '/webframe', + async () => + new Response(webFrameHTML, { + headers: { + 'Content-Type': 'text/html; charset=utf-8', + 'Cache-Control': 'no-store', + }, + }), + ); + + const response = await router.handle(request, context); + if (!response) { + return new Response('No route matching', { status: 404 }); + } + + return response; +}; + +export default createIntegration({ + fetch: handleFetchEvent, + components: [visitorClaimsWebframeDemo], +}); diff --git a/integrations/visitor-claims-webframe-demo/src/webframe.ts b/integrations/visitor-claims-webframe-demo/src/webframe.ts new file mode 100644 index 000000000..6b8461d0e --- /dev/null +++ b/integrations/visitor-claims-webframe-demo/src/webframe.ts @@ -0,0 +1,215 @@ +export const webFrameHTML: string = ` + + + + + + + Visitor claims webframe demo + + + +
+
+

Visitor claims webframe demo

+
+ +
+

No webframe state received yet.

+
+ +
+

Full webframe state

+
{}
+
+ +
+
+

state.visitor

+
null
+
+
+ + +
+ + + + +`; diff --git a/integrations/visitor-claims-webframe-demo/tsconfig.json b/integrations/visitor-claims-webframe-demo/tsconfig.json new file mode 100644 index 000000000..1a48f875b --- /dev/null +++ b/integrations/visitor-claims-webframe-demo/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@gitbook/tsconfig/integration.json" +}