-
Notifications
You must be signed in to change notification settings - Fork 767
feat: add config builder #14226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
feat: add config builder #14226
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8686e21
feat: add interactive config builder to JS SDK docs
sarahxsanders a206063
update to project token + defaults
sarahxsanders 85cb6dc
style guide + component README
sarahxsanders 65927c6
Merge branch 'master' into config-builder
sarahxsanders e63892c
scroll nit
sarahxsanders 5c0a2d4
feedback
sarahxsanders 36852ed
Merge branch 'master' into config-builder
willwearing File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
162 changes: 162 additions & 0 deletions
162
contents/docs/libraries/js/_snippets/JSConfigBuilder.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| import React from 'react' | ||
| import { ConfigBuilder, ConfigState } from 'components/Docs/ConfigBuilder' | ||
|
|
||
| const generateCode = (config: ConfigState): string => { | ||
| const { selectedValue, checkboxes, inputs } = config | ||
| const apiKey = inputs.apiKey as string | ||
| const apiHost = selectedValue === 'eu-cloud' ? 'https://eu.i.posthog.com' : 'https://us.i.posthog.com' | ||
|
|
||
| const configLines: string[] = [] | ||
| configLines.push(` api_host: '${apiHost}',`) | ||
|
|
||
| if (checkboxes.useDefaults) configLines.push(` defaults: '<ph_posthog_js_defaults>',`) | ||
| if (!checkboxes.enableAutocapture) configLines.push(` autocapture: false,`) | ||
| if (checkboxes.spaMode) configLines.push(` capture_pageview: 'history_change',`) | ||
| if (!checkboxes.enableSessionRecording) configLines.push(` disable_session_recording: true,`) | ||
| if (checkboxes.recordConsoleLogs) configLines.push(` enable_recording_console_log: true,`) | ||
| if (checkboxes.enableHeatmaps) configLines.push(` enable_heatmaps: true,`) | ||
| if (!checkboxes.enableSurveys) configLines.push(` disable_surveys: true,`) | ||
| if (checkboxes.maskAllText) configLines.push(` mask_all_text: true,`) | ||
| if (checkboxes.maskAllAttributes) configLines.push(` mask_all_element_attributes: true,`) | ||
| if (checkboxes.optOutByDefault) configLines.push(` opt_out_capturing_by_default: true,`) | ||
|
|
||
| const persistence = inputs.persistence as string | ||
| if (persistence && persistence !== 'localStorage+cookie') { | ||
| configLines.push(` persistence: '${persistence}',`) | ||
| } | ||
|
|
||
| if (!checkboxes.crossSubdomainCookie) configLines.push(` cross_subdomain_cookie: false,`) | ||
| if (checkboxes.secureCookie) configLines.push(` secure_cookie: true,`) | ||
| if (checkboxes.alwaysCreateProfiles) configLines.push(` person_profiles: 'always',`) | ||
|
|
||
| return `posthog.init('${apiKey}', {\n${configLines.join('\n')}\n})` | ||
| } | ||
|
|
||
| const getFilename = (): string => 'posthog-init.js' | ||
| const getLanguage = (): string => 'javascript' | ||
|
|
||
| export const JSConfigBuilder: React.FC = () => { | ||
| return ( | ||
| <ConfigBuilder | ||
| toggle={{ | ||
| label: 'Where is PostHog hosted?', | ||
| options: [ | ||
| { value: 'us-cloud', label: 'US Cloud' }, | ||
| { value: 'eu-cloud', label: 'EU Cloud' }, | ||
| ], | ||
| defaultValue: 'us-cloud', | ||
| }} | ||
| checkboxes={[ | ||
| { | ||
| id: 'useDefaults', | ||
| label: 'Use recommended defaults', | ||
| description: 'Sets defaults to the latest recommended behaviors', | ||
| defaultValue: false, | ||
| }, | ||
| { | ||
| id: 'enableAutocapture', | ||
| label: 'Enable autocapture', | ||
| description: 'Automatically capture clicks, form submissions, and other interactions', | ||
| defaultValue: true, | ||
| }, | ||
| { | ||
| id: 'spaMode', | ||
| label: 'Single-page app (SPA)', | ||
| description: 'Detect page changes via history API instead of page loads', | ||
| defaultValue: false, | ||
| }, | ||
| { | ||
| id: 'enableSessionRecording', | ||
| label: 'Enable session recording', | ||
| description: 'Record user sessions for replay', | ||
| defaultValue: true, | ||
| }, | ||
| { | ||
| id: 'recordConsoleLogs', | ||
| label: 'Record console logs', | ||
| description: 'Include browser console logs in session recordings', | ||
| defaultValue: false, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'enableHeatmaps', | ||
| label: 'Enable heatmaps', | ||
| description: 'Capture click positions for heatmap visualizations', | ||
| defaultValue: false, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'enableSurveys', | ||
| label: 'Enable surveys', | ||
| description: 'Load the surveys script to show surveys to users', | ||
| defaultValue: true, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'maskAllText', | ||
| label: 'Mask all text (privacy)', | ||
| description: 'Replace all text content with asterisks in autocapture and recordings', | ||
| defaultValue: false, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'maskAllAttributes', | ||
| label: 'Mask all element attributes (privacy)', | ||
| description: 'Remove all element attributes from autocapture data', | ||
| defaultValue: false, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'optOutByDefault', | ||
| label: 'Opt users out by default (GDPR)', | ||
| description: 'Require explicit opt-in before tracking', | ||
| defaultValue: false, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'crossSubdomainCookie', | ||
| label: 'Cross-subdomain cookies', | ||
| description: 'Share identity across subdomains (enabled by default)', | ||
| defaultValue: true, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'secureCookie', | ||
| label: 'Secure cookies only (HTTPS)', | ||
| description: 'Only send cookies over HTTPS connections', | ||
| defaultValue: false, | ||
| group: 'advanced', | ||
| }, | ||
| { | ||
| id: 'alwaysCreateProfiles', | ||
| label: 'Always create person profiles', | ||
| description: 'Create profiles for all users, not just identified ones (identified_only by default)', | ||
| defaultValue: false, | ||
| group: 'advanced', | ||
| }, | ||
| ]} | ||
| inputs={[ | ||
| { | ||
| id: 'apiKey', | ||
| label: 'Project token', | ||
| type: 'text', | ||
| defaultValue: '<ph_project_token>', | ||
| }, | ||
| { | ||
| id: 'persistence', | ||
| label: 'Persistence method', | ||
| description: 'How to store user identity', | ||
| type: 'text', | ||
| placeholder: 'localStorage+cookie (default)', | ||
| defaultValue: '', | ||
| group: 'advanced', | ||
| }, | ||
| ]} | ||
| generateCode={generateCode} | ||
| getFilename={getFilename} | ||
| getLanguage={getLanguage} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| export default JSConfigBuilder |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| # ConfigBuilder | ||
|
|
||
| A reusable, two-panel interactive configuration builder for SDK docs pages. Users toggle options on the left and see generated code update live on the right. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```tsx | ||
| import { ConfigBuilder } from 'components/Docs/ConfigBuilder' | ||
|
|
||
| <ConfigBuilder | ||
| toggle={{ label: 'Region', options: [{ value: 'us', label: 'US' }, { value: 'eu', label: 'EU' }] }} | ||
| checkboxes={[{ id: 'feature', label: 'Enable feature', defaultValue: true }]} | ||
| inputs={[{ id: 'token', label: 'Token', type: 'text', defaultValue: '<ph_project_token>' }]} | ||
| generateCode={(config) => `init('${config.inputs.token}', { ... })`} | ||
| getFilename={() => 'init.js'} | ||
| getLanguage={() => 'javascript'} | ||
| /> | ||
| ``` | ||
|
|
||
| ## Props | ||
|
|
||
| | Prop | Type | Description | | ||
| |---|---|---| | ||
| | `toggle` | `{ label, options, defaultValue }` | Two-option toggle (e.g., US/EU Cloud) using RadixUI ToggleGroup | | ||
| | `select` | `{ label, options, defaultValue }` | Dropdown select for more than two options | | ||
| | `checkboxes` | `CheckboxOption[]` | Boolean config options. Supports `group: 'advanced'` to collapse under "Show advanced options" | | ||
| | `inputs` | `InputField[]` | Text, number, or `environment-list` inputs. Also supports `group: 'advanced'` | | ||
| | `generateCode` | `(config: ConfigState) => string` | Generates the code snippet from current config state | | ||
| | `getFilename` | `(selectedValue: string) => string` | Returns filename label for code block | | ||
| | `getLanguage` | `(selectedValue: string) => string` | Returns language for syntax highlighting | | ||
| | `optionsHeader` | `React.ReactNode` | Optional content above the config options | | ||
| | `previewHeader` | `string` | Label above the code preview (default: "Generated configuration") | | ||
|
|
||
| ## Placeholder auto-fill | ||
|
|
||
| The generated code renders inside `SingleCodeBlock`, which auto-replaces placeholders like `<ph_project_token>`, `<ph_client_api_host>`, and `<ph_posthog_js_defaults>` with the user's actual values (or latest defaults). Use these placeholders in `generateCode` and `defaultValue` fields. | ||
|
|
||
| ## Layout | ||
|
|
||
| - Uses `@container` queries (not media queries) per project guidelines | ||
| - Two-column grid at `@md` breakpoint, single column on narrow containers | ||
| - Left panel: scrollable config options | ||
| - Right panel: sticky code preview with reset button | ||
| - Checkbox descriptions hidden at `@md` to save space in two-column mode | ||
|
|
||
| ## Creating a new SDK config builder | ||
|
|
||
| 1. Create a file like `contents/docs/libraries/{sdk}/_snippets/{SDK}ConfigBuilder.tsx` | ||
| 2. Define `generateCode`, `getFilename`, `getLanguage` functions | ||
| 3. Pass SDK-specific checkboxes, inputs, and toggle/select options to `<ConfigBuilder />` | ||
| 4. Import and render in the SDK's config MDX page | ||
|
|
||
| See `contents/docs/libraries/js/_snippets/JSConfigBuilder.tsx` for a reference implementation. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.