Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/changelog-1.9.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ All changes included in 1.9:
### `website`

- Algolia Insights now uses privacy-friendly defaults: `useCookie: false` with random session tokens when cookie consent is not configured. When `cookie-consent: true` is enabled, Algolia scripts are deferred and only use cookies after user grants "tracking" consent, ensuring GDPR compliance.
- Add support for Plausible Analytics via `plausible-analytics` configuration option. Users can either paste their Plausible script snippet directly in YAML or provide a path to a file containing the snippet using `plausible-analytics: { path: _plausible_snippet.html }`.

## `publish`

Expand Down
69 changes: 49 additions & 20 deletions src/project/types/website/website-analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
import { Document } from "../../../core/deno-dom.ts";
import { join } from "../../../deno_ral/path.ts";
import { existsSync } from "../../../deno_ral/fs.ts";
import { kLang, kTitle } from "../../../config/constants.ts";
import { Format, Metadata } from "../../../config/types.ts";
import { projectTypeResourcePath } from "../../../core/resources.ts";
Expand All @@ -26,6 +27,10 @@ const kStorage = "storage";
const kAnonymizeIp = "anonymize-ip";
const kVersion = "version";

// Plausible analytics
export const kPlausibleAnalytics = "plausible-analytics";
const kPlausiblePath = "path";

// Cookie consent properties
export const kCookieConsent = "cookie-consent";
const kCookieConsentType = "type";
Expand Down Expand Up @@ -77,21 +82,19 @@ ${contents}
}
}

// Generate the script to inject into the head for Google Analytics
// Generate the script to inject into the head for Google Analytics and/or Plausible
export function websiteAnalyticsScriptFile(
project: ProjectContext,
temp: TempContext,
) {
// Find the ga tag
const siteMeta = project.config?.[kWebsite] as Metadata;

// The google analytics metadata (either from the page or the site)
// Deal with page and site options
let gaConfig: GaConfiguration | undefined = undefined;
const scripts: string[] = [];

if (siteMeta) {
// Google Analytics
let gaConfig: GaConfiguration | undefined = undefined;
const siteGa = siteMeta[kGoogleAnalytics];
if (typeof (siteGa) === "object") {
if (typeof siteGa === "object") {
const siteGaMeta = siteGa as Metadata;
// Merge the site and page options and then layer over defaults
const trackingId = siteGaMeta[kTrackingId] as string;
Expand All @@ -105,19 +108,45 @@ export function websiteAnalyticsScriptFile(
anonymizedIp,
version,
);
} else if (siteGa && typeof (siteGa) === "string") {
} else if (siteGa && typeof siteGa === "string") {
gaConfig = googleAnalyticsConfig(project, siteGa as string);
}
}

// Generate the actual GA dependencies
if (gaConfig) {
const script = analyticsScript(gaConfig);
if (script) {
return scriptFile(script, temp);
} else {
return undefined;
if (gaConfig) {
const gaScript = analyticsScript(gaConfig);
if (gaScript) {
scripts.push(gaScript);
}
}

// Plausible Analytics
const plausibleSnippet = siteMeta[kPlausibleAnalytics];
if (plausibleSnippet) {
if (typeof plausibleSnippet === "string") {
// Inline snippet provided directly in YAML
scripts.push(plausibleSnippet);
} else if (typeof plausibleSnippet === "object") {
// Path to file containing snippet
const plausibleMeta = plausibleSnippet as Metadata;
const snippetPath = plausibleMeta[kPlausiblePath] as string;
if (snippetPath) {
const absolutePath = join(project.dir, snippetPath);
if (existsSync(absolutePath)) {
const snippetContent = Deno.readTextFileSync(absolutePath);
scripts.push(snippetContent);
} else {
throw new Error(
`Plausible Analytics snippet file not found: ${snippetPath}`,
);
}
}
}
}
}

// Return combined script file if we have any analytics
if (scripts.length > 0) {
return scriptFile(scripts.join("\n"), temp);
} else {
return undefined;
}
Expand All @@ -138,7 +167,7 @@ export function cookieConsentDependencies(
let configuration: CookieConsentConfiguration | undefined = undefined;
let changePrefsText: string | undefined = undefined;
const consent = siteMeta[kCookieConsent];
if (typeof (consent) === "object") {
if (typeof consent === "object") {
const cookieMeta = consent as Metadata;
configuration = cookieConsentConfiguration(
title,
Expand Down Expand Up @@ -384,7 +413,7 @@ cookieconsent.run({
}

function scriptFile(script: string, temp: TempContext) {
const gaScriptFile = temp.createFile({ suffix: "-lytics.js" });
Deno.writeTextFileSync(gaScriptFile, script);
return gaScriptFile;
const analyticsScriptFile = temp.createFile({ suffix: "-lytics.js" });
Deno.writeTextFileSync(analyticsScriptFile, script);
return analyticsScriptFile;
}
50 changes: 47 additions & 3 deletions src/resources/editor/tools/vs-code.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9427,6 +9427,30 @@ var require_yaml_intelligence_resources = __commonJS({
],
description: "Enable Google Analytics for this website"
},
"plausible-analytics": {
anyOf: [
"string",
{
object: {
closed: true,
properties: {
path: {
path: {
description: "Path to a file containing the Plausible Analytics script snippet"
}
}
},
required: [
"path"
]
}
}
],
description: {
short: "Enable Plausible Analytics for this website by providing a script snippet or path to snippet file",
long: 'Enable Plausible Analytics for this website by pasting the script snippet from your Plausible dashboard,\nor by providing a path to a file containing the snippet.\n\nPlausible is a privacy-friendly, GDPR-compliant web analytics service that does not use cookies and does not require cookie consent.\n\n**Option 1: Inline snippet**\n\n```yaml\nwebsite:\n plausible-analytics: |\n <script async src="https://plausible.io/js/script.js"><\/script>\n```\n\n**Option 2: File path**\n\n```yaml\nwebsite:\n plausible-analytics:\n path: _plausible_snippet.html\n```\n\nTo get your script snippet:\n\n1. Log into your Plausible account at <https://plausible.io>\n2. Go to your site settings\n3. Copy the JavaScript snippet provided\n4. Either paste it directly in your configuration or save it to a file\n\nFor more information, see <https://plausible.io/docs/plausible-script>\n'
}
},
announcement: {
anyOf: [
"string",
Expand Down Expand Up @@ -21513,6 +21537,11 @@ var require_yaml_intelligence_resources = __commonJS({
short: "The version number of Google Analytics to use.",
long: "The version number of Google Analytics to use."
},
{
short: "Enable Plausible Analytics for this website by providing a script\nsnippet or path to snippet file",
long: "Enable Plausible Analytics for this website by pasting the script\nsnippet from your Plausible dashboard, or by providing a path to a file\ncontaining the snippet.\nPlausible is a privacy-friendly, GDPR-compliant web analytics service\nthat does not use cookies and does not require cookie consent.\n<strong>Option 1: Inline snippet</strong>"
},
"Path to a file containing the Plausible Analytics script snippet",
"Provides an announcement displayed at the top of the page.",
"The content of the announcement",
"Whether this announcement may be dismissed by the user.",
Expand Down Expand Up @@ -21674,6 +21703,11 @@ var require_yaml_intelligence_resources = __commonJS({
short: "The version number of Google Analytics to use.",
long: "The version number of Google Analytics to use."
},
{
short: "Enable Plausible Analytics for this website by providing a script\nsnippet or path to snippet file",
long: "Enable Plausible Analytics for this website by pasting the script\nsnippet from your Plausible dashboard, or by providing a path to a file\ncontaining the snippet.\nPlausible is a privacy-friendly, GDPR-compliant web analytics service\nthat does not use cookies and does not require cookie consent.\n<strong>Option 1: Inline snippet</strong>"
},
"Path to a file containing the Plausible Analytics script snippet",
"Provides an announcement displayed at the top of the page.",
"The content of the announcement",
"Whether this announcement may be dismissed by the user.",
Expand Down Expand Up @@ -24060,6 +24094,11 @@ var require_yaml_intelligence_resources = __commonJS({
short: "The version number of Google Analytics to use.",
long: "The version number of Google Analytics to use."
},
{
short: "Enable Plausible Analytics for this website by providing a script\nsnippet or path to snippet file",
long: "Enable Plausible Analytics for this website by pasting the script\nsnippet from your Plausible dashboard, or by providing a path to a file\ncontaining the snippet.\nPlausible is a privacy-friendly, GDPR-compliant web analytics service\nthat does not use cookies and does not require cookie consent.\n<strong>Option 1: Inline snippet</strong>"
},
"Path to a file containing the Plausible Analytics script snippet",
"Provides an announcement displayed at the top of the page.",
"The content of the announcement",
"Whether this announcement may be dismissed by the user.",
Expand Down Expand Up @@ -24410,6 +24449,11 @@ var require_yaml_intelligence_resources = __commonJS({
short: "The version number of Google Analytics to use.",
long: "The version number of Google Analytics to use."
},
{
short: "Enable Plausible Analytics for this website by providing a script\nsnippet or path to snippet file",
long: "Enable Plausible Analytics for this website by pasting the script\nsnippet from your Plausible dashboard, or by providing a path to a file\ncontaining the snippet.\nPlausible is a privacy-friendly, GDPR-compliant web analytics service\nthat does not use cookies and does not require cookie consent.\n<strong>Option 1: Inline snippet</strong>"
},
"Path to a file containing the Plausible Analytics script snippet",
"Provides an announcement displayed at the top of the page.",
"The content of the announcement",
"Whether this announcement may be dismissed by the user.",
Expand Down Expand Up @@ -24933,12 +24977,12 @@ var require_yaml_intelligence_resources = __commonJS({
mermaid: "%%"
},
"handlers/mermaid/schema.yml": {
_internalId: 197474,
_internalId: 197491,
type: "object",
description: "be an object",
properties: {
"mermaid-format": {
_internalId: 197466,
_internalId: 197483,
type: "enum",
enum: [
"png",
Expand All @@ -24954,7 +24998,7 @@ var require_yaml_intelligence_resources = __commonJS({
exhaustiveCompletions: true
},
theme: {
_internalId: 197473,
_internalId: 197490,
type: "anyOf",
anyOf: [
{
Expand Down

Large diffs are not rendered by default.

50 changes: 47 additions & 3 deletions src/resources/editor/tools/yaml/web-worker.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading