feat: support privacy-respecting analytics (#193)

main
Óscar Fernández 1 year ago committed by GitHub
parent 2eaee6557c
commit 228f1ea6e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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]

@ -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

@ -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

@ -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

@ -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).

@ -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).

@ -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).

@ -0,0 +1,35 @@
{% 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" %}
<script async
{% if self_hosted_url %}
data-goatcounter="{{ self_hosted_url ~ '/count' }}"
src="{{ self_hosted_url ~ '/count.js' }}"
{% else %}
data-goatcounter="https://{{ analytics_id }}.goatcounter.com/count"
src="//gc.zgo.at/count.js"
{% endif %}
></script>
{% elif analytics_service == "umami" %}
<script async defer
{% if self_hosted_url %}
data-website-id="{{ analytics_id }}"
src="{{ self_hosted_url ~ '/umami.js' }}"
{% else %}
data-website-id="{{ analytics_id }}"
src="https://analytics.eu.umami.is/script.js"
{% endif %}
data-do-not-track="true">
</script>
{% elif analytics_service == "plausible" %}
<script
defer
data-domain="{{ analytics_id }}"
src="{% if self_hosted_url %}{{ self_hosted_url ~ '/js/plausible.js' }}{% else %}https://plausible.io/js/script.js{% endif %}"
></script>
{% endif %}

@ -0,0 +1,93 @@
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'
{%- if config.extra.allowed_domains -%}
;
{#- Check if a comment system is enabled to allow the necessary domains and directives -#}
{%- set utterances_enabled = config.extra.utterances.enabled_for_all_posts or page.extra.utterances -%}
{%- set giscus_enabled = config.extra.giscus.enabled_for_all_posts or page.extra.giscus -%}
{%- set hyvortalk_enabled = config.extra.hyvortalk.enabled_for_all_posts or page.extra.hyvortalk -%}
{%- set isso_enabled = config.extra.isso.enabled_for_all_posts or page.extra.isso -%}
{#- Initialise a base script-src directive -#}
{%- set script_src = "script-src 'self'" -%}
{#- Initialise a base connect-src directive -#}
{%- set connect_src = "connect-src 'self'" -%}
{# Base logic for appending analytics domains #}
{%- set analytics_url = config.extra.analytics.self_hosted_url | default(value="") %}
{%- if analytics_url -%}
{%- set script_src = script_src ~ " " ~ analytics_url -%}
{%- set connect_src = connect_src ~ " " ~ analytics_url -%}
{%- else -%}
{%- if config.extra.analytics.service -%}
{%- if config.extra.analytics.service == "goatcounter" -%}
{%- set script_src = script_src ~ " gc.zgo.at" -%}
{%- set connect_src = connect_src ~ " gc.zgo.at" -%}
{%- elif config.extra.analytics.service == "umami" -%}
{%- set script_src = script_src ~ " analytics.eu.umami.is" -%}
{%- set connect_src = connect_src ~ " analytics.eu.umami.is" -%}
{%- elif config.extra.analytics.service == "plausible" -%}
{%- set script_src = script_src ~ " plausible.io" -%}
{%- set connect_src = connect_src ~ " plausible.io" -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- if hyvortalk_enabled -%}
{%- set connect_src = connect_src ~ " talk.hyvor.com" -%}
{%- set script_src = script_src ~ " talk.hyvor.com" -%}
{%- elif isso_enabled -%}
{%- set connect_src = connect_src ~ " " ~ config.extra.isso.endpoint_url -%}
{%- set script_src = script_src ~ " " ~ config.extra.isso.endpoint_url -%}
{%- elif giscus_enabled -%}
{%- set script_src = script_src ~ " " ~ " giscus.app" -%}
{%- elif utterances_enabled -%}
{%- set script_src = script_src ~ " " ~ " utteranc.es" -%}
{%- endif -%}
{#- Append WebSocket for Zola serve mode -#}
{%- if config.mode == "serve" -%}
{%- set connect_src = connect_src ~ " ws:" -%}
{%- endif -%}
{%- for domain in config.extra.allowed_domains -%}
{%- if domain.directive == "connect-src" -%}
{%- set configured_connect_src = domain.domains | join(sep=' ') -%}
{%- set_global connect_src = connect_src ~ " " ~ configured_connect_src -%}
{%- continue -%}
{%- endif -%}
{%- if domain.directive == "script-src" -%}
{%- set configured_script_src = domain.domains | join(sep=' ') -%}
{%- set_global script_src = script_src ~ " " ~ configured_script_src -%}
{%- continue -%}
{%- endif -%}
{#- Handle directives that are not connect-src -#}
{{ domain.directive }} {{ domain.domains | join(sep=' ') -}}
{%- if utterances_enabled or hyvortalk_enabled -%}
{%- if domain.directive == "style-src" %} 'unsafe-inline'
{%- endif -%}
{%- endif -%}
{%- if domain.directive == "frame-src" -%}
{%- if giscus_enabled %} giscus.app
{%- elif utterances_enabled %} utteranc.es
{%- elif hyvortalk_enabled %} talk.hyvor.com
{%- endif %}
{%- endif -%}
{%- if not loop.last -%}
;
{%- endif -%}
{%- endfor -%}
{#- Insert the generated connect-src -#}
{{ ";" ~ connect_src }}
{#- Insert the generated script-src -#}
{{ ";" ~ script_src }}
{%- endif -%}">

@ -142,65 +142,7 @@
<meta property="og:site_name" content="{{ config.title }}">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'
{%- if config.extra.allowed_domains -%}
;
{#- Check if a comment system is enabled to allow the necessary domains and directives -#}
{%- set utterances_enabled = config.extra.utterances.enabled_for_all_posts or page.extra.utterances -%}
{%- set giscus_enabled = config.extra.giscus.enabled_for_all_posts or page.extra.giscus -%}
{%- set hyvortalk_enabled = config.extra.hyvortalk.enabled_for_all_posts or page.extra.hyvortalk -%}
{%- set isso_enabled = config.extra.isso.enabled_for_all_posts or page.extra.isso -%}
{#- Initialise a base connect-src directive -#}
{%- set connect_src = "connect-src 'self'" -%}
{%- if hyvortalk_enabled -%}
{%- set connect_src = connect_src ~ " talk.hyvor.com" -%}
{%- elif isso_enabled -%}
{%- set connect_src = connect_src ~ " " ~ config.extra.isso.endpoint_url -%}
{%- endif -%}
{#- Append WebSocket for Zola serve mode -#}
{%- if config.mode == "serve" -%}
{%- set connect_src = connect_src ~ " ws:" -%}
{%- endif -%}
{%- for domain in config.extra.allowed_domains -%}
{%- if domain.directive == "connect-src" -%}
{%- set configured_connect_src = domain.domains | join(sep=' ') -%}
{%- set_global connect_src = connect_src ~ " " ~ configured_connect_src -%}
{%- continue -%}
{%- endif -%}
{#- Handle directives that are not connect-src -#}
{{ domain.directive }} {{ domain.domains | join(sep=' ') -}}
{% if utterances_enabled or hyvortalk_enabled -%}
{%- if domain.directive == "style-src" %} 'unsafe-inline'
{%- endif -%}
{% endif -%}
{%- if domain.directive == "script-src" or domain.directive == "frame-src" -%}
{%- if giscus_enabled %} giscus.app
{%- elif utterances_enabled %} utteranc.es
{%- elif hyvortalk_enabled %} talk.hyvor.com
{%- endif %}
{%- endif -%}
{%- if domain.directive == "script-src" -%}
{%- if isso_enabled %} {{ config.extra.isso.endpoint_url }}
{%- endif %}
{%- endif -%}
{%- if not loop.last -%}
;
{%- endif -%}
{%- endfor -%}
{#- Insert the generated connect-src -#}
{{ ";" ~ connect_src }}
{%- endif -%}">
{%- include "partials/content_security_policy.html" -%}
{%- if config.extra.theme_switcher and config.extra.theme_switcher == true -%}
{# If JavaScript is disabled, hide the button. #}
@ -209,4 +151,8 @@
<script defer src="{{ get_url(path='js/themeSwitcher.min.js', trailing_slash=false) | safe }}"/></script>
{%- endif -%}
{%- if config.extra.analytics.service -%}
{%- include "partials/analytics.html" -%}
{%- endif -%}
</head>

@ -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]

Loading…
Cancel
Save