-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ph module * capture hubspot forms * global middleware for feature flags * fix types / change interval * small type fix * button capture for posthog * add types for pagebuilder * add experiment types * Add posthog to page * add posthog * fix url for posthog module * fix typage * fix url again * update module yet again * temp fixes * fix ui host behavior * new form logic * uncomment gtm * remove logs
- Loading branch information
1 parent
f88d2c4
commit 6f5c22c
Showing
26 changed files
with
676 additions
and
52 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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 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,21 @@ | ||
export default defineNuxtRouteMiddleware((to) => { | ||
const posthogFeatureFlagsPayload = useState<Record<string, boolean | string> | undefined>('ph-feature-flag-payloads'); | ||
|
||
if (!posthogFeatureFlagsPayload.value) return; | ||
|
||
// Clone the Vue proxy object to a plain object | ||
const flags = Object.values(JSON.parse(JSON.stringify(posthogFeatureFlagsPayload.value))); | ||
|
||
let redirectTo; | ||
|
||
flags.some((flag: any) => { | ||
if (flag.experiment_type === 'page' && to.path === flag.control_path && flag.control_path !== flag.path) { | ||
redirectTo = flag.path; | ||
return true; | ||
} | ||
}); | ||
|
||
if (redirectTo) { | ||
return navigateTo(redirectTo); | ||
} | ||
}); |
This file contains 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,108 @@ | ||
import { defineNuxtModule, addImports, addComponent, addPlugin, createResolver, addTypeTemplate } from '@nuxt/kit'; | ||
import type { PostHogConfig } from 'posthog-js'; | ||
import { defu } from 'defu'; | ||
|
||
export interface ModuleOptions { | ||
/** | ||
* The PostHog API key | ||
* @default process.env.POSTHOG_API_KEY | ||
* @example 'phc_1234567890abcdef1234567890abcdef1234567890a' | ||
* @type string | ||
* @docs https://posthog.com/docs/api | ||
*/ | ||
publicKey: string; | ||
|
||
/** | ||
* The PostHog API host | ||
* @default process.env.POSTHOG_API_HOST | ||
* @example 'https://app.posthog.com' | ||
* @type string | ||
* @docs https://posthog.com/docs/api | ||
*/ | ||
host: string; | ||
|
||
/** | ||
* If set to true, the module will capture page views automatically | ||
* @default true | ||
* @type boolean | ||
* @docs https://posthog.com/docs/product-analytics/capture-events#single-page-apps-and-pageviews | ||
*/ | ||
capturePageViews?: boolean; | ||
|
||
/** | ||
* PostHog Client options | ||
* @default { | ||
* api_host: process.env.POSTHOG_API_HOST, | ||
* loaded: () => <enable debug mode if in development> | ||
* } | ||
* @type object | ||
* @docs https://posthog.com/docs/libraries/js#config | ||
*/ | ||
clientOptions?: Partial<PostHogConfig>; | ||
|
||
/** | ||
* If set to true, the module will be disabled (no events will be sent to PostHog). | ||
* This is useful for development environments. Directives and components will still be available for you to use. | ||
* @default false | ||
* @type boolean | ||
*/ | ||
disabled?: boolean; | ||
} | ||
|
||
export default defineNuxtModule<ModuleOptions>({ | ||
meta: { | ||
name: 'nuxt-posthog', | ||
configKey: 'posthog', | ||
}, | ||
defaults: { | ||
publicKey: process.env.POSTHOG_API_KEY as string, | ||
host: process.env.POSTHOG_API_HOST as string, | ||
capturePageViews: true, | ||
disabled: false, | ||
}, | ||
setup(options, nuxt) { | ||
const { resolve } = createResolver(import.meta.url); | ||
|
||
// Public runtimeConfig | ||
nuxt.options.runtimeConfig.public.posthog = defu<ModuleOptions, ModuleOptions[]>( | ||
nuxt.options.runtimeConfig.public.posthog, | ||
{ | ||
publicKey: options.publicKey, | ||
host: options.host, | ||
capturePageViews: options.capturePageViews, | ||
clientOptions: options.clientOptions, | ||
disabled: options.disabled, | ||
}, | ||
); | ||
|
||
// Make sure url and key are set | ||
if (!nuxt.options.runtimeConfig.public.posthog.publicKey) { | ||
// eslint-disable-next-line no-console | ||
console.warn('Missing PostHog API public key, set it either in `nuxt.config.ts` or via env variable'); | ||
} | ||
|
||
if (!nuxt.options.runtimeConfig.public.posthog.host) { | ||
// eslint-disable-next-line no-console | ||
console.warn('Missing PostHog API host, set it either in `nuxt.config.ts` or via env variable'); | ||
} | ||
|
||
addPlugin(resolve('./runtime/plugins/directives')); | ||
addPlugin(resolve('./runtime/plugins/posthog.client')); | ||
addPlugin(resolve('./runtime/plugins/posthog.server')); | ||
|
||
addImports({ | ||
from: resolve('./runtime/composables/usePostHogFeatureFlag'), | ||
name: 'usePostHogFeatureFlag', | ||
}); | ||
|
||
addComponent({ | ||
filePath: resolve('./runtime/components/PostHogFeatureFlag.vue'), | ||
name: 'PostHogFeatureFlag', | ||
}); | ||
|
||
addTypeTemplate({ | ||
filename: 'types/posthog-directives.d.ts', | ||
src: resolve('./runtime/types/directives.d.ts'), | ||
}); | ||
}, | ||
}); |
This file contains 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,20 @@ | ||
<script setup lang="ts"> | ||
import { computed } from 'vue'; | ||
import usePostHogFeatureFlag from '../composables/usePostHogFeatureFlag'; | ||
const { name } = withDefaults( | ||
defineProps<{ | ||
name: string; | ||
match?: boolean | string; | ||
}>(), | ||
{ match: true }, | ||
); | ||
const { getFeatureFlag } = usePostHogFeatureFlag(); | ||
const featureFlag = computed(() => getFeatureFlag(name)); | ||
</script> | ||
|
||
<template> | ||
<slot v-if="featureFlag?.value === match" :payload="featureFlag.payload" /> | ||
</template> |
23 changes: 23 additions & 0 deletions
23
modules/posthog/runtime/composables/usePostHogFeatureFlag.ts
This file contains 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,23 @@ | ||
import { useState } from '#app'; | ||
import type { JsonType } from 'posthog-js'; | ||
|
||
export default () => { | ||
const posthogFeatureFlags = useState<Record<string, boolean | string> | undefined>('ph-feature-flags'); | ||
const posthogFeatureFlagPayloads = useState<Record<string, JsonType> | undefined>('ph-feature-flag-payloads'); | ||
|
||
const isFeatureEnabled = (feature: string) => { | ||
return posthogFeatureFlags.value?.[feature] ?? false; | ||
}; | ||
|
||
const getFeatureFlag = (feature: string) => { | ||
return { | ||
value: posthogFeatureFlags.value?.[feature] ?? false, | ||
payload: posthogFeatureFlagPayloads.value?.[feature], | ||
}; | ||
}; | ||
|
||
return { | ||
isFeatureEnabled, | ||
getFeatureFlag, | ||
}; | ||
}; |
This file contains 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,88 @@ | ||
import { useNuxtApp } from '#app'; | ||
import type { ObjectDirective, FunctionDirective, DirectiveBinding } from 'vue'; | ||
|
||
type CaptureEvent = { | ||
name: string; | ||
properties?: Record<string, any>; | ||
}; | ||
|
||
type CaptureModifiers = { | ||
click?: boolean; | ||
hover?: boolean; | ||
}; | ||
|
||
type EventHandler = { | ||
event: string; | ||
handler: (event: Event) => void; | ||
}; | ||
|
||
const listeners = new WeakMap<HTMLElement, EventHandler[]>(); | ||
|
||
const directive: FunctionDirective<HTMLElement, CaptureEvent | string> = ( | ||
el, | ||
binding: DirectiveBinding<CaptureEvent | string> & { modifiers: CaptureModifiers }, | ||
) => { | ||
const { value, modifiers } = binding; | ||
|
||
// Don't bind if the value is undefined | ||
if (!value) { | ||
return; | ||
} | ||
|
||
const { $posthog } = useNuxtApp(); | ||
|
||
function capture(_event: Event) { | ||
if (!$posthog) return; | ||
|
||
if (typeof value === 'string') { | ||
$posthog.capture(value); | ||
} else { | ||
$posthog.capture(value.name, value.properties); | ||
} | ||
} | ||
|
||
// Determine the events to listen for based on the modifiers | ||
const events: string[] = []; | ||
|
||
if (Object.keys(modifiers).length === 0) { | ||
// Default to click if no modifiers are specified | ||
events.push('click'); | ||
} else { | ||
if (modifiers.click) events.push('click'); | ||
if (modifiers.hover) events.push('mouseenter'); | ||
} | ||
|
||
// Remove existing event listeners | ||
if (listeners.has(el)) { | ||
const oldEvents = listeners.get(el) as EventHandler[]; | ||
|
||
oldEvents.forEach(({ event, handler }) => { | ||
el.removeEventListener(event, handler); | ||
}); | ||
} | ||
|
||
// Add new event listeners and store them | ||
const eventHandlers = events.map((event) => { | ||
const handler = capture.bind(null); | ||
el.addEventListener(event, handler); | ||
return { event, handler }; | ||
}); | ||
|
||
listeners.set(el, eventHandlers); | ||
}; | ||
|
||
export const vCapture: ObjectDirective = { | ||
mounted: directive, | ||
updated: directive, | ||
unmounted(el) { | ||
if (listeners.has(el)) { | ||
const eventHandlers = listeners.get(el) as EventHandler[]; | ||
|
||
eventHandlers.forEach(({ event, handler }) => { | ||
el.removeEventListener(event, handler); | ||
}); | ||
|
||
listeners.delete(el); | ||
} | ||
}, | ||
}; |
This file contains 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,6 @@ | ||
import { vCapture } from '../directives/v-capture'; | ||
import { defineNuxtPlugin } from '#app'; | ||
|
||
export default defineNuxtPlugin(({ vueApp }) => { | ||
vueApp.directive('capture', vCapture); | ||
}); |
Oops, something went wrong.