Skip to content

Commit

Permalink
refactor(ganalytics, gtag): move options out of themeConfig (#5832)
Browse files Browse the repository at this point in the history
* refactor(ganalytics, gtag): move options out of themeConfig

* Forbid themeConfig options

* Add PR link

* Add key names to error message

* Fix?

* Doc updates

Co-authored-by: Sébastien Lorber <[email protected]>
  • Loading branch information
Josh-Cena and slorber authored Nov 10, 2021
1 parent f5732e7 commit ac88d97
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 102 deletions.
10 changes: 5 additions & 5 deletions packages/docusaurus-module-type-aliases/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ declare module '@generated/site-metadata' {
import type {DocusaurusSiteMetadata} from '@docusaurus/types';

const siteMetadata: DocusaurusSiteMetadata;
export default siteMetadata;
export = siteMetadata;
}

declare module '@generated/registry' {
Expand All @@ -48,13 +48,13 @@ declare module '@generated/routes' {

declare module '@generated/routesChunkNames' {
const routesChunkNames: Record<string, Record<string, string>>;
export default routesChunkNames;
export = routesChunkNames;
}

declare module '@generated/globalData' {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const globalData: Record<string, any>;
export default globalData;
export = globalData;
}

declare module '@generated/i18n' {
Expand All @@ -64,12 +64,12 @@ declare module '@generated/i18n' {
currentLocale: string;
localeConfigs: Record<string, {label: string; direction: string}>;
};
export default i18n;
export = i18n;
}

declare module '@generated/codeTranslations' {
const codeTranslations: Record<string, string>;
export default codeTranslations;
export = codeTranslations;
}

declare module '@theme-original/*';
Expand Down
3 changes: 2 additions & 1 deletion packages/docusaurus-plugin-google-analytics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
},
"license": "MIT",
"dependencies": {
"@docusaurus/core": "2.0.0-beta.9"
"@docusaurus/core": "2.0.0-beta.9",
"@docusaurus/utils-validation": "2.0.0-beta.9"
},
"devDependencies": {
"@docusaurus/types": "2.0.0-beta.9"
Expand Down
62 changes: 39 additions & 23 deletions packages/docusaurus-plugin-google-analytics/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,23 @@
*/

import path from 'path';
import type {LoadContext, Plugin, HtmlTags} from '@docusaurus/types';
import type {ThemeConfig} from '@docusaurus/plugin-google-analytics';

export default function pluginGoogleAnalytics(context: LoadContext): Plugin {
const {
siteConfig: {themeConfig},
} = context;
const {googleAnalytics} = themeConfig as ThemeConfig;

if (!googleAnalytics) {
throw new Error(
`You need to specify "googleAnalytics" object in "themeConfig" with "trackingId" field in it to use docusaurus-plugin-google-analytics.`,
);
}

const {trackingID, anonymizeIP} = googleAnalytics;

if (!trackingID) {
throw new Error(
'You specified the "googleAnalytics" object in "themeConfig" but the "trackingID" field was missing. ' +
'Please ensure this is not a mistake.',
);
}
import {Joi} from '@docusaurus/utils-validation';
import type {
LoadContext,
Plugin,
HtmlTags,
OptionValidationContext,
ValidationResult,
ThemeConfig,
ThemeConfigValidationContext,
} from '@docusaurus/types';
import type {PluginOptions} from '@docusaurus/plugin-google-analytics';

export default function pluginGoogleAnalytics(
context: LoadContext,
options: PluginOptions,
): Plugin {
const {trackingID, anonymizeIP} = options;
const isProd = process.env.NODE_ENV === 'production';

return {
Expand Down Expand Up @@ -74,3 +67,26 @@ export default function pluginGoogleAnalytics(context: LoadContext): Plugin {
},
};
}

const pluginOptionsSchema = Joi.object<PluginOptions>({
trackingID: Joi.string().required(),
anonymizeIP: Joi.boolean().default(false),
});

export function validateOptions({
validate,
options,
}: OptionValidationContext<PluginOptions>): ValidationResult<PluginOptions> {
return validate(pluginOptionsSchema, options);
}

export function validateThemeConfig({
themeConfig,
}: ThemeConfigValidationContext<ThemeConfig>): ValidationResult<ThemeConfig> {
if (themeConfig.googleAnalytics) {
throw new Error(
'The "googleAnalytics" field in themeConfig should now be specified as option for plugin-google-analytics. More information at https://github.com/facebook/docusaurus/pull/5832.',
);
}
return themeConfig;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

export interface ThemeConfig {
googleAnalytics?: {
trackingID: string;
anonymizeIP?: boolean;
};
}
export type PluginOptions = {
trackingID: string;
anonymizeIP: boolean;
};

export type Options = Partial<PluginOptions>;
3 changes: 2 additions & 1 deletion packages/docusaurus-plugin-google-gtag/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
},
"license": "MIT",
"dependencies": {
"@docusaurus/core": "2.0.0-beta.9"
"@docusaurus/core": "2.0.0-beta.9",
"@docusaurus/utils-validation": "2.0.0-beta.9"
},
"devDependencies": {
"@docusaurus/types": "2.0.0-beta.9"
Expand Down
9 changes: 4 additions & 5 deletions packages/docusaurus-plugin-google-gtag/src/gtag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@
*/

import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
import siteConfig from '@generated/docusaurus.config';
import type {ThemeConfig} from '@docusaurus/plugin-google-gtag';
import globalData from '@generated/globalData';
import type {PluginOptions} from '@docusaurus/plugin-google-gtag';

export default (function () {
if (!ExecutionEnvironment.canUseDOM) {
return null;
}

const {themeConfig} = siteConfig;
const {gtag} = themeConfig as ThemeConfig;
const {trackingID} = gtag!;
const {trackingID} = globalData['docusaurus-plugin-google-gtag']
.default as PluginOptions;

return {
onRouteUpdate({location}: {location: Location}) {
Expand Down
66 changes: 43 additions & 23 deletions packages/docusaurus-plugin-google-gtag/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,32 @@
*/

import path from 'path';
import type {LoadContext, Plugin, HtmlTags} from '@docusaurus/types';
import type {ThemeConfig} from '@docusaurus/plugin-google-gtag';

export default function pluginGoogleGtag(context: LoadContext): Plugin {
const {
siteConfig: {themeConfig},
} = context;
const {gtag} = themeConfig as ThemeConfig;

if (!gtag) {
throw new Error(
`You need to specify "gtag" object in "themeConfig" with "trackingId" field in it to use docusaurus-plugin-google-gtag.`,
);
}

const {anonymizeIP, trackingID} = gtag;

if (!trackingID) {
throw new Error(
'You specified the "gtag" object in "themeConfig" but the "trackingID" field was missing. ' +
'Please ensure this is not a mistake.',
);
}
import {Joi} from '@docusaurus/utils-validation';
import type {
LoadContext,
Plugin,
HtmlTags,
OptionValidationContext,
ValidationResult,
ThemeConfig,
ThemeConfigValidationContext,
} from '@docusaurus/types';
import type {PluginOptions} from '@docusaurus/plugin-google-gtag';

export default function pluginGoogleGtag(
context: LoadContext,
options: PluginOptions,
): Plugin {
const {anonymizeIP, trackingID} = options;
const isProd = process.env.NODE_ENV === 'production';

return {
name: 'docusaurus-plugin-google-gtag',

async contentLoaded({actions}) {
actions.setGlobalData(options);
},

getClientModules() {
return isProd ? [path.resolve(__dirname, './gtag')] : [];
},
Expand Down Expand Up @@ -83,3 +80,26 @@ export default function pluginGoogleGtag(context: LoadContext): Plugin {
},
};
}

const pluginOptionsSchema = Joi.object<PluginOptions>({
trackingID: Joi.string().required(),
anonymizeIP: Joi.boolean().default(false),
});

export function validateOptions({
validate,
options,
}: OptionValidationContext<PluginOptions>): ValidationResult<PluginOptions> {
return validate(pluginOptionsSchema, options);
}

export function validateThemeConfig({
themeConfig,
}: ThemeConfigValidationContext<ThemeConfig>): ValidationResult<ThemeConfig> {
if (themeConfig.gtag) {
throw new Error(
'The "gtag" field in themeConfig should now be specified as option for plugin-google-gtag. More information at https://github.com/facebook/docusaurus/pull/5832.',
);
}
return themeConfig;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

export interface ThemeConfig {
gtag?: {
trackingID: string;
anonymizeIP?: boolean;
};
}
export type PluginOptions = {
trackingID: string;
anonymizeIP: boolean;
};

export type Options = Partial<PluginOptions>;
22 changes: 17 additions & 5 deletions packages/docusaurus-preset-classic/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,19 @@ export default function preset(
): Preset {
const {siteConfig} = context;
const {themeConfig} = siteConfig;
const {algolia, googleAnalytics, gtag} = themeConfig as Partial<ThemeConfig>;
const {algolia} = themeConfig as Partial<ThemeConfig>;
const isProd = process.env.NODE_ENV === 'production';
const {debug, docs, blog, pages, sitemap, theme, ...rest} = opts;
const {
debug,
docs,
blog,
pages,
sitemap,
theme,
googleAnalytics,
gtag,
...rest
} = opts;

const themes: PluginConfig[] = [];
themes.push(makePluginConfig('@docusaurus/theme-classic', theme));
Expand All @@ -50,13 +60,15 @@ export default function preset(
plugins.push(makePluginConfig('@docusaurus/plugin-content-pages', pages));
}
if (isProd && googleAnalytics) {
plugins.push(require.resolve('@docusaurus/plugin-google-analytics'));
plugins.push(
makePluginConfig('@docusaurus/plugin-google-analytics', googleAnalytics),
);
}
if (debug || (debug === undefined && !isProd)) {
plugins.push(require.resolve('@docusaurus/plugin-debug'));
}
if (isProd && gtag) {
plugins.push(require.resolve('@docusaurus/plugin-google-gtag'));
plugins.push(makePluginConfig('@docusaurus/plugin-google-gtag', gtag));
}
if (isProd && sitemap !== false) {
plugins.push(makePluginConfig('@docusaurus/plugin-sitemap', sitemap));
Expand All @@ -65,7 +77,7 @@ export default function preset(
throw new Error(
`Unrecognized keys ${Object.keys(rest).join(
', ',
)} found in preset-classic configuration. The allowed keys are debug, docs, blog, pages, sitemap, theme. Check the documentation: https://docusaurus.io/docs/presets#docusauruspreset-classic for more information on how to configure individual plugins.`,
)} found in preset-classic configuration. The allowed keys are debug, docs, blog, pages, sitemap, theme, googleAnalytics, gtag. Check the documentation: https://docusaurus.io/docs/presets#docusauruspreset-classic for more information on how to configure individual plugins.`,
);
}

Expand Down
8 changes: 3 additions & 5 deletions packages/docusaurus-preset-classic/src/preset-classic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ export type Options = {
pages?: false | import('@docusaurus/plugin-content-pages').Options;
sitemap?: false | import('@docusaurus/plugin-sitemap').Options;
theme?: import('@docusaurus/theme-classic').Options;
googleAnalytics?: import('@docusaurus/plugin-google-analytics').Options;
gtag?: import('@docusaurus/plugin-google-gtag').Options;
};

export type ThemeConfig = import('@docusaurus/types').ThemeConfig &
import('@docusaurus/theme-common').UserThemeConfig &
// Those plugins themeConfigs should rather be moved to preset/plugin options
// Plugin data can be made available to browser thank to the globalData api
import('@docusaurus/plugin-google-analytics').ThemeConfig &
import('@docusaurus/plugin-google-gtag').ThemeConfig & {
import('@docusaurus/theme-common').UserThemeConfig & {
algolia?: unknown; // TODO type plugin
};
Loading

0 comments on commit ac88d97

Please sign in to comment.