@nuxt/scripts
Version:
Load third-party scripts with better performance, privacy and DX in Nuxt Apps.
187 lines (186 loc) • 8.48 kB
TypeScript
import type { ActiveHeadEntry, AsAsyncFunctionValues, DataKeys, SchemaAugmentations, ScriptBase } from '@unhead/schema';
import type { UseScriptInput, VueScriptInstance, UseScriptOptions } from '@unhead/vue';
import type { ComputedRef, Ref } from 'vue';
import type { InferInput, ObjectSchema } from 'valibot';
import type { Import } from 'unimport';
import type { SegmentInput } from './registry/segment.js';
import type { CloudflareWebAnalyticsInput } from './registry/cloudflare-web-analytics.js';
import type { MetaPixelInput } from './registry/meta-pixel.js';
import type { FathomAnalyticsInput } from './registry/fathom-analytics.js';
import type { HotjarInput } from './registry/hotjar.js';
import type { IntercomInput } from './registry/intercom.js';
import type { GoogleMapsInput } from './registry/google-maps.js';
import type { MatomoAnalyticsInput } from './registry/matomo-analytics.js';
import type { StripeInput } from './registry/stripe.js';
import type { VimeoPlayerInput } from './registry/vimeo-player.js';
import type { XPixelInput } from './registry/x-pixel.js';
import type { SnapTrPixelInput } from './registry/snapchat-pixel.js';
import type { YouTubePlayerInput } from './registry/youtube-player.js';
import type { PlausibleAnalyticsInput } from './registry/plausible-analytics.js';
import type { NpmInput } from './registry/npm.js';
import type { LemonSqueezyInput } from './registry/lemon-squeezy.js';
import type { GoogleAdsenseInput } from './registry/google-adsense.js';
import type { ClarityInput } from './registry/clarity.js';
import type { CrispInput } from './registry/crisp.js';
import type { GoogleAnalyticsInput } from './registry/google-analytics.js';
import type { GoogleTagManagerInput } from './registry/google-tag-manager.js';
import type { UmamiAnalyticsInput } from './registry/umami-analytics.js';
export type WarmupStrategy = false | 'preload' | 'preconnect' | 'dns-prefetch';
export type UseScriptContext<T extends Record<symbol | string, any>> = (Promise<T> & VueScriptInstance<T>) & AsAsyncFunctionValues<T> & {
/**
* @deprecated Use top-level functions instead.
*/
$script: Promise<T> & VueScriptInstance<T>;
warmup: (rel: WarmupStrategy) => void;
_warmupEl?: void | ActiveHeadEntry<any>;
};
export type NuxtUseScriptOptions<T extends Record<symbol | string, any> = {}> = Omit<UseScriptOptions<T>, 'trigger'> & {
/**
* The trigger to load the script:
* - `onNuxtReady` - Load the script when Nuxt is ready.
* - `manual` - Load the script manually by calling `load()`.
* - `Promise` - Load the script when the promise resolves.
*/
trigger?: UseScriptOptions<T>['trigger'] | 'onNuxtReady';
/**
* Should the script be bundled as an asset and loaded from your server. This is useful for improving the
* performance by avoiding the extra DNS lookup and reducing the number of requests. It also
* improves privacy by not sharing the user's IP address with third-party servers.
* - `true` - Bundle the script as an asset.
* - `false` - Do not bundle the script. (default)
*/
bundle?: boolean;
/**
* Skip any schema validation for the script input. This is useful for loading the script stubs for development without
* loading the actual script and not getting warnings.
*/
skipValidation?: boolean;
/**
* Specify a strategy for warming up the connection to the third-party script.
*
* The strategy to use for preloading the script.
* - `false` - Disable preloading.
* - `'preload'` - Preload the script.
* - `'preconnect'` | `'dns-prefetch'` - Preconnect to the script. Only works when loading a script from a different origin, will fallback
* to `false` if the origin is the same.
*/
warmupStrategy?: WarmupStrategy;
/**
* @internal
*/
performanceMarkFeature?: string;
/**
* @internal
*/
devtools?: {
/**
* Key used to map to the registry script for Nuxt DevTools.
* @internal
*/
registryKey?: string;
/**
* Extra metadata to show with the registry script
* @internal
*/
registryMeta?: Record<string, string>;
};
};
export type NuxtUseScriptOptionsSerializable = Omit<NuxtUseScriptOptions, 'use' | 'skipValidation' | 'stub' | 'trigger' | 'eventContext' | 'beforeInit'> & {
trigger?: 'client' | 'server' | 'onNuxtReady';
};
export type NuxtUseScriptInput = UseScriptInput;
export interface TrackedPage {
title?: string;
path: string;
}
type ExcludePromises<T> = T extends Promise<any> ? never : T;
export interface ConsentScriptTriggerOptions {
/**
* An optional reactive (or promise) reference to the consent state. You can use this to accept the consent for scripts
* instead of using the accept() method.
*/
consent?: Promise<boolean | void> | Ref<boolean> | ComputedRef<boolean> | boolean;
/**
* Should the script be loaded on the `requestIdleCallback` callback. This is useful for non-essential scripts that
* have already been consented to be loaded.
*/
postConsentTrigger?: ExcludePromises<NuxtUseScriptOptions['trigger']> | (() => Promise<any>);
}
export interface NuxtDevToolsScriptInstance {
registryKey?: string;
registryMeta?: Record<string, string>;
src: string;
$script: VueScriptInstance<any>;
events: {
type: string;
fn?: string | symbol;
args?: any;
status?: string;
trigger?: NuxtUseScriptOptions['trigger'];
at: number;
}[];
}
export interface ScriptRegistry {
crisp?: CrispInput;
clarity?: ClarityInput;
cloudflareWebAnalytics?: CloudflareWebAnalyticsInput;
metaPixel?: MetaPixelInput;
fathomAnalytics?: FathomAnalyticsInput;
plausibleAnalytics?: PlausibleAnalyticsInput;
googleAdsense?: GoogleAdsenseInput;
googleAnalytics?: GoogleAnalyticsInput;
googleMaps?: GoogleMapsInput;
lemonSqueezy?: LemonSqueezyInput;
googleTagManager?: GoogleTagManagerInput;
hotjar?: HotjarInput;
intercom?: IntercomInput;
matomoAnalytics?: MatomoAnalyticsInput;
segment?: SegmentInput;
stripe?: StripeInput;
xPixel?: XPixelInput;
snapchatPixel?: SnapTrPixelInput;
youtubePlayer?: YouTubePlayerInput;
vimeoPlayer?: VimeoPlayerInput;
umamiAnalytics?: UmamiAnalyticsInput;
[key: `${string}-npm`]: NpmInput;
}
export type NuxtConfigScriptRegistryEntry<T> = true | 'mock' | T | [T, NuxtUseScriptOptionsSerializable];
export type NuxtConfigScriptRegistry<T extends keyof ScriptRegistry = keyof ScriptRegistry> = Partial<{
[key in T]: NuxtConfigScriptRegistryEntry<ScriptRegistry[key]>;
}>;
export type UseFunctionType<T, U> = T extends {
use: infer V;
} ? V extends (...args: any) => any ? ReturnType<V> : U : U;
declare const _emptyOptions: ObjectSchema<{}, undefined>;
export type EmptyOptionsSchema = typeof _emptyOptions;
type ScriptInput = ScriptBase & DataKeys & SchemaAugmentations['script'];
export type InferIfSchema<T> = T extends ObjectSchema<any, any> ? InferInput<T> : T;
export type RegistryScriptInput<T = EmptyOptionsSchema, Bundelable extends boolean = true, Usable extends boolean = false, CanBypassOptions extends boolean = true> = (InferIfSchema<T> & {
/**
* A unique key to use for the script, this can be used to load multiple of the same script with different options.
*/
key?: string;
scriptInput?: ScriptInput;
scriptOptions?: Omit<NuxtUseScriptOptions, Bundelable extends true ? '' : 'bundle' | Usable extends true ? '' : 'use'>;
}) | Partial<InferIfSchema<T>> & (CanBypassOptions extends true ? {
/**
* A unique key to use for the script, this can be used to load multiple of the same script with different options.
*/
key?: string;
scriptInput: Required<Pick<ScriptInput, 'src'>> & ScriptInput;
scriptOptions?: Omit<NuxtUseScriptOptions, Bundelable extends true ? '' : 'bundle' | Usable extends true ? '' : 'use'>;
} : never);
export interface RegistryScript {
import?: Import;
scriptBundling?: false | ((options?: any) => string | false);
label?: string;
src?: string | false;
category?: string;
logo?: string | {
light: string;
dark: string;
};
}
export type ElementScriptTrigger = 'immediate' | 'visible' | string | string[] | false;
export type RegistryScripts = RegistryScript[];
export {};