From 4376416e446abc94e986b744f2a82429cc70d2e5 Mon Sep 17 00:00:00 2001 From: harlan Date: Fri, 19 Apr 2024 17:52:16 +1000 Subject: [PATCH] progress commit --- package.json | 1 + pnpm-lock.yaml | 12 +++++-- src/runtime/components/GoogleMaps.ts | 2 +- src/runtime/components/YoutubeEmbed.ts | 38 -------------------- src/runtime/components/YoutubeEmbed.vue | 41 ++++++++++++++++++++++ src/runtime/registry/google-analytics.ts | 39 ++++++++++++-------- src/runtime/registry/google-maps.ts | 15 ++++---- src/runtime/registry/google-tag-manager.ts | 33 ++++++++++------- 8 files changed, 105 insertions(+), 76 deletions(-) delete mode 100644 src/runtime/components/YoutubeEmbed.ts create mode 100644 src/runtime/components/YoutubeEmbed.vue diff --git a/package.json b/package.json index f5e4d44f..e5d11778 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "shiki": "^1.3.0", "sirv": "^2.0.4", "std-env": "^3.7.0", + "third-party-capital": "^1.0.28", "ufo": "^1.5.3", "unimport": "^3.7.1", "unplugin": "^1.10.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e8c3a13..d5b2879f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ importers: std-env: specifier: ^3.7.0 version: 3.7.0 + third-party-capital: + specifier: ^1.0.28 + version: 1.0.28 ufo: specifier: ^1.5.3 version: 1.5.3 @@ -6007,6 +6010,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + third-party-capital@1.0.28: + resolution: {integrity: sha512-FfO+e4ABQYeZ7j2FalaYavyj/Ms17e/9sh63HBwg6GpW0BNygyPYAVk1x5glL1JL7yrqg2qSeRBMT/CqO6d1lw==} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -13224,7 +13230,7 @@ snapshots: '@nuxt/vite-builder': 3.11.2(@types/node@20.12.7)(eslint@9.0.0)(optionator@0.9.3)(rollup@4.14.3)(sass@1.75.0)(terser@5.30.3)(typescript@5.4.5)(vue@3.4.23(typescript@5.4.5)) '@unhead/dom': 1.9.5 '@unhead/ssr': 1.9.5 - '@unhead/vue': 1.9.7(vue@3.4.23(typescript@5.4.5)) + '@unhead/vue': 1.9.6(vue@3.4.23(typescript@5.4.5)) '@vue/shared': 3.4.23 acorn: 8.11.3 c12: 1.10.0 @@ -13340,7 +13346,7 @@ snapshots: '@nuxt/vite-builder': 3.11.2(@types/node@20.12.7)(eslint@9.0.0)(optionator@0.9.3)(rollup@4.14.3)(sass@1.75.0)(terser@5.30.3)(typescript@5.4.5)(vue@3.4.23(typescript@5.4.5)) '@unhead/dom': 1.9.5 '@unhead/ssr': 1.9.5 - '@unhead/vue': 1.9.7(vue@3.4.23(typescript@5.4.5)) + '@unhead/vue': 1.9.6(vue@3.4.23(typescript@5.4.5)) '@vue/shared': 3.4.23 acorn: 8.11.3 c12: 1.10.0 @@ -14918,6 +14924,8 @@ snapshots: dependencies: any-promise: 1.3.0 + third-party-capital@1.0.28: {} + through@2.3.8: {} tiny-inflate@1.0.3: {} diff --git a/src/runtime/components/GoogleMaps.ts b/src/runtime/components/GoogleMaps.ts index 3a0be24e..aea796e8 100644 --- a/src/runtime/components/GoogleMaps.ts +++ b/src/runtime/components/GoogleMaps.ts @@ -2,7 +2,7 @@ import type { PropType, Ref } from 'vue' import { defineComponent, h, ref, watch } from 'vue' import type google from 'google.maps' import { formatDimensionValue } from '../util' -import { useScriptGoogleMaps } from '../composables/googleMaps' +import { useScriptGoogleMaps } from '#imports' interface LatLng { lat: number diff --git a/src/runtime/components/YoutubeEmbed.ts b/src/runtime/components/YoutubeEmbed.ts deleted file mode 100644 index 15d37427..00000000 --- a/src/runtime/components/YoutubeEmbed.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { defineComponent, h, ref, watch } from 'vue' -import * as tpc from 'third-party-capital' -import { convertThirdPartyCapital, formatDimensionValue } from '../util' -import { useHead, useScript } from '#imports' - -/** - * YoutubeEmbed - * - * A 3P wrapper component that takes the props to feed into third-party-capital({@link https://github.com/GoogleChromeLabs/third-party-capital}), which returns data to define and build the component. - */ -const YoutubeEmbed = defineComponent({ - name: 'YoutubeEmbed', - props: { - videoId: { type: String, required: true }, - playLabel: { type: String, required: true }, - width: { type: String, required: false, default: '100%' }, - height: { type: String, required: false, default: '100%' }, - params: { type: String, required: false, default: undefined }, - }, - async setup(props) { - const ytRef = ref(tpc.YouTubeEmbed({ videoid: props.videoId, playlabel: props.playLabel })) - - if (import.meta.client) - watch(props, () => ytRef.value = tpc.YouTubeEmbed({ videoid: props.videoId, playlabel: props.playLabel })) - - const { useHeadInput, useScriptInput } = convertThirdPartyCapital('lite-yt-embed', ytRef.value) - useScript(useScriptInput, { - beforeInit: () => useHead(useHeadInput), - }) - - return () => h('div', { class: 'lite-youtube-container', innerHTML: ytRef.value.html, style: { - width: formatDimensionValue(props.width), - height: formatDimensionValue(props.height), - } }) - }, -}) - -export default YoutubeEmbed diff --git a/src/runtime/components/YoutubeEmbed.vue b/src/runtime/components/YoutubeEmbed.vue new file mode 100644 index 00000000..108e4584 --- /dev/null +++ b/src/runtime/components/YoutubeEmbed.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/runtime/registry/google-analytics.ts b/src/runtime/registry/google-analytics.ts index f8358384..90e88c81 100644 --- a/src/runtime/registry/google-analytics.ts +++ b/src/runtime/registry/google-analytics.ts @@ -1,7 +1,8 @@ import type { GoogleAnalyticsApi } from 'third-party-capital' import { object, string } from 'valibot' import type { NuxtUseScriptOptions, ScriptDynamicSrcInput } from '#nuxt-scripts' -import { useScript, validateScriptInputSchema } from '#imports' +import { useScript } from '#imports' +import { registryScriptOptions } from '~/src/runtime/utils' const GoogleAnalyticsOptions = object({ id: string(), @@ -18,25 +19,33 @@ declare global { * * A 3P wrapper for Google Analytics that takes an options input to feed into third-party-capital({@link https://github.com/GoogleChromeLabs/third-party-capital}), which returns instructions for nuxt-scripts. */ -export function useScriptGoogleAnalytics(options?: GoogleAnalyticsInput, _scriptOptions?: Omit, 'beforeInit' | 'use'>) { - const scriptOptions: NuxtUseScriptOptions = _scriptOptions || {} - scriptOptions.beforeInit = () => { - import.meta.dev && validateScriptInputSchema(GoogleAnalyticsOptions, options) - if (import.meta.client) { - window.dataLayer = window.dataLayer || [] - window.gtag = function gtag(...p) { - window.dataLayer.push(p) - } - window.gtag('js', new Date()) - window.gtag('config', options.id) - } - } +export function useScriptGoogleAnalytics(options?: GoogleAnalyticsInput, scriptOptions?: Omit, 'beforeInit' | 'use'>) { // Note: inputs.useScriptInput is not usable, needs to be normalized return useScript({ key: 'googleAnalytics', src: 'https://www.googletagmanager.com/gtag/js', }, { - ...scriptOptions, + ...registryScriptOptions({ + scriptOptions, + schema: GoogleAnalyticsOptions, + options, + clientInit: import.meta.server + ? undefined + : () => { + window.dataLayer = window.dataLayer || [] + window.gtag = function gtag(...p) { + window.dataLayer.push(p) + } + window.gtag('js', new Date()) + window.gtag('config', options.id) + }, + }), + // allow dataLayer to be accessed on the server + stub: import.meta.client + ? undefined + : ({ fn }) => { + return fn === 'dataLayer' ? [] : undefined + }, use: () => ({ dataLayer: window.dataLayer, gtag: window.gtag }), }) } diff --git a/src/runtime/registry/google-maps.ts b/src/runtime/registry/google-maps.ts index 6329f059..3149e3fa 100644 --- a/src/runtime/registry/google-maps.ts +++ b/src/runtime/registry/google-maps.ts @@ -3,7 +3,8 @@ import { array, object, optional, string } from 'valibot' import type google from 'google.maps' import { withQuery } from 'ufo' import type { NuxtUseScriptOptions, ScriptDynamicSrcInput } from '#nuxt-scripts' -import { useScript, validateScriptInputSchema } from '#imports' +import { useScript } from '#imports' +import { registryScriptOptions } from '~/src/runtime/utils' export const GoogleMapsOptions = object({ apiKey: string(), @@ -25,11 +26,7 @@ declare global { * * A 3P wrapper to load the Google Maps JavaScript api. */ -export function useScriptGoogleMaps(options?: Input, _scriptOptions?: Omit, 'beforeInit' | 'use'>) { - const scriptOptions: NuxtUseScriptOptions = _scriptOptions || {} - scriptOptions.beforeInit = () => { - import.meta.dev && validateScriptInputSchema(GoogleMapsOptions, options) - } +export function useScriptGoogleMaps(options?: Input, scriptOptions?: Omit, 'beforeInit' | 'use'>) { const libraries = options?.libraries || ['places'] return useScript({ key: 'googleMaps', @@ -38,7 +35,11 @@ export function useScriptGoogleMaps(options?: Input ({ maps: window.google.maps }), }) } diff --git a/src/runtime/registry/google-tag-manager.ts b/src/runtime/registry/google-tag-manager.ts index d09ec14c..2a40f70b 100644 --- a/src/runtime/registry/google-tag-manager.ts +++ b/src/runtime/registry/google-tag-manager.ts @@ -1,7 +1,7 @@ import type { GoogleTagManagerApi } from 'third-party-capital' import { object, string } from 'valibot' - -import { useScript, validateScriptInputSchema } from '#imports' +import { registryScriptOptions } from '../utils' +import { useScript } from '#imports' import type { NuxtUseScriptOptions, ScriptDynamicSrcInput } from '#nuxt-scripts' const GoogleTagManagerOptions = object({ @@ -19,22 +19,29 @@ declare global { * * A 3P wrapper for Google Tag Manager that takes an options input to feed into third-party-capital({@link https://github.com/GoogleChromeLabs/third-party-capital}), which returns instructions for nuxt-scripts. */ -export function useScriptGoogleTagManager(options?: GoogleTagManagerInput, _scriptOptions?: Omit, 'beforeInit' | 'use'>) { - const scriptOptions: NuxtUseScriptOptions = _scriptOptions || {} - scriptOptions.beforeInit = () => { - import.meta.dev && validateScriptInputSchema(GoogleTagManagerOptions, options) - if (import.meta.client) { - window.dataLayer = window.dataLayer || [] - window.dataLayer.push({ 'gtm.start': new Date().getTime(), 'event': 'gtm.js' }) - } - } - // Note: inputs.useScriptInput is not usable, needs to be normalized +export function useScriptGoogleTagManager(options?: GoogleTagManagerInput, scriptOptions?: Omit, 'beforeInit' | 'use'>) { return useScript({ // need static sources so they can be transformed key: 'googleTagManager', src: 'https://www.googletagmanager.com/gtm.js', }, { - ...scriptOptions, + ...registryScriptOptions({ + scriptOptions, + schema: GoogleTagManagerOptions, + options, + clientInit: import.meta.server + ? undefined + : () => { + window.dataLayer = window.dataLayer || [] + window.dataLayer.push({ 'gtm.start': new Date().getTime(), 'event': 'gtm.js' }) + }, + }), + // allow dataLayer to be accessed on the server + stub: import.meta.client + ? undefined + : ({ fn }) => { + return fn === 'dataLayer' ? [] : undefined + }, use: () => ({ dataLayer: window.dataLayer, google_tag_manager: window.google_tag_manager }), }) }