Skip to content

Add Analytics - #12

Merged
cameronyule merged 3 commits into
mainfrom
feat-analytics
Jul 24, 2025
Merged

Add Analytics#12
cameronyule merged 3 commits into
mainfrom
feat-analytics

Conversation

@cameronyule

Copy link
Copy Markdown
Owner

Not that I'm expecting a lot of traffic, but it'd be nice to have some visibility on it. As I'm using GitHub sites for hosting and don't have access to server-side logging, I'm assuming client-side will be the way to go.

Google Analytics is an obvious candidate, but I should do some research to see what else is available.

@cameronyule

Copy link
Copy Markdown
Owner Author

Self-hosting would be needed if I wanted to go the route of server-side rather than client-side, which would be better from a privacy perspective.

There's a lot of open-source self-hosted solutions available, such as:

@cameronyule

cameronyule commented Jul 19, 2025

Copy link
Copy Markdown
Owner Author

Goatcounter offers free client-side and privacy-friendly analytics, and is also open-source and can be self-hosted.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @cameronyule, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request aims to add client-side analytics to the website to provide insights into traffic and usage. It achieves this by incorporating GoatCounter, a privacy-focused analytics tool, through modifications to the core HTML templates to include a new footer partial containing the necessary tracking script.

Highlights

  • Analytics Integration: I've integrated GoatCounter, a privacy-friendly web analytics solution, to gain visibility into website traffic. This was chosen as a client-side solution suitable for GitHub Pages hosting.
  • Template Structure Update: To facilitate the analytics integration, I've introduced a new footer.html partial. This partial now contains the GoatCounter script and is included in the baseof.html templates for bookmarks, posts, and 'Today I Learned' (TIL) pages, ensuring the script loads across these content types.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces analytics to the blog using GoatCounter, a privacy-focused alternative to Google Analytics. The implementation correctly adds the analytics script to a footer partial and includes this footer across the different page layouts.

My main feedback is a security recommendation to add Subresource Integrity (SRI) to the third-party script tag. This is an important measure to protect your site and its visitors from potential supply-chain attacks via the CDN hosting the script. I've also included a suggestion to consider adding a privacy notice to inform users about the data collection.

{{ end }}
{{ end }}

<script data-goatcounter="https://camyule.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

For enhanced security, it's highly recommended to use Subresource Integrity (SRI) when loading scripts from third-party CDNs. This ensures that the script file hasn't been tampered with by a malicious actor. A compromise of the CDN could allow an attacker to execute arbitrary JavaScript on your site, and SRI mitigates this risk by having the browser verify the script's integrity against a cryptographic hash you provide.

You can generate the hash and update your script tag as follows:

  1. Generate the SHA-384 hash of the script:
    curl "https://gc.zgo.at/count.js" | openssl dgst -sha384 -binary | openssl base64 -A
  2. Add the integrity and crossorigin attributes to your script tag. The suggestion below uses a placeholder for the hash, which you'll need to replace with the generated value.

Note that if GoatCounter updates count.js, you will need to update the hash. This is a worthwhile trade-off for improved security.

Suggested change
<script data-goatcounter="https://camyule.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>
<script data-goatcounter="https://camyule.goatcounter.com/count" async src="//gc.zgo.at/count.js" integrity="sha384-YOUR_GENERATED_HASH_HERE" crossorigin="anonymous"></script>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good suggestion, I will make this change. Doing some research, GoatCounter has official support for pinning to a specific release and using subresource integrity: https://camyule.goatcounter.com/help/countjs-versions.

{{ end }}
{{ end }}

<script data-goatcounter="https://camyule.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While GoatCounter is an excellent choice for privacy-respecting analytics, it's still a form of user tracking. To be transparent with your visitors and to comply with regulations like GDPR, it's a good practice to inform them that their visits are being tracked.

Consider adding a note to your site's footer and/or creating a privacy policy page that explains what data is collected and why. This builds trust with your audience.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is reasonable feedback, but I'm going to hold off on this for now and revisit it later if necessary. The GoatCounter page on GDPR notices is relevant here: https://camyule.goatcounter.com/help/gdpr#conclusion-4

As suggested by Gemini Code Assist PR review.

Refs: #12
@cameronyule
cameronyule merged commit 40e8a09 into main Jul 24, 2025
3 checks passed
@cameronyule
cameronyule deleted the feat-analytics branch July 24, 2025 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant