diff --git a/config.toml b/config.toml
index f66725173..f78321762 100644
--- a/config.toml
+++ b/config.toml
@@ -211,6 +211,25 @@ allowed_domains = [
# Please see https://welpo.github.io/tabi/blog/custom-font-subset/ to learn how to create this file.
custom_subset = true
+[extra.analytics]
+# Specify which analytics service you want to use.
+# Supported options: ["goatcounter", "umami", "plausible"]
+# service = "umami"
+
+# Unique identifier for tracking.
+# For GoatCounter, this is the code you choose during signup.
+# For Umami, this is the website ID.
+# For Plausible, this is the domain name (e.g. "example.com").
+# Note: Leave this field empty if you're self-hosting.
+# id = "yourID"
+
+# Optional: Specify the URL for self-hosted analytics instances.
+# For GoatCounter: Base URL like "https://stats.example.com"
+# For Umami: Base URL like "https://umami.example.com"
+# For Plausible: Base URL like "https://plausible.example.com"
+# Leave this field empty if you're using the service's default hosting.
+# self_hosted_url = ""
+
# giscus support for comments. https://giscus.app
# Setup instructions: https://welpo.github.io/tabi/blog/comments/#setup
[extra.giscus]
diff --git a/content/blog/mastering-tabi-settings.ca.md b/content/blog/mastering-tabi-settings.ca.md
index af9c2d95a..19ef42898 100644
--- a/content/blog/mastering-tabi-settings.ca.md
+++ b/content/blog/mastering-tabi-settings.ca.md
@@ -1,6 +1,7 @@
+++
title = "Domina la configuració de tabi: guia completa"
date = 2023-09-18
+updated = 2023-09-29
description = "Descobreix les múltiples maneres en què pots personalitzar tabi."
[taxonomies]
@@ -443,9 +444,7 @@ Per obtenir més informació, incloent instruccions sobre com crear un subconjun
Per defecte, el feed Atom només conté el resum o descripció de les teves publicacions. Pots incloure el contingut complet de les publicacions establint `full_content_in_feed = true` a `config.toml`.
----
-
-## Comentaris {#afegir-comentaris}
+### Comentaris {#afegir-comentaris}
| Pàgina | Secció | `config.toml` | Segueix la jerarquia | Requereix JavaScript |
|:------:|:-------:|:-------------:|:-------------------:|:-------------------:|
@@ -457,6 +456,37 @@ Si vols activar els comentaris de forma global, pots fer-ho establint `enabled_f
Llegeix la [documentació](/ca/blog/comments/) per a més informació sobre els sistemes disponibles i la seva configuració.
+### Anàlisi web
+
+| Pàgina | Secció | `config.toml` | Segueix Jerarquia | Requereix JavaScript |
+|:------:|:-------:|:-------------:|:-----------------:|:--------------------:|
+| ❌ | ❌ | ✅ | ❌ | ✅ |
+
+tabi ofereix suport per a 3 sistemes d'anàlisi web que respecten la privacitat: [Plausible](https://plausible.io/), [GoatCounter](https://www.goatcounter.com/) i [Umami](https://umami.is/).
+
+Pots configurar-los en la secció `[extra.analytics]` del teu arxiu `config.toml`.
+
+- `service`: el servei a utilitzar. Les opcions disponibles són `"goatcounter"`, `"umami", i "plausible"`.
+
+- `id`: l'identificador únic per al teu servei d'anàlisi. Això varia segons el servei:
+ - Per a GoatCounter, és el codi triat durant el registre. Instàncies auto-allotjades no requereixen aquest camp.
+ - Per a Umami, és l'ID del lloc web.
+ - Per a Plausible, és el nom de domini.
+
+- `self_hosted_url`: Opcional. Utilitza aquest camp per especificar l'URL si tens una instància auto-allotjada. L'URL base variarà segons la teva configuració particular. Alguns exemples:
+ - Per a GoatCounter: `"https://stats.example.com"`
+ - Per a Umami: `"https://umami.example.com"`
+ - Per a Plausible: `"https://plausible.example.com"`
+
+Un exemple de configuració per a GoatCounter no auto-allotjada seria:
+
+```toml
+[extra.analytics]
+service = "goatcounter"
+id = "tabi"
+self_hosted_url = ""
+
+
---
## Icones al peu de pàgina
diff --git a/content/blog/mastering-tabi-settings.es.md b/content/blog/mastering-tabi-settings.es.md
index 67fc59b88..1cebf6c37 100644
--- a/content/blog/mastering-tabi-settings.es.md
+++ b/content/blog/mastering-tabi-settings.es.md
@@ -1,6 +1,7 @@
+++
title = "Domina la configuración de tabi: guía completa"
date = 2023-09-18
+updated = 2023-09-29
description = "Descubre las múltiples maneras en que puedes personalizar tabi."
[taxonomies]
@@ -441,9 +442,7 @@ Para obtener más información, incluyendo instrucciones sobre cómo crear un su
Por defecto, el feed Atom solo contiene el resumen/descripción de tus publicaciones. Puedes incluir el contenido completo de las publicaciones estableciendo `full_content_in_feed = true` en `config.toml`.
----
-
-## Comentarios {#añadir-comentarios}
+### Comentarios {#añadir-comentarios}
| Página | Sección | `config.toml` | Sigue la jerarquía | Requiere JavaScript |
|:------:|:-------:|:-------------:|:---------------:|:-------------------:|
@@ -455,6 +454,37 @@ Si quieres activar los comentarios de forma global, puedes hacerlo estableciendo
Lee la [documentación](/es/blog/comments/) para obtener más información sobre los sistemas disponibles y su configuración.
+### Análisis web
+
+| Página | Sección | `config.toml` | Sigue Jerarquía | Requiere JavaScript |
+|:------:|:--------:|:-------------:|:----------------:|:-------------------:|
+| ❌ | ❌ | ✅ | ❌ | ✅ |
+
+tabi ofrece soporte para 3 sistemas de análisis web que respetan la privacidad: [Plausible](https://plausible.io/), [GoatCounter](https://www.goatcounter.com/) y [Umami](https://umami.is/).
+
+Puedes configurarlos en la sección `[extra.analytics]` de tu archivo `config.toml`.
+
+- `service`: el servicio a utilizar. Las opciones disponibles son `"goatcounter"`, `"umami"`, y `"plausible"`.
+
+- `id`: el identificador único para tu servicio de análisis. Esto varía según el servicio:
+ - Para GoatCounter, es el código elegido durante el registro. Instancias auto-alojadas no requieren este campo.
+ - Para Umami, es la ID del sitio web.
+ - Para Plausible, es el nombre de dominio.
+
+- `self_hosted_url`. Opcional. Utiliza este campo para especificar la URL si tienes una instancia auto-alojada. La URL base variará según tu configuración particular. Algunos ejemplos:
+ - Para GoatCounter: `"https://stats.example.com"`
+ - Para Umami: `"https://umami.example.com"`
+ - Para Plausible: `"https://plausible.example.com"`
+
+Un ejemplo de configuración para GoatCounter no auto-alojada sería:
+
+```toml
+[extra.analytics]
+service = "goatcounter"
+id = "tabi"
+self_hosted_url = ""
+```
+
---
## Iconos en el pie de página
diff --git a/content/blog/mastering-tabi-settings.md b/content/blog/mastering-tabi-settings.md
index 5b0d7a08e..c57e797f6 100644
--- a/content/blog/mastering-tabi-settings.md
+++ b/content/blog/mastering-tabi-settings.md
@@ -1,6 +1,7 @@
+++
title = "Mastering tabi Settings: A Comprehensive Guide"
date = 2023-09-18
+updated = 2023-09-29
description = "Discover the many ways you can customise your tabi site."
[taxonomies]
@@ -445,9 +446,7 @@ For more information, including instructions on how to create a custom subset, s
By default, the Atom feed only contains the summary/description of your posts. You can include the entire posts' content by setting `full_content_in_feed = true` in `config.toml`.
----
-
-## Comments {#adding-comments}
+### Comments {#adding-comments}
| Page | Section | `config.toml` | Follows Hierarchy | Requires JavaScript |
|:----:|:-------:|:-------------:|:-----------------:|:-------------------:|
@@ -459,6 +458,37 @@ To enable a system globally (on all pages), set `enabled_for_all_posts = true` i
Read [the docs](/blog/comments/) for more information on the available systems and their setup.
+### Analytics
+
+| Page | Section | `config.toml` | Follows Hierarchy | Requires JavaScript |
+|:----:|:-------:|:-------------:|:-----------------:|:-------------------:|
+| ❌ | ❌ | ✅ | ❌ | ✅ |
+
+tabi supports 3 privacy-friendly analytics systems: [Plausible](https://plausible.io/), [GoatCounter](https://www.goatcounter.com/) and [Umami](https://umami.is/).
+
+You can set them up in the `[extra.analytics]` section of your `config.toml`.
+
+- `service`: Specifies which analytics service to use. Supported options are `"goatcounter"`, `"umami"`, and `"plausible"`.
+
+- `id`: The unique identifier for your analytics service. This varies based on the service:
+ - For GoatCounter, it's the code chosen during signup. Self-hosted instances don't require this field.
+ - For Umami, it's the website ID.
+ - For Plausible, it's the domain name.
+
+- `self_hosted_url`: Optional. Use this field to specify the URL for self-hosted instances of your chosen analytics service. The base URL differs based on your specific setup. Some examples:
+ - For GoatCounter: `"https://stats.example.com"`
+ - For Umami: `"https://umami.example.com"`
+ - For Plausible: `"https://plausible.example.com"`
+
+An example configuration for non-self-hosted GoatCounter would look like this:
+
+```toml
+[extra.analytics]
+service = "goatcounter"
+id = "tabi"
+self_hosted_url = ""
+```
+
---
## Footer Icons
diff --git a/content/blog/security.ca.md b/content/blog/security.ca.md
index e16677540..1a1bb7da6 100644
--- a/content/blog/security.ca.md
+++ b/content/blog/security.ca.md
@@ -1,7 +1,7 @@
+++
title = "Seguretat per defecte"
date = 2023-02-22
-updated = 2023-07-17
+updated = 2023-09-29
description = "tabi té una Política de Seguretat de Contingut (CSP) fàcilment personalitzable amb valors segurs per defecte. Obtingues tranquil·litat i un A+ en l'Observatori de Mozilla."
[taxonomies]
@@ -30,6 +30,6 @@ La llista `allowed_domains` especifica les URLs a les quals el lloc web hauria d
Aquesta funcionalitat permet personalitzar fàcilment les capçaleres de seguretat del lloc web per permetre casos d'ús específics, com ara inserir vídeos de YouTube, carregar scripts o tipografies remotes ([no recomanat](https://www.albertovarela.net/blog/2022/11/stop-using-google-fonts/)).
-**Nota**: [habilitar els comentaris](@/blog/comments.ca.md) permet automàticament scripts i frames del sistema de comentaris corresponent, així com estils en línia no segurs en el cas de utterances i Hyvor Talk.
+**Nota**: [habilitar els comentaris](@/blog/comments.ca.md) o [les analítiques](@/blog/mastering-tabi-settings.ca.md#analitiques) automàticament permet scripts/frames/estils/connexions en funció del servei habilitat.
[^1]: Requereix una configuració adequada del servidor web (p. ex., redirigir el trànsit HTTP a HTTPS).
diff --git a/content/blog/security.es.md b/content/blog/security.es.md
index 72435ec30..fba7c94d5 100644
--- a/content/blog/security.es.md
+++ b/content/blog/security.es.md
@@ -1,7 +1,7 @@
+++
title = "Seguro por defecto"
date = 2023-02-22
-updated = 2023-07-17
+updated = 2023-09-29
description = "tabi tiene una Política de Seguridad de Contenido (CSP) fácilmente personalizable con configuraciones seguras. Obtén tranquilidad y una calificación de A+ en Mozilla Observatory."
[taxonomies]
@@ -30,6 +30,6 @@ La lista `allowed_domains` especifica las URL a las que el sitio web debería po
Esta función permite personalizar fácilmente las cabeceras de seguridad del sitio web para permitir casos de uso específicos, como la incrustación de videos de YouTube, la carga de scripts o fuentes remotas ([no recomendado](https://www.albertovarela.net/blog/2022/11/stop-using-google-fonts/)).
-**Nota**: [habilitar los comentarios](@/blog/comments.es.md) permite automáticamente scripts y frames del sistema de comentarios correspondiente, así como estilos unsafe-inline en el caso de utterances o Hyvor Talk.
+**Nota**: [habilitar los comentarios](@/blog/comments.es.md) o [las analíticas](@/blog/mastering-tabi-settings.es.md#analisis-web) automáticamente permite scripts/frames/estilos/conexiones en función del servicio habilitado.
[^1]: Requiere una configuración adecuada del servidor web (por ejemplo, redirigir el tráfico HTTP a HTTPS).
diff --git a/content/blog/security.md b/content/blog/security.md
index 4c9235de6..dd2b6a196 100644
--- a/content/blog/security.md
+++ b/content/blog/security.md
@@ -1,7 +1,7 @@
+++
title = "Secure by default"
date = 2023-02-22
-updated = 2023-07-17
+updated = 2023-09-29
description = "tabi has an easily customizable Content Security Policy (CSP) with safe defaults. Get peace of mind and an A+ on Mozilla Observatory."
[taxonomies]
@@ -30,6 +30,6 @@ The `allowed_domains` list specifies the URLs that the website should be able to
This feature allows you to easily customize the website's security headers to allow for specific use cases, such as embedding YouTube videos, loading scripts or remote fonts ([not recommended](https://www.albertovarela.net/blog/2022/11/stop-using-google-fonts/)).
-**Note**: [enabling comments](@/blog/comments.md) automatically allows scripts and frames from the comment system, as well as unsafe-inline styles when using utterances or Hyvor Talk.
+**Note**: [enabling comments](@/blog/comments.md) or [analytics](@/blog/mastering-tabi-settings.md#analytics) automatically allows scripts/frames/styles/connections as needed from the respective services.
[^1]: Requires proper webserver configuration (e.g. redirecting HTTP traffic to HTTPS).
diff --git a/templates/partials/analytics.html b/templates/partials/analytics.html
new file mode 100644
index 000000000..bd1543183
--- /dev/null
+++ b/templates/partials/analytics.html
@@ -0,0 +1,41 @@
+{% set analytics_service = config.extra.analytics.service %}
+{% set analytics_id = config.extra.analytics.id | default(value="") %}
+{% set self_hosted_url = config.extra.analytics.self_hosted_url | default(value="") %}
+
+{% if analytics_service == "goatcounter" %}
+ {% if self_hosted_url %}
+
+ {% else %}
+
+ {% endif %}
+
+{% elif analytics_service == "umami" %}
+ {% if self_hosted_url %}
+
+ {% else %}
+
+ {% endif %}
+
+ {% elif analytics_service == "plausible" %}
+
+{% endif %}
diff --git a/templates/partials/content_security_policy.html b/templates/partials/content_security_policy.html
new file mode 100644
index 000000000..6f5547a32
--- /dev/null
+++ b/templates/partials/content_security_policy.html
@@ -0,0 +1,93 @@
+
diff --git a/templates/partials/header.html b/templates/partials/header.html
index 6afd8ae74..4c1b9a8b8 100644
--- a/templates/partials/header.html
+++ b/templates/partials/header.html
@@ -139,65 +139,7 @@
-
+ {%- include "partials/content_security_policy.html" -%}
{%- if config.extra.theme_switcher and config.extra.theme_switcher == true -%}
{# If JavaScript is disabled, hide the button. #}
@@ -206,4 +148,8 @@
{%- endif -%}
+ {%- if config.extra.analytics.service -%}
+ {%- include "partials/analytics.html" -%}
+ {%- endif -%}
+
diff --git a/theme.toml b/theme.toml
index 3ad2b5db4..6200c3f0e 100644
--- a/theme.toml
+++ b/theme.toml
@@ -190,6 +190,25 @@ allowed_domains = [
# Please see https://welpo.github.io/tabi/blog/custom-font-subset/ to learn how to create this file.
# custom_subset = true
+[extra.analytics]
+# Specify which analytics service you want to use.
+# Supported options: ["goatcounter", "umami", "plausible"]
+# service = "umami"
+
+# Unique identifier for tracking.
+# For GoatCounter, this is the code you choose during signup.
+# For Umami, this is the website ID.
+# For Plausible, this is the domain name (e.g. "example.com").
+# Note: Leave this field empty if you're self-hosting.
+# id = "yourID"
+
+# Optional: Specify the URL for self-hosted analytics instances.
+# For GoatCounter: Base URL like "https://stats.example.com"
+# For Umami: Base URL like "https://umami.example.com"
+# For Plausible: Base URL like "https://plausible.example.com"
+# Leave this field empty if you're using the service's default hosting.
+# self_hosted_url = ""
+
# giscus support for comments. https://giscus.app
# Setup instructions: https://welpo.github.io/tabi/blog/comments/#setup
[extra.giscus]